--- a/.hgtags Mon Nov 06 19:45:47 2017 +0100
+++ b/.hgtags Wed Nov 08 16:03:35 2017 -0500
@@ -454,3 +454,4 @@
b87d7b5d5dedc1185e5929470f945b7378cdb3ad jdk-10+27
92f08900cb3c0d694e5c529a676c1c9e5909193f jdk-10+28
a6e591e12f122768f675428e1e5a838fd0e9c7ec jdk-10+29
+8fee80b92e65149f7414250fd5e34b6f35d417b4 jdk-10+30
--- a/make/CompileToolsHotspot.gmk Mon Nov 06 19:45:47 2017 +0100
+++ b/make/CompileToolsHotspot.gmk Wed Nov 08 16:03:35 2017 -0500
@@ -67,6 +67,7 @@
$(SRC_DIR)/org.graalvm.compiler.phases.common/src \
$(SRC_DIR)/org.graalvm.compiler.serviceprovider/src \
$(SRC_DIR)/org.graalvm.compiler.virtual/src \
+ $(SRC_DIR)/org.graalvm.graphio/src \
$(SRC_DIR)/org.graalvm.util/src \
$(VM_CI_SRC_DIR)/jdk.vm.ci.code/src \
$(VM_CI_SRC_DIR)/jdk.vm.ci.common/src \
@@ -125,6 +126,7 @@
$(SRC_DIR)/org.graalvm.compiler.nodeinfo/src \
$(SRC_DIR)/org.graalvm.compiler.options/src \
$(SRC_DIR)/org.graalvm.compiler.serviceprovider/src \
+ $(SRC_DIR)/org.graalvm.graphio/src \
$(SRC_DIR)/org.graalvm.util/src \
$(VM_CI_SRC_DIR)/jdk.vm.ci.code/src \
$(VM_CI_SRC_DIR)/jdk.vm.ci.common/src \
--- a/make/autoconf/basics.m4 Mon Nov 06 19:45:47 2017 +0100
+++ b/make/autoconf/basics.m4 Wed Nov 08 16:03:35 2017 -0500
@@ -639,6 +639,14 @@
elif test -d "$DEVKIT_ROOT/$host/sys-root"; then
SYSROOT="$DEVKIT_ROOT/$host/sys-root"
fi
+
+ if test "x$DEVKIT_ROOT" != x; then
+ DEVKIT_LIB_DIR="$DEVKIT_ROOT/lib"
+ if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+ DEVKIT_LIB_DIR="$DEVKIT_ROOT/lib64"
+ fi
+ AC_SUBST(DEVKIT_LIB_DIR)
+ fi
]
)
--- a/make/autoconf/configure.ac Mon Nov 06 19:45:47 2017 +0100
+++ b/make/autoconf/configure.ac Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
SRC#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
@@ -203,6 +203,9 @@
JDKOPT_SETUP_DEBUG_SYMBOLS
JDKOPT_SETUP_CODE_COVERAGE
+# AddressSanitizer
+JDKOPT_SETUP_ADDRESS_SANITIZER
+
# Need toolchain to setup dtrace
HOTSPOT_SETUP_DTRACE
HOTSPOT_ENABLE_DISABLE_AOT
--- a/make/autoconf/generated-configure.sh Mon Nov 06 19:45:47 2017 +0100
+++ b/make/autoconf/generated-configure.sh Wed Nov 08 16:03:35 2017 -0500
@@ -690,6 +690,7 @@
FREETYPE_BUNDLE_LIB_PATH
FREETYPE_LIBS
FREETYPE_CFLAGS
+FONTCONFIG_CFLAGS
CUPS_CFLAGS
X_EXTRA_LIBS
X_LIBS
@@ -704,6 +705,7 @@
BUILD_GTEST
ENABLE_CDS
ENABLE_AOT
+ASAN_ENABLED
GCOV_ENABLED
ZIP_EXTERNAL_DEBUG_SYMBOLS
COPY_DEBUG_SYMBOLS
@@ -958,6 +960,7 @@
SPEC
SDKROOT
XCODEBUILD
+DEVKIT_LIB_DIR
JVM_VARIANT_MAIN
VALID_JVM_VARIANTS
JVM_VARIANTS
@@ -1171,6 +1174,7 @@
enable_debug_symbols
enable_zip_debug_info
enable_native_coverage
+enable_asan
enable_dtrace
enable_aot
enable_cds
@@ -1181,6 +1185,8 @@
with_x
with_cups
with_cups_include
+with_fontconfig
+with_fontconfig_include
with_freetype
with_freetype_include
with_freetype_lib
@@ -1976,6 +1982,7 @@
--enable-native-coverage
enable native compilation with code coverage
data[disabled]
+ --enable-asan enable AddressSanitizer if possible [disabled]
--enable-dtrace[=yes/no/auto]
enable dtrace. Default is auto, where dtrace is
enabled if all dependencies are present.
@@ -2109,6 +2116,10 @@
--with-cups specify prefix directory for the cups package
(expecting the headers under PATH/include)
--with-cups-include specify directory for the cups include files
+ --with-fontconfig specify prefix directory for the fontconfig package
+ (expecting the headers under PATH/include)
+ --with-fontconfig-include
+ specify directory for the fontconfig include files
--with-freetype specify prefix directory for the freetype package
(expecting the libraries under PATH/lib and the
headers under PATH/include)
@@ -4166,6 +4177,8 @@
PKGHANDLER_COMMAND="sudo apt-get install libasound2-dev" ;;
cups)
PKGHANDLER_COMMAND="sudo apt-get install libcups2-dev" ;;
+ fontconfig)
+ PKGHANDLER_COMMAND="sudo apt-get install libfontconfig1-dev" ;;
freetype)
PKGHANDLER_COMMAND="sudo apt-get install libfreetype6-dev" ;;
ffi)
@@ -4189,6 +4202,8 @@
PKGHANDLER_COMMAND="sudo yum install alsa-lib-devel" ;;
cups)
PKGHANDLER_COMMAND="sudo yum install cups-devel" ;;
+ fontconfig)
+ PKGHANDLER_COMMAND="sudo yum install fontconfig-devel" ;;
freetype)
PKGHANDLER_COMMAND="sudo yum install freetype-devel" ;;
x11)
@@ -4403,6 +4418,12 @@
#
+###############################################################################
+#
+# AddressSanitizer
+#
+
+
################################################################################
#
# Static build support. When enabled will generate static
@@ -4746,6 +4767,36 @@
################################################################################
+#
+# 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.
+#
+
+################################################################################
+# Setup fontconfig
+################################################################################
+
+
################################################################################
# Determine which libraries are needed for this configuration
@@ -5115,7 +5166,7 @@
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1509013542
+DATE_WHEN_GENERATED=1509128484
###############################################################################
#
@@ -17273,6 +17324,14 @@
SYSROOT="$DEVKIT_ROOT/$host/sys-root"
fi
+ if test "x$DEVKIT_ROOT" != x; then
+ DEVKIT_LIB_DIR="$DEVKIT_ROOT/lib"
+ if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+ DEVKIT_LIB_DIR="$DEVKIT_ROOT/lib64"
+ fi
+
+ fi
+
fi
@@ -54169,6 +54228,49 @@
+# AddressSanitizer
+
+ # Check whether --enable-asan was given.
+if test "${enable_asan+set}" = set; then :
+ enableval=$enable_asan;
+fi
+
+ ASAN_ENABLED="no"
+ if test "x$enable_asan" = "xyes"; then
+ case $TOOLCHAIN_TYPE in
+ gcc | clang)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if asan is enabled" >&5
+$as_echo_n "checking if asan is enabled... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ ASAN_CFLAGS="-fsanitize=address -fno-omit-frame-pointer"
+ ASAN_LDFLAGS="-fsanitize=address"
+ JVM_CFLAGS="$JVM_CFLAGS $ASAN_CFLAGS"
+ JVM_LDFLAGS="$JVM_LDFLAGS $ASAN_LDFLAGS"
+ CFLAGS_JDKLIB="$CFLAGS_JDKLIB $ASAN_CFLAGS"
+ CFLAGS_JDKEXE="$CFLAGS_JDKEXE $ASAN_CFLAGS"
+ CXXFLAGS_JDKLIB="$CXXFLAGS_JDKLIB $ASAN_CFLAGS"
+ CXXFLAGS_JDKEXE="$CXXFLAGS_JDKEXE $ASAN_CFLAGS"
+ LDFLAGS_JDKLIB="$LDFLAGS_JDKLIB $ASAN_LDFLAGS"
+ LDFLAGS_JDKEXE="$LDFLAGS_JDKEXE $ASAN_LDFLAGS"
+ ASAN_ENABLED="yes"
+ ;;
+ *)
+ as_fn_error $? "--enable-asan only works with toolchain type gcc or clang" "$LINENO" 5
+ ;;
+ esac
+ elif test "x$enable_asan" = "xno"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if asan is enabled" >&5
+$as_echo_n "checking if asan is enabled... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ elif test "x$enable_asan" != "x"; then
+ as_fn_error $? "--enable-asan can only be assigned \"yes\" or \"no\"" "$LINENO" 5
+ fi
+
+
+
+
# Need toolchain to setup dtrace
# Test for dtrace dependencies
@@ -54480,6 +54582,16 @@
NEEDS_LIB_X11=true
fi
+ # Check if fontconfig is needed
+ if test "x$OPENJDK_TARGET_OS" = xwindows || test "x$OPENJDK_TARGET_OS" = xmacosx; then
+ # No fontconfig support on windows or macosx
+ NEEDS_LIB_FONTCONFIG=false
+ else
+ # All other instances need fontconfig, even if building headless only,
+ # libawt still needs fontconfig headers.
+ NEEDS_LIB_FONTCONFIG=true
+ fi
+
# Check if cups is needed
if test "x$OPENJDK_TARGET_OS" = xwindows; then
# Windows have a separate print system
@@ -58297,6 +58409,116 @@
+# Check whether --with-fontconfig was given.
+if test "${with_fontconfig+set}" = set; then :
+ withval=$with_fontconfig;
+fi
+
+
+# Check whether --with-fontconfig-include was given.
+if test "${with_fontconfig_include+set}" = set; then :
+ withval=$with_fontconfig_include;
+fi
+
+
+ if test "x$NEEDS_LIB_FONTCONFIG" = xfalse; then
+ if (test "x${with_fontconfig}" != x && test "x${with_fontconfig}" != xno) || \
+ (test "x${with_fontconfig_include}" != x && test "x${with_fontconfig_include}" != xno); then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: fontconfig not used, so --with-fontconfig[-*] is ignored" >&5
+$as_echo "$as_me: WARNING: fontconfig not used, so --with-fontconfig[-*] is ignored" >&2;}
+ fi
+ FONTCONFIG_CFLAGS=
+ else
+ FONTCONFIG_FOUND=no
+
+ if test "x${with_fontconfig}" = xno || test "x${with_fontconfig_include}" = xno; then
+ as_fn_error $? "It is not possible to disable the use of fontconfig. Remove the --without-fontconfig option." "$LINENO" 5
+ fi
+
+ if test "x${with_fontconfig}" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fontconfig headers" >&5
+$as_echo_n "checking for fontconfig headers... " >&6; }
+ if test -s "${with_fontconfig}/include/fontconfig/fontconfig.h"; then
+ FONTCONFIG_CFLAGS="-I${with_fontconfig}/include"
+ FONTCONFIG_FOUND=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FONTCONFIG_FOUND" >&5
+$as_echo "$FONTCONFIG_FOUND" >&6; }
+ else
+ as_fn_error $? "Can't find 'include/fontconfig/fontconfig.h' under ${with_fontconfig} given with the --with-fontconfig option." "$LINENO" 5
+ fi
+ fi
+ if test "x${with_fontconfig_include}" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fontconfig headers" >&5
+$as_echo_n "checking for fontconfig headers... " >&6; }
+ if test -s "${with_fontconfig_include}/fontconfig/fontconfig.h"; then
+ FONTCONFIG_CFLAGS="-I${with_fontconfig_include}"
+ FONTCONFIG_FOUND=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FONTCONFIG_FOUND" >&5
+$as_echo "$FONTCONFIG_FOUND" >&6; }
+ else
+ as_fn_error $? "Can't find 'fontconfig/fontconfig.h' under ${with_fontconfig_include} given with the --with-fontconfig-include option." "$LINENO" 5
+ fi
+ fi
+ if test "x$FONTCONFIG_FOUND" = xno; then
+ # Are the fontconfig headers installed in the default /usr/include location?
+ for ac_header in fontconfig/fontconfig.h
+do :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "fontconfig/fontconfig.h" "ac_cv_header_fontconfig_fontconfig_h" "$ac_includes_default"
+if test "x$ac_cv_header_fontconfig_fontconfig_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FONTCONFIG_FONTCONFIG_H 1
+_ACEOF
+
+ FONTCONFIG_FOUND=yes
+ FONTCONFIG_CFLAGS=
+ DEFAULT_FONTCONFIG=yes
+
+fi
+
+done
+
+ fi
+ if test "x$FONTCONFIG_FOUND" = xno; then
+
+ # Print a helpful message on how to acquire the necessary build dependency.
+ # fontconfig is the help tag: freetype, cups, alsa etc
+ MISSING_DEPENDENCY=fontconfig
+
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+ cygwin_help $MISSING_DEPENDENCY
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+ msys_help $MISSING_DEPENDENCY
+ else
+ PKGHANDLER_COMMAND=
+
+ case $PKGHANDLER in
+ apt-get)
+ apt_help $MISSING_DEPENDENCY ;;
+ yum)
+ yum_help $MISSING_DEPENDENCY ;;
+ brew)
+ brew_help $MISSING_DEPENDENCY ;;
+ port)
+ port_help $MISSING_DEPENDENCY ;;
+ pkgutil)
+ pkgutil_help $MISSING_DEPENDENCY ;;
+ pkgadd)
+ pkgadd_help $MISSING_DEPENDENCY ;;
+ esac
+
+ if test "x$PKGHANDLER_COMMAND" != x; then
+ HELP_MSG="You might be able to fix this by running '$PKGHANDLER_COMMAND'."
+ fi
+ fi
+
+ as_fn_error $? "Could not find fontconfig! $HELP_MSG " "$LINENO" 5
+ fi
+ fi
+
+
+
+
+
# Check whether --with-freetype was given.
if test "${with_freetype+set}" = set; then :
withval=$with_freetype;
@@ -65831,6 +66053,7 @@
+
# Hotspot setup depends on lib checks.
--- a/make/autoconf/help.m4 Mon Nov 06 19:45:47 2017 +0100
+++ b/make/autoconf/help.m4 Wed Nov 08 16:03:35 2017 -0500
@@ -113,6 +113,8 @@
PKGHANDLER_COMMAND="sudo apt-get install libasound2-dev" ;;
cups)
PKGHANDLER_COMMAND="sudo apt-get install libcups2-dev" ;;
+ fontconfig)
+ PKGHANDLER_COMMAND="sudo apt-get install libfontconfig1-dev" ;;
freetype)
PKGHANDLER_COMMAND="sudo apt-get install libfreetype6-dev" ;;
ffi)
@@ -136,6 +138,8 @@
PKGHANDLER_COMMAND="sudo yum install alsa-lib-devel" ;;
cups)
PKGHANDLER_COMMAND="sudo yum install cups-devel" ;;
+ fontconfig)
+ PKGHANDLER_COMMAND="sudo yum install fontconfig-devel" ;;
freetype)
PKGHANDLER_COMMAND="sudo yum install freetype-devel" ;;
x11)
--- a/make/autoconf/jdk-options.m4 Mon Nov 06 19:45:47 2017 +0100
+++ b/make/autoconf/jdk-options.m4 Wed Nov 08 16:03:35 2017 -0500
@@ -399,6 +399,46 @@
AC_SUBST(GCOV_ENABLED)
])
+###############################################################################
+#
+# AddressSanitizer
+#
+AC_DEFUN_ONCE([JDKOPT_SETUP_ADDRESS_SANITIZER],
+[
+ AC_ARG_ENABLE(asan, [AS_HELP_STRING([--enable-asan],
+ [enable AddressSanitizer if possible @<:@disabled@:>@])])
+ ASAN_ENABLED="no"
+ if test "x$enable_asan" = "xyes"; then
+ case $TOOLCHAIN_TYPE in
+ gcc | clang)
+ AC_MSG_CHECKING([if asan is enabled])
+ AC_MSG_RESULT([yes])
+ ASAN_CFLAGS="-fsanitize=address -fno-omit-frame-pointer"
+ ASAN_LDFLAGS="-fsanitize=address"
+ JVM_CFLAGS="$JVM_CFLAGS $ASAN_CFLAGS"
+ JVM_LDFLAGS="$JVM_LDFLAGS $ASAN_LDFLAGS"
+ CFLAGS_JDKLIB="$CFLAGS_JDKLIB $ASAN_CFLAGS"
+ CFLAGS_JDKEXE="$CFLAGS_JDKEXE $ASAN_CFLAGS"
+ CXXFLAGS_JDKLIB="$CXXFLAGS_JDKLIB $ASAN_CFLAGS"
+ CXXFLAGS_JDKEXE="$CXXFLAGS_JDKEXE $ASAN_CFLAGS"
+ LDFLAGS_JDKLIB="$LDFLAGS_JDKLIB $ASAN_LDFLAGS"
+ LDFLAGS_JDKEXE="$LDFLAGS_JDKEXE $ASAN_LDFLAGS"
+ ASAN_ENABLED="yes"
+ ;;
+ *)
+ AC_MSG_ERROR([--enable-asan only works with toolchain type gcc or clang])
+ ;;
+ esac
+ elif test "x$enable_asan" = "xno"; then
+ AC_MSG_CHECKING([if asan is enabled])
+ AC_MSG_RESULT([no])
+ elif test "x$enable_asan" != "x"; then
+ AC_MSG_ERROR([--enable-asan can only be assigned "yes" or "no"])
+ fi
+
+ AC_SUBST(ASAN_ENABLED)
+])
+
################################################################################
#
# Static build support. When enabled will generate static
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/make/autoconf/lib-fontconfig.m4 Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,85 @@
+#
+# 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.
+#
+
+################################################################################
+# Setup fontconfig
+################################################################################
+AC_DEFUN_ONCE([LIB_SETUP_FONTCONFIG],
+[
+ AC_ARG_WITH(fontconfig, [AS_HELP_STRING([--with-fontconfig],
+ [specify prefix directory for the fontconfig package
+ (expecting the headers under PATH/include)])])
+ AC_ARG_WITH(fontconfig-include, [AS_HELP_STRING([--with-fontconfig-include],
+ [specify directory for the fontconfig include files])])
+
+ if test "x$NEEDS_LIB_FONTCONFIG" = xfalse; then
+ if (test "x${with_fontconfig}" != x && test "x${with_fontconfig}" != xno) || \
+ (test "x${with_fontconfig_include}" != x && test "x${with_fontconfig_include}" != xno); then
+ AC_MSG_WARN([[fontconfig not used, so --with-fontconfig[-*] is ignored]])
+ fi
+ FONTCONFIG_CFLAGS=
+ else
+ FONTCONFIG_FOUND=no
+
+ if test "x${with_fontconfig}" = xno || test "x${with_fontconfig_include}" = xno; then
+ AC_MSG_ERROR([It is not possible to disable the use of fontconfig. Remove the --without-fontconfig option.])
+ fi
+
+ if test "x${with_fontconfig}" != x; then
+ AC_MSG_CHECKING([for fontconfig headers])
+ if test -s "${with_fontconfig}/include/fontconfig/fontconfig.h"; then
+ FONTCONFIG_CFLAGS="-I${with_fontconfig}/include"
+ FONTCONFIG_FOUND=yes
+ AC_MSG_RESULT([$FONTCONFIG_FOUND])
+ else
+ AC_MSG_ERROR([Can't find 'include/fontconfig/fontconfig.h' under ${with_fontconfig} given with the --with-fontconfig option.])
+ fi
+ fi
+ if test "x${with_fontconfig_include}" != x; then
+ AC_MSG_CHECKING([for fontconfig headers])
+ if test -s "${with_fontconfig_include}/fontconfig/fontconfig.h"; then
+ FONTCONFIG_CFLAGS="-I${with_fontconfig_include}"
+ FONTCONFIG_FOUND=yes
+ AC_MSG_RESULT([$FONTCONFIG_FOUND])
+ else
+ AC_MSG_ERROR([Can't find 'fontconfig/fontconfig.h' under ${with_fontconfig_include} given with the --with-fontconfig-include option.])
+ fi
+ fi
+ if test "x$FONTCONFIG_FOUND" = xno; then
+ # Are the fontconfig headers installed in the default /usr/include location?
+ AC_CHECK_HEADERS([fontconfig/fontconfig.h], [
+ FONTCONFIG_FOUND=yes
+ FONTCONFIG_CFLAGS=
+ DEFAULT_FONTCONFIG=yes
+ ])
+ fi
+ if test "x$FONTCONFIG_FOUND" = xno; then
+ HELP_MSG_MISSING_DEPENDENCY([fontconfig])
+ AC_MSG_ERROR([Could not find fontconfig! $HELP_MSG ])
+ fi
+ fi
+
+ AC_SUBST(FONTCONFIG_CFLAGS)
+])
--- a/make/autoconf/libraries.m4 Mon Nov 06 19:45:47 2017 +0100
+++ b/make/autoconf/libraries.m4 Wed Nov 08 16:03:35 2017 -0500
@@ -31,6 +31,7 @@
m4_include([lib-freetype.m4])
m4_include([lib-std.m4])
m4_include([lib-x11.m4])
+m4_include([lib-fontconfig.m4])
################################################################################
# Determine which libraries are needed for this configuration
@@ -47,6 +48,16 @@
NEEDS_LIB_X11=true
fi
+ # Check if fontconfig is needed
+ if test "x$OPENJDK_TARGET_OS" = xwindows || test "x$OPENJDK_TARGET_OS" = xmacosx; then
+ # No fontconfig support on windows or macosx
+ NEEDS_LIB_FONTCONFIG=false
+ else
+ # All other instances need fontconfig, even if building headless only,
+ # libawt still needs fontconfig headers.
+ NEEDS_LIB_FONTCONFIG=true
+ fi
+
# Check if cups is needed
if test "x$OPENJDK_TARGET_OS" = xwindows; then
# Windows have a separate print system
@@ -83,6 +94,7 @@
LIB_SETUP_STD_LIBS
LIB_SETUP_X11
LIB_SETUP_CUPS
+ LIB_SETUP_FONTCONFIG
LIB_SETUP_FREETYPE
LIB_SETUP_ALSA
LIB_SETUP_LIBFFI
--- a/make/autoconf/spec.gmk.in Mon Nov 06 19:45:47 2017 +0100
+++ b/make/autoconf/spec.gmk.in Wed Nov 08 16:03:35 2017 -0500
@@ -311,6 +311,16 @@
GCOV_ENABLED=@GCOV_ENABLED@
+# AddressSanitizer
+export ASAN_ENABLED:=@ASAN_ENABLED@
+export DEVKIT_LIB_DIR:=@DEVKIT_LIB_DIR@
+ifeq ($(ASAN_ENABLED), yes)
+ export ASAN_OPTIONS="handle_segv=0 detect_leaks=0"
+ ifneq ($(DEVKIT_LIB_DIR),)
+ export LD_LIBRARY_PATH:=$(LD_LIBRARY_PATH):$(DEVKIT_LIB_DIR)
+ endif
+endif
+
# Necessary additional compiler flags to compile X11
X_CFLAGS:=@X_CFLAGS@
X_LIBS:=@X_LIBS@
--- a/make/conf/jib-profiles.js Mon Nov 06 19:45:47 2017 +0100
+++ b/make/conf/jib-profiles.js Wed Nov 08 16:03:35 2017 -0500
@@ -1060,7 +1060,7 @@
jtreg: {
server: "javare",
revision: "4.2",
- build_number: "b09",
+ build_number: "b10",
checksum_file: "MD5_VALUES",
file: "jtreg_bin-4.2.zip",
environment_name: "JT_HOME",
--- a/make/lib/Awt2dLibraries.gmk Mon Nov 06 19:45:47 2017 +0100
+++ b/make/lib/Awt2dLibraries.gmk Wed Nov 08 16:03:35 2017 -0500
@@ -317,6 +317,7 @@
LIBAWT_XAWT_CFLAGS += -DXAWT -DXAWT_HACK \
-DPACKAGE_PATH=\"$(PACKAGE_PATH)\" \
+ $(FONTCONFIG_CFLAGS) \
$(CUPS_CFLAGS)
ifeq ($(OPENJDK_TARGET_OS), solaris)
@@ -555,6 +556,7 @@
-DHEADLESS=true \
-DPACKAGE_PATH=\"$(PACKAGE_PATH)\" \
$(CUPS_CFLAGS) \
+ $(FONTCONFIG_CFLAGS) \
$(X_CFLAGS) \
$(LIBAWT_HEADLESS_CFLAGS), \
DISABLED_WARNINGS_xlc := 1506-356, \
--- a/src/hotspot/cpu/aarch64/frame_aarch64.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/cpu/aarch64/frame_aarch64.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -431,11 +431,11 @@
// This is the sp before any possible extension (adapter/locals).
intptr_t* unextended_sp = interpreter_frame_sender_sp();
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
if (map->update_map()) {
update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset));
}
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
return frame(sender_sp, unextended_sp, link(), sender_pc());
}
--- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -41,7 +41,7 @@
#ifdef COMPILER1
#include "c1/c1_Runtime1.hpp"
#endif
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
#include "adfiles/ad_aarch64.hpp"
#include "opto/runtime.hpp"
#endif
@@ -114,7 +114,7 @@
};
OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
if (save_vectors) {
// Save upper half of vector registers
int vect_words = 32 * 8 / wordSize;
@@ -2688,7 +2688,7 @@
return 0;
}
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
//------------------------------generate_uncommon_trap_blob--------------------
void SharedRuntime::generate_uncommon_trap_blob() {
// Allocate space for the code
@@ -2894,7 +2894,7 @@
}
#endif
}
-#endif // COMPILER2
+#endif // COMPILER2_OR_JVMCI
//------------------------------generate_handler_blob------
@@ -3070,8 +3070,7 @@
return RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_in_words, oop_maps, true);
}
-
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
// This is here instead of runtime_x86_64.cpp because it uses SimpleRuntimeFrame
//
//------------------------------generate_exception_blob---------------------------
@@ -3200,4 +3199,4 @@
// Set exception blob
_exception_blob = ExceptionBlob::create(&buffer, oop_maps, SimpleRuntimeFrame::framesize >> 1);
}
-#endif // COMPILER2
+#endif // COMPILER2_OR_JVMCI
--- a/src/hotspot/cpu/arm/compiledIC_arm.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/cpu/arm/compiledIC_arm.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -33,7 +33,7 @@
#include "runtime/safepoint.hpp"
// ----------------------------------------------------------------------------
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
#define __ _masm.
// emit call stub, compiled java to interpreter
address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark) {
@@ -89,7 +89,7 @@
int CompiledStaticCall::reloc_to_interp_stub() {
return 10; // 4 in emit_to_interp_stub + 1 in Java_Static_Call
}
-#endif // COMPILER2 || JVMCI
+#endif // COMPILER2_OR_JVMCI
// size of C2 call stub, compiled java to interpretor
int CompiledStaticCall::to_interp_stub_size() {
--- a/src/hotspot/cpu/x86/frame_x86.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/cpu/x86/frame_x86.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -436,11 +436,11 @@
// This is the sp before any possible extension (adapter/locals).
intptr_t* unextended_sp = interpreter_frame_sender_sp();
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
if (map->update_map()) {
update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset));
}
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
return frame(sender_sp, unextended_sp, link(), sender_pc());
}
--- a/src/hotspot/cpu/x86/globals_x86.hpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/cpu/x86/globals_x86.hpp Wed Nov 08 16:03:35 2017 -0500
@@ -46,11 +46,11 @@
// the the vep is aligned at CodeEntryAlignment whereas c2 only aligns
// the uep and the vep doesn't get real alignment but just slops on by
// only assured that the entry instruction meets the 5 byte size requirement.
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
define_pd_global(intx, CodeEntryAlignment, 32);
#else
define_pd_global(intx, CodeEntryAlignment, 16);
-#endif // COMPILER2
+#endif // COMPILER2_OR_JVMCI
define_pd_global(intx, OptoLoopAlignment, 16);
define_pd_global(intx, InlineFrequencyCount, 100);
define_pd_global(intx, InlineSmallCode, 1000);
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -151,7 +151,7 @@
if (UseAVX < 3) {
num_xmm_regs = num_xmm_regs/2;
}
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
if (save_vectors) {
assert(UseAVX > 0, "Vectors larger than 16 byte long are supported only with AVX");
assert(MaxVectorSize <= 64, "Only up to 64 byte long vectors are supported");
@@ -260,7 +260,7 @@
}
}
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
if (save_vectors) {
off = ymm0_off;
int delta = ymm1_off - off;
@@ -270,7 +270,7 @@
off += delta;
}
}
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
// %%% These should all be a waste but we'll keep things as they were for now
if (true) {
@@ -323,7 +323,7 @@
__ addptr(rsp, frame::arg_reg_save_area_bytes);
}
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
if (restore_vectors) {
assert(UseAVX > 0, "Vectors larger than 16 byte long are supported only with AVX");
assert(MaxVectorSize <= 64, "Only up to 64 byte long vectors are supported");
--- a/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2016, 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
@@ -3433,6 +3433,8 @@
}
address generate_libmExp() {
+ StubCodeMark mark(this, "StubRoutines", "libmExp");
+
address start = __ pc();
const XMMRegister x0 = xmm0;
@@ -3458,6 +3460,8 @@
}
address generate_libmLog() {
+ StubCodeMark mark(this, "StubRoutines", "libmLog");
+
address start = __ pc();
const XMMRegister x0 = xmm0;
@@ -3483,6 +3487,8 @@
}
address generate_libmLog10() {
+ StubCodeMark mark(this, "StubRoutines", "libmLog10");
+
address start = __ pc();
const XMMRegister x0 = xmm0;
@@ -3508,6 +3514,8 @@
}
address generate_libmPow() {
+ StubCodeMark mark(this, "StubRoutines", "libmPow");
+
address start = __ pc();
const XMMRegister x0 = xmm0;
@@ -3533,6 +3541,8 @@
}
address generate_libm_reduce_pi04l() {
+ StubCodeMark mark(this, "StubRoutines", "libm_reduce_pi04l");
+
address start = __ pc();
BLOCK_COMMENT("Entry:");
@@ -3543,6 +3553,8 @@
}
address generate_libm_sin_cos_huge() {
+ StubCodeMark mark(this, "StubRoutines", "libm_sin_cos_huge");
+
address start = __ pc();
const XMMRegister x0 = xmm0;
@@ -3556,6 +3568,8 @@
}
address generate_libmSin() {
+ StubCodeMark mark(this, "StubRoutines", "libmSin");
+
address start = __ pc();
const XMMRegister x0 = xmm0;
@@ -3579,6 +3593,8 @@
}
address generate_libmCos() {
+ StubCodeMark mark(this, "StubRoutines", "libmCos");
+
address start = __ pc();
const XMMRegister x0 = xmm0;
@@ -3604,6 +3620,8 @@
}
address generate_libm_tan_cot_huge() {
+ StubCodeMark mark(this, "StubRoutines", "libm_tan_cot_huge");
+
address start = __ pc();
const XMMRegister x0 = xmm0;
@@ -3617,6 +3635,8 @@
}
address generate_libmTan() {
+ StubCodeMark mark(this, "StubRoutines", "libmTan");
+
address start = __ pc();
const XMMRegister x0 = xmm0;
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -4619,6 +4619,8 @@
}
address generate_libmExp() {
+ StubCodeMark mark(this, "StubRoutines", "libmExp");
+
address start = __ pc();
const XMMRegister x0 = xmm0;
@@ -4646,6 +4648,8 @@
}
address generate_libmLog() {
+ StubCodeMark mark(this, "StubRoutines", "libmLog");
+
address start = __ pc();
const XMMRegister x0 = xmm0;
@@ -4674,6 +4678,8 @@
}
address generate_libmLog10() {
+ StubCodeMark mark(this, "StubRoutines", "libmLog10");
+
address start = __ pc();
const XMMRegister x0 = xmm0;
@@ -4701,6 +4707,8 @@
}
address generate_libmPow() {
+ StubCodeMark mark(this, "StubRoutines", "libmPow");
+
address start = __ pc();
const XMMRegister x0 = xmm0;
@@ -4731,6 +4739,8 @@
}
address generate_libmSin() {
+ StubCodeMark mark(this, "StubRoutines", "libmSin");
+
address start = __ pc();
const XMMRegister x0 = xmm0;
@@ -4770,6 +4780,8 @@
}
address generate_libmCos() {
+ StubCodeMark mark(this, "StubRoutines", "libmCos");
+
address start = __ pc();
const XMMRegister x0 = xmm0;
@@ -4809,6 +4821,8 @@
}
address generate_libmTan() {
+ StubCodeMark mark(this, "StubRoutines", "libmTan");
+
address start = __ pc();
const XMMRegister x0 = xmm0;
--- a/src/hotspot/cpu/x86/vm_version_x86.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/cpu/x86/vm_version_x86.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -944,7 +944,7 @@
}
}
#endif
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
if (MaxVectorSize > 0) {
if (!is_power_of_2(MaxVectorSize)) {
warning("MaxVectorSize must be a power of 2");
@@ -996,7 +996,7 @@
}
#endif // COMPILER2 && ASSERT
}
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
#ifdef COMPILER2
#ifdef _LP64
--- a/src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -73,7 +73,7 @@
frame ret_frame(ret_sp, ret_fp, addr.pc());
if (!ret_frame.safe_for_sender(jt)) {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
// C2 and JVMCI use ebp as a general register see if NULL fp helps
frame ret_frame2(ret_sp, NULL, addr.pc());
if (!ret_frame2.safe_for_sender(jt)) {
@@ -84,7 +84,7 @@
#else
// nothing else to try if the frame isn't good
return false;
-#endif /* COMPILER2 || INCLUDE_JVMCI */
+#endif // COMPILER2_OR_JVMCI
}
*fr_addr = ret_frame;
return true;
--- a/src/hotspot/os_cpu/linux_x86/thread_linux_x86.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/os_cpu/linux_x86/thread_linux_x86.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -74,7 +74,7 @@
frame ret_frame(ret_sp, ret_fp, addr.pc());
if (!ret_frame.safe_for_sender(jt)) {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
// C2 and JVMCI use ebp as a general register see if NULL fp helps
frame ret_frame2(ret_sp, NULL, addr.pc());
if (!ret_frame2.safe_for_sender(jt)) {
@@ -85,7 +85,7 @@
#else
// nothing else to try if the frame isn't good
return false;
-#endif /* COMPILER2 || INCLUDE_JVMCI */
+#endif // COMPILER2_OR_JVMCI
}
*fr_addr = ret_frame;
return true;
--- a/src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -81,7 +81,7 @@
frame ret_frame(ret_sp, ret_fp, addr.pc());
if (!ret_frame.safe_for_sender(jt)) {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
// C2 and JVMCI use ebp as a general register see if NULL fp helps
frame ret_frame2(ret_sp, NULL, addr.pc());
if (!ret_frame2.safe_for_sender(jt)) {
@@ -92,7 +92,7 @@
#else
// nothing else to try if the frame isn't good
return false;
-#endif /* COMPILER2 || INCLUDE_JVMCI */
+#endif // COMPILER2_OR_JVMCI
}
*fr_addr = ret_frame;
return true;
--- a/src/hotspot/share/aot/aotCodeHeap.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/aot/aotCodeHeap.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -490,6 +490,8 @@
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_checkcast_arraycopy", address, StubRoutines::_checkcast_arraycopy);
+ SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_generic_arraycopy", address, StubRoutines::_generic_arraycopy);
+
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_aescrypt_encryptBlock", address, StubRoutines::_aescrypt_encryptBlock);
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_aescrypt_decryptBlock", address, StubRoutines::_aescrypt_decryptBlock);
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_cipherBlockChaining_encryptAESCrypt", address, StubRoutines::_cipherBlockChaining_encryptAESCrypt);
--- a/src/hotspot/share/code/scopeDesc.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/code/scopeDesc.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -228,7 +228,7 @@
}
}
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
if (NOT_JVMCI(DoEscapeAnalysis &&) is_top() && _objects != NULL) {
st->print_cr(" Objects");
for (int i = 0; i < _objects->length(); i++) {
@@ -239,7 +239,7 @@
st->cr();
}
}
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
}
#endif
--- a/src/hotspot/share/compiler/oopMap.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/compiler/oopMap.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -268,9 +268,9 @@
#if !defined(TIERED) && !defined(INCLUDE_JVMCI)
COMPILER1_PRESENT(ShouldNotReachHere();)
#endif // !defined(TIERED) && !defined(INCLUDE_JVMCI)
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
DerivedPointerTable::add(derived, base);
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
}
@@ -461,12 +461,12 @@
#if !defined(TIERED) && !defined(INCLUDE_JVMCI)
COMPILER1_PRESENT(return false);
#endif // !TIERED
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
OopMapStream oms(this,OopMapValue::derived_oop_value);
return oms.is_done();
#else
return false;
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
}
#endif //PRODUCT
@@ -726,7 +726,7 @@
//------------------------------DerivedPointerTable---------------------------
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
class DerivedPointerEntry : public CHeapObj<mtCompiler> {
private:
@@ -819,4 +819,4 @@
_active = false;
}
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
--- a/src/hotspot/share/compiler/oopMap.hpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/compiler/oopMap.hpp Wed Nov 08 16:03:35 2017 -0500
@@ -427,7 +427,7 @@
// oops, it is filled in with references to all locations that contains a
// derived oop (assumed to be very few). When the GC is complete, the derived
// pointers are updated based on their base pointers new value and an offset.
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
class DerivedPointerTable : public AllStatic {
friend class VMStructs;
private:
@@ -463,6 +463,6 @@
}
}
};
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
#endif // SHARE_VM_COMPILER_OOPMAP_HPP
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -2296,7 +2296,7 @@
// way with the marking information used by GC.
NoRefDiscovery no_discovery(ref_processor());
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
DerivedPointerTableDeactivate dpt_deact;
#endif
@@ -2869,7 +2869,7 @@
print_eden_and_survivor_chunk_arrays();
{
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
DerivedPointerTableDeactivate dpt_deact;
#endif
if (CMSParallelInitialMarkEnabled) {
@@ -4171,7 +4171,7 @@
print_eden_and_survivor_chunk_arrays();
{
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
DerivedPointerTableDeactivate dpt_deact;
#endif
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -2597,7 +2597,7 @@
// FIXME: what is this about?
// I'm ignoring the "fill_newgen()" call if "alloc_event_enabled"
// is set.
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
assert(DerivedPointerTable::is_empty(), "derived pointer present");
#endif
// always_do_update_barrier = true;
@@ -3010,7 +3010,7 @@
_verifier->check_bitmaps("GC Start");
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
DerivedPointerTable::clear();
#endif
@@ -4439,7 +4439,7 @@
purge_code_root_memory();
redirty_logged_cards();
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
double start = os::elapsedTime();
DerivedPointerTable::update_pointers();
g1_policy()->phase_times()->record_derived_pointer_table_update_time((os::elapsedTime() - start) * 1000.0);
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -414,7 +414,7 @@
debug_time("Redirty Cards", _recorded_redirty_logged_cards_time_ms);
trace_phase(_gc_par_phases[RedirtyCards]);
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
debug_time("DerivedPointerTable Update", _cur_derived_pointer_table_update_time_ms);
#endif
--- a/src/hotspot/share/gc/g1/g1MarkSweep.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1MarkSweep.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -62,7 +62,7 @@
assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
HandleMark hm; // Discard invalid handles created during gc
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
DerivedPointerTable::clear();
#endif
#ifdef ASSERT
@@ -96,7 +96,7 @@
// Prepare compaction.
mark_sweep_phase2();
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
// Don't add any more derived pointers during phase3
DerivedPointerTable::set_active(false);
#endif
@@ -111,7 +111,7 @@
BiasedLocking::restore_marks();
GenMarkSweep::deallocate_stacks();
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
// Now update the derived pointers.
DerivedPointerTable::update_pointers();
#endif
@@ -204,7 +204,7 @@
if (VerifyDuringGC) {
HandleMark hm; // handle scope
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
DerivedPointerTableDeactivate dpt_deact;
#endif
g1h->prepare_for_verify();
--- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -192,7 +192,7 @@
allocate_stacks();
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
DerivedPointerTable::clear();
#endif
@@ -203,7 +203,7 @@
mark_sweep_phase2();
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
// Don't add any more derived pointers during phase3
assert(DerivedPointerTable::is_active(), "Sanity");
DerivedPointerTable::set_active(false);
@@ -252,7 +252,7 @@
CodeCache::gc_epilogue();
JvmtiExport::gc_epilogue();
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
DerivedPointerTable::update_pointers();
#endif
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -1032,7 +1032,7 @@
CodeCache::gc_epilogue();
JvmtiExport::gc_epilogue();
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
DerivedPointerTable::update_pointers();
#endif
@@ -1783,7 +1783,7 @@
CodeCache::gc_prologue();
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
DerivedPointerTable::clear();
#endif
@@ -1799,7 +1799,7 @@
&& GCCause::is_user_requested_gc(gc_cause);
summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc);
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
assert(DerivedPointerTable::is_active(), "Sanity");
DerivedPointerTable::set_active(false);
#endif
--- a/src/hotspot/share/gc/parallel/psScavenge.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/parallel/psScavenge.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -331,7 +331,7 @@
save_to_space_top_before_gc();
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
DerivedPointerTable::clear();
#endif
@@ -601,7 +601,7 @@
assert(young_gen->to_space()->is_empty(), "to space should be empty now");
}
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
DerivedPointerTable::update_pointers();
#endif
--- a/src/hotspot/share/gc/serial/genMarkSweep.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -92,7 +92,7 @@
mark_sweep_phase2();
// Don't add any more derived pointers during phase3
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
assert(DerivedPointerTable::is_active(), "Sanity");
DerivedPointerTable::set_active(false);
#endif
--- a/src/hotspot/share/gc/shared/collectedHeap.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/shared/collectedHeap.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -241,7 +241,7 @@
void CollectedHeap::pre_initialize() {
// Used for ReduceInitialCardMarks (when COMPILER2 is used);
// otherwise remains unused.
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
_defer_initial_card_mark = is_server_compilation_mode_vm() && ReduceInitialCardMarks && can_elide_tlab_store_barriers()
&& (DeferInitialCardMark || card_mark_must_follow_store());
#else
@@ -545,7 +545,7 @@
" to threads list is doomed to failure!");
for (JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
if (use_tlab) thread->tlab().make_parsable(retire_tlabs);
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
// The deferred store barriers must all have been flushed to the
// card-table (or other remembered set structure) before GC starts
// processing the card-table (or other remembered set).
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -1067,11 +1067,11 @@
};
void GenCollectedHeap::gc_epilogue(bool full) {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
assert(DerivedPointerTable::is_empty(), "derived pointer present");
size_t actual_gap = pointer_delta((HeapWord*) (max_uintx-3), *(end_addr()));
guarantee(is_client_compilation_mode_vm() || actual_gap > (size_t)FastAllocateSizeLimit, "inline allocation wraps");
-#endif /* COMPILER2 || INCLUDE_JVMCI */
+#endif // COMPILER2_OR_JVMCI
resize_all_tlabs();
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -921,6 +921,14 @@
int bci = method->bci_from(last_frame.bcp());
nm = method->lookup_osr_nmethod_for(bci, CompLevel_none, false);
}
+ if (nm != NULL && thread->is_interp_only_mode()) {
+ // Normally we never get an nm if is_interp_only_mode() is true, because
+ // policy()->event has a check for this and won't compile the method when
+ // true. However, it's possible for is_interp_only_mode() to become true
+ // during the compilation. We don't want to return the nm in that case
+ // because we want to continue to execute interpreted.
+ nm = NULL;
+ }
#ifndef PRODUCT
if (TraceOnStackReplacement) {
if (nm != NULL) {
--- a/src/hotspot/share/jvmci/jvmciCompiler.hpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/jvmci/jvmciCompiler.hpp Wed Nov 08 16:03:35 2017 -0500
@@ -55,10 +55,13 @@
public:
JVMCICompiler();
- static JVMCICompiler* instance(TRAPS) {
+ static JVMCICompiler* instance(bool require_non_null, TRAPS) {
if (!EnableJVMCI) {
THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVMCI is not enabled")
}
+ if (_instance == NULL && require_non_null) {
+ THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "The JVMCI compiler instance has not been created");
+ }
return _instance;
}
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -1018,7 +1018,7 @@
Handle installed_code_handle(THREAD, JNIHandles::resolve(installed_code));
Handle speculation_log_handle(THREAD, JNIHandles::resolve(speculation_log));
- JVMCICompiler* compiler = JVMCICompiler::instance(CHECK_JNI_ERR);
+ JVMCICompiler* compiler = JVMCICompiler::instance(true, CHECK_JNI_ERR);
TraceTime install_time("installCode", JVMCICompiler::codeInstallTimer());
bool is_immutable_PIC = HotSpotCompiledCode::isImmutablePIC(compiled_code_handle) > 0;
@@ -1136,7 +1136,7 @@
C2V_END
C2V_VMENTRY(void, resetCompilationStatistics, (JNIEnv *jniEnv, jobject))
- JVMCICompiler* compiler = JVMCICompiler::instance(CHECK);
+ JVMCICompiler* compiler = JVMCICompiler::instance(true, CHECK);
CompilerStatistics* stats = compiler->stats();
stats->_standard.reset();
stats->_osr.reset();
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -821,7 +821,7 @@
}
CompLevel JVMCIRuntime::adjust_comp_level_inner(const methodHandle& method, bool is_osr, CompLevel level, JavaThread* thread) {
- JVMCICompiler* compiler = JVMCICompiler::instance(thread);
+ JVMCICompiler* compiler = JVMCICompiler::instance(false, thread);
if (compiler != NULL && compiler->is_bootstrapping()) {
return level;
}
--- a/src/hotspot/share/memory/metachunk.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/memory/metachunk.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -55,8 +55,8 @@
_container(container)
{
_top = initial_top();
+ set_is_tagged_free(false);
#ifdef ASSERT
- set_is_tagged_free(false);
mangle(uninitMetaWordVal);
#endif
}
--- a/src/hotspot/share/memory/metachunk.hpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/memory/metachunk.hpp Wed Nov 08 16:03:35 2017 -0500
@@ -102,7 +102,7 @@
// Current allocation top.
MetaWord* _top;
- DEBUG_ONLY(bool _is_tagged_free;)
+ bool _is_tagged_free;
MetaWord* initial_top() const { return (MetaWord*)this + overhead(); }
MetaWord* top() const { return _top; }
@@ -138,10 +138,8 @@
size_t used_word_size() const;
size_t free_word_size() const;
-#ifdef ASSERT
bool is_tagged_free() { return _is_tagged_free; }
void set_is_tagged_free(bool v) { _is_tagged_free = v; }
-#endif
bool contains(const void* ptr) { return bottom() <= ptr && ptr < _top; }
--- a/src/hotspot/share/memory/metaspace.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/memory/metaspace.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -108,6 +108,18 @@
return (ChunkIndex) (i+1);
}
+static const char* scale_unit(size_t scale) {
+ switch(scale) {
+ case 1: return "BYTES";
+ case K: return "KB";
+ case M: return "MB";
+ case G: return "GB";
+ default:
+ ShouldNotReachHere();
+ return NULL;
+ }
+}
+
volatile intptr_t MetaspaceGC::_capacity_until_GC = 0;
uint MetaspaceGC::_shrink_factor = 0;
bool MetaspaceGC::_should_concurrent_collect = false;
@@ -176,7 +188,7 @@
void locked_get_statistics(ChunkManagerStatistics* stat) const;
void get_statistics(ChunkManagerStatistics* stat) const;
- static void print_statistics(const ChunkManagerStatistics* stat, outputStream* out);
+ static void print_statistics(const ChunkManagerStatistics* stat, outputStream* out, size_t scale);
public:
@@ -283,7 +295,7 @@
// Prints composition for both non-class and (if available)
// class chunk manager.
- static void print_all_chunkmanagers(outputStream* out);
+ static void print_all_chunkmanagers(outputStream* out, size_t scale = 1);
};
class SmallBlocks : public CHeapObj<mtClass> {
@@ -480,6 +492,7 @@
#endif
void print_on(outputStream* st) const;
+ void print_map(outputStream* st, bool is_class) const;
};
#define assert_is_aligned(value, alignment) \
@@ -531,6 +544,94 @@
}
}
+void VirtualSpaceNode::print_map(outputStream* st, bool is_class) const {
+
+ // Format:
+ // <ptr>
+ // <ptr> . .. . . ..
+ // SSxSSMMMMMMMMMMMMMMMMsssXX
+ // 112114444444444444444
+ // <ptr> . .. . . ..
+ // SSxSSMMMMMMMMMMMMMMMMsssXX
+ // 112114444444444444444
+
+ if (bottom() == top()) {
+ return;
+ }
+
+ // First line: dividers for every med-chunk-sized interval
+ // Second line: a dot for the start of a chunk
+ // Third line: a letter per chunk type (x,s,m,h), uppercase if in use.
+
+ const size_t spec_chunk_size = is_class ? ClassSpecializedChunk : SpecializedChunk;
+ const size_t small_chunk_size = is_class ? ClassSmallChunk : SmallChunk;
+ const size_t med_chunk_size = is_class ? ClassMediumChunk : MediumChunk;
+
+ int line_len = 100;
+ const size_t section_len = align_up(spec_chunk_size * line_len, med_chunk_size);
+ line_len = (int)(section_len / spec_chunk_size);
+
+ char* line1 = (char*)os::malloc(line_len, mtInternal);
+ char* line2 = (char*)os::malloc(line_len, mtInternal);
+ char* line3 = (char*)os::malloc(line_len, mtInternal);
+ int pos = 0;
+ const MetaWord* p = bottom();
+ const Metachunk* chunk = (const Metachunk*)p;
+ const MetaWord* chunk_end = p + chunk->word_size();
+ while (p < top()) {
+ if (pos == line_len) {
+ pos = 0;
+ st->fill_to(22);
+ st->print_raw(line1, line_len);
+ st->cr();
+ st->fill_to(22);
+ st->print_raw(line2, line_len);
+ st->cr();
+ }
+ if (pos == 0) {
+ st->print(PTR_FORMAT ":", p2i(p));
+ }
+ if (p == chunk_end) {
+ chunk = (Metachunk*)p;
+ chunk_end = p + chunk->word_size();
+ }
+ if (p == (const MetaWord*)chunk) {
+ // chunk starts.
+ line1[pos] = '.';
+ } else {
+ line1[pos] = ' ';
+ }
+ // Line 2: chunk type (x=spec, s=small, m=medium, h=humongous), uppercase if
+ // chunk is in use.
+ const bool chunk_is_free = ((Metachunk*)chunk)->is_tagged_free();
+ if (chunk->word_size() == spec_chunk_size) {
+ line2[pos] = chunk_is_free ? 'x' : 'X';
+ } else if (chunk->word_size() == small_chunk_size) {
+ line2[pos] = chunk_is_free ? 's' : 'S';
+ } else if (chunk->word_size() == med_chunk_size) {
+ line2[pos] = chunk_is_free ? 'm' : 'M';
+ } else if (chunk->word_size() > med_chunk_size) {
+ line2[pos] = chunk_is_free ? 'h' : 'H';
+ } else {
+ ShouldNotReachHere();
+ }
+ p += spec_chunk_size;
+ pos ++;
+ }
+ if (pos > 0) {
+ st->fill_to(22);
+ st->print_raw(line1, pos);
+ st->cr();
+ st->fill_to(22);
+ st->print_raw(line2, pos);
+ st->cr();
+ }
+ os::free(line1);
+ os::free(line2);
+ os::free(line3);
+}
+
+
#ifdef ASSERT
uintx VirtualSpaceNode::container_count_slow() {
uintx count = 0;
@@ -637,6 +738,7 @@
void purge(ChunkManager* chunk_manager);
void print_on(outputStream* st) const;
+ void print_map(outputStream* st) const;
class VirtualSpaceListIterator : public StackObj {
VirtualSpaceNode* _virtual_spaces;
@@ -1449,6 +1551,18 @@
}
}
+void VirtualSpaceList::print_map(outputStream* st) const {
+ VirtualSpaceNode* list = virtual_space_list();
+ VirtualSpaceListIterator iter(list);
+ unsigned i = 0;
+ while (iter.repeat()) {
+ st->print_cr("Node %u:", i);
+ VirtualSpaceNode* node = iter.get_next();
+ node->print_map(st, this->is_class());
+ i ++;
+ }
+}
+
// MetaspaceGC methods
// VM_CollectForMetadataAllocation is the vm operation used to GC.
@@ -1724,7 +1838,6 @@
#endif
// ChunkManager methods
-
size_t ChunkManager::free_chunks_total_words() {
return _free_chunks_total;
}
@@ -1923,11 +2036,10 @@
// Remove it from the links to this freelist
chunk->set_next(NULL);
chunk->set_prev(NULL);
-#ifdef ASSERT
+
// Chunk is no longer on any freelist. Setting to false make container_count_slow()
// work.
chunk->set_is_tagged_free(false);
-#endif
chunk->container()->inc_container_count();
slow_locked_verify();
@@ -1995,7 +2107,7 @@
chunk_size_name(index), p2i(chunk), chunk->word_size());
}
chunk->container()->dec_container_count();
- DEBUG_ONLY(chunk->set_is_tagged_free(true);)
+ chunk->set_is_tagged_free(true);
// Chunk has been added; update counters.
account_for_added_chunk(chunk);
@@ -2057,22 +2169,45 @@
locked_get_statistics(stat);
}
-void ChunkManager::print_statistics(const ChunkManagerStatistics* stat, outputStream* out) {
+void ChunkManager::print_statistics(const ChunkManagerStatistics* stat, outputStream* out, size_t scale) {
size_t total = 0;
+ assert(scale == 1 || scale == K || scale == M || scale == G, "Invalid scale");
+
+ const char* unit = scale_unit(scale);
for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) {
- out->print_cr(" " SIZE_FORMAT " %s (" SIZE_FORMAT " bytes) chunks, total " SIZE_FORMAT " bytes",
- stat->num_by_type[i], chunk_size_name(i),
- stat->single_size_by_type[i],
- stat->total_size_by_type[i]);
+ out->print(" " SIZE_FORMAT " %s (" SIZE_FORMAT " bytes) chunks, total ",
+ stat->num_by_type[i], chunk_size_name(i),
+ stat->single_size_by_type[i]);
+ if (scale == 1) {
+ out->print_cr(SIZE_FORMAT " bytes", stat->total_size_by_type[i]);
+ } else {
+ out->print_cr("%.2f%s", (float)stat->total_size_by_type[i] / scale, unit);
+ }
+
total += stat->total_size_by_type[i];
}
- out->print_cr(" " SIZE_FORMAT " humongous chunks, total " SIZE_FORMAT " bytes",
- stat->num_humongous_chunks, stat->total_size_humongous_chunks);
+
+
total += stat->total_size_humongous_chunks;
- out->print_cr(" total size: " SIZE_FORMAT ".", total);
+
+ if (scale == 1) {
+ out->print_cr(" " SIZE_FORMAT " humongous chunks, total " SIZE_FORMAT " bytes",
+ stat->num_humongous_chunks, stat->total_size_humongous_chunks);
+
+ out->print_cr(" total size: " SIZE_FORMAT " bytes.", total);
+ } else {
+ out->print_cr(" " SIZE_FORMAT " humongous chunks, total %.2f%s",
+ stat->num_humongous_chunks,
+ (float)stat->total_size_humongous_chunks / scale, unit);
+
+ out->print_cr(" total size: %.2f%s.", (float)total / scale, unit);
+ }
+
}
-void ChunkManager::print_all_chunkmanagers(outputStream* out) {
+void ChunkManager::print_all_chunkmanagers(outputStream* out, size_t scale) {
+ assert(scale == 1 || scale == K || scale == M || scale == G, "Invalid scale");
+
// Note: keep lock protection only to retrieving statistics; keep printing
// out of lock protection
ChunkManagerStatistics stat;
@@ -2080,7 +2215,7 @@
const ChunkManager* const non_class_cm = Metaspace::chunk_manager_metadata();
if (non_class_cm != NULL) {
non_class_cm->get_statistics(&stat);
- ChunkManager::print_statistics(&stat, out);
+ ChunkManager::print_statistics(&stat, out, scale);
} else {
out->print_cr("unavailable.");
}
@@ -2088,7 +2223,7 @@
const ChunkManager* const class_cm = Metaspace::chunk_manager_class();
if (class_cm != NULL) {
class_cm->get_statistics(&stat);
- ChunkManager::print_statistics(&stat, out);
+ ChunkManager::print_statistics(&stat, out, scale);
} else {
out->print_cr("unavailable.");
}
@@ -2911,9 +3046,9 @@
size_t free_bytes = free_bytes_slow(mdtype);
size_t used_and_free = used_bytes + free_bytes +
free_chunks_capacity_bytes;
- out->print_cr(" Chunk accounting: used in chunks " SIZE_FORMAT
+ out->print_cr(" Chunk accounting: (used in chunks " SIZE_FORMAT
"K + unused in chunks " SIZE_FORMAT "K + "
- " capacity in free chunks " SIZE_FORMAT "K = " SIZE_FORMAT
+ " capacity in free chunks " SIZE_FORMAT "K) = " SIZE_FORMAT
"K capacity in allocated chunks " SIZE_FORMAT "K",
used_bytes / K,
free_bytes / K,
@@ -2981,6 +3116,194 @@
}
}
+class MetadataStats VALUE_OBJ_CLASS_SPEC {
+private:
+ size_t _capacity;
+ size_t _used;
+ size_t _free;
+ size_t _waste;
+
+public:
+ MetadataStats() : _capacity(0), _used(0), _free(0), _waste(0) { }
+ MetadataStats(size_t capacity, size_t used, size_t free, size_t waste)
+ : _capacity(capacity), _used(used), _free(free), _waste(waste) { }
+
+ void add(const MetadataStats& stats) {
+ _capacity += stats.capacity();
+ _used += stats.used();
+ _free += stats.free();
+ _waste += stats.waste();
+ }
+
+ size_t capacity() const { return _capacity; }
+ size_t used() const { return _used; }
+ size_t free() const { return _free; }
+ size_t waste() const { return _waste; }
+
+ void print_on(outputStream* out, size_t scale) const;
+};
+
+
+void MetadataStats::print_on(outputStream* out, size_t scale) const {
+ const char* unit = scale_unit(scale);
+ out->print_cr("capacity=%10.2f%s used=%10.2f%s free=%10.2f%s waste=%10.2f%s",
+ (float)capacity() / scale, unit,
+ (float)used() / scale, unit,
+ (float)free() / scale, unit,
+ (float)waste() / scale, unit);
+}
+
+class PrintCLDMetaspaceInfoClosure : public CLDClosure {
+private:
+ outputStream* _out;
+ size_t _scale;
+
+ size_t _total_count;
+ MetadataStats _total_metadata;
+ MetadataStats _total_class;
+
+ size_t _total_anon_count;
+ MetadataStats _total_anon_metadata;
+ MetadataStats _total_anon_class;
+
+public:
+ PrintCLDMetaspaceInfoClosure(outputStream* out, size_t scale = K)
+ : _out(out), _scale(scale), _total_count(0), _total_anon_count(0) { }
+
+ ~PrintCLDMetaspaceInfoClosure() {
+ print_summary();
+ }
+
+ void do_cld(ClassLoaderData* cld) {
+ assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
+
+ if (cld->is_unloading()) return;
+ Metaspace* msp = cld->metaspace_or_null();
+ if (msp == NULL) {
+ return;
+ }
+
+ bool anonymous = false;
+ if (cld->is_anonymous()) {
+ _out->print_cr("ClassLoader: for anonymous class");
+ anonymous = true;
+ } else {
+ ResourceMark rm;
+ _out->print_cr("ClassLoader: %s", cld->loader_name());
+ }
+
+ print_metaspace(msp, anonymous);
+ _out->cr();
+ }
+
+private:
+ void print_metaspace(Metaspace* msp, bool anonymous);
+ void print_summary() const;
+};
+
+void PrintCLDMetaspaceInfoClosure::print_metaspace(Metaspace* msp, bool anonymous){
+ assert(msp != NULL, "Sanity");
+ SpaceManager* vsm = msp->vsm();
+ const char* unit = scale_unit(_scale);
+
+ size_t capacity = vsm->sum_capacity_in_chunks_in_use() * BytesPerWord;
+ size_t used = vsm->sum_used_in_chunks_in_use() * BytesPerWord;
+ size_t free = vsm->sum_free_in_chunks_in_use() * BytesPerWord;
+ size_t waste = vsm->sum_waste_in_chunks_in_use() * BytesPerWord;
+
+ _total_count ++;
+ MetadataStats metadata_stats(capacity, used, free, waste);
+ _total_metadata.add(metadata_stats);
+
+ if (anonymous) {
+ _total_anon_count ++;
+ _total_anon_metadata.add(metadata_stats);
+ }
+
+ _out->print(" Metadata ");
+ metadata_stats.print_on(_out, _scale);
+
+ if (Metaspace::using_class_space()) {
+ vsm = msp->class_vsm();
+
+ capacity = vsm->sum_capacity_in_chunks_in_use() * BytesPerWord;
+ used = vsm->sum_used_in_chunks_in_use() * BytesPerWord;
+ free = vsm->sum_free_in_chunks_in_use() * BytesPerWord;
+ waste = vsm->sum_waste_in_chunks_in_use() * BytesPerWord;
+
+ MetadataStats class_stats(capacity, used, free, waste);
+ _total_class.add(class_stats);
+
+ if (anonymous) {
+ _total_anon_class.add(class_stats);
+ }
+
+ _out->print(" Class data ");
+ class_stats.print_on(_out, _scale);
+ }
+}
+
+void PrintCLDMetaspaceInfoClosure::print_summary() const {
+ const char* unit = scale_unit(_scale);
+ _out->cr();
+ _out->print_cr("Summary:");
+
+ MetadataStats total;
+ total.add(_total_metadata);
+ total.add(_total_class);
+
+ _out->print(" Total class loaders=" SIZE_FORMAT_W(6) " ", _total_count);
+ total.print_on(_out, _scale);
+
+ _out->print(" Metadata ");
+ _total_metadata.print_on(_out, _scale);
+
+ if (Metaspace::using_class_space()) {
+ _out->print(" Class data ");
+ _total_class.print_on(_out, _scale);
+ }
+ _out->cr();
+
+ MetadataStats total_anon;
+ total_anon.add(_total_anon_metadata);
+ total_anon.add(_total_anon_class);
+
+ _out->print("For anonymous classes=" SIZE_FORMAT_W(6) " ", _total_anon_count);
+ total_anon.print_on(_out, _scale);
+
+ _out->print(" Metadata ");
+ _total_anon_metadata.print_on(_out, _scale);
+
+ if (Metaspace::using_class_space()) {
+ _out->print(" Class data ");
+ _total_anon_class.print_on(_out, _scale);
+ }
+}
+
+void MetaspaceAux::print_metadata_for_nmt(outputStream* out, size_t scale) {
+ const char* unit = scale_unit(scale);
+ out->print_cr("Metaspaces:");
+ out->print_cr(" Metadata space: reserved=" SIZE_FORMAT_W(10) "%s committed=" SIZE_FORMAT_W(10) "%s",
+ reserved_bytes(Metaspace::NonClassType) / scale, unit,
+ committed_bytes(Metaspace::NonClassType) / scale, unit);
+ if (Metaspace::using_class_space()) {
+ out->print_cr(" Class space: reserved=" SIZE_FORMAT_W(10) "%s committed=" SIZE_FORMAT_W(10) "%s",
+ reserved_bytes(Metaspace::ClassType) / scale, unit,
+ committed_bytes(Metaspace::ClassType) / scale, unit);
+ }
+
+ out->cr();
+ ChunkManager::print_all_chunkmanagers(out, scale);
+
+ out->cr();
+ out->print_cr("Per-classloader metadata:");
+ out->cr();
+
+ PrintCLDMetaspaceInfoClosure cl(out, scale);
+ ClassLoaderDataGraph::cld_do(&cl);
+}
+
+
// Dump global metaspace things from the end of ClassLoaderDataGraph
void MetaspaceAux::dump(outputStream* out) {
out->print_cr("All Metaspace:");
@@ -2989,6 +3312,31 @@
print_waste(out);
}
+// Prints an ASCII representation of the given space.
+void MetaspaceAux::print_metaspace_map(outputStream* out, Metaspace::MetadataType mdtype) {
+ MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
+ const bool for_class = mdtype == Metaspace::ClassType ? true : false;
+ VirtualSpaceList* const vsl = for_class ? Metaspace::class_space_list() : Metaspace::space_list();
+ if (vsl != NULL) {
+ if (for_class) {
+ if (!Metaspace::using_class_space()) {
+ out->print_cr("No Class Space.");
+ return;
+ }
+ out->print_raw("---- Metaspace Map (Class Space) ----");
+ } else {
+ out->print_raw("---- Metaspace Map (Non-Class Space) ----");
+ }
+ // Print legend:
+ out->cr();
+ out->print_cr("Chunk Types (uppercase chunks are in use): x-specialized, s-small, m-medium, h-humongous.");
+ out->cr();
+ VirtualSpaceList* const vsl = for_class ? Metaspace::class_space_list() : Metaspace::space_list();
+ vsl->print_map(out);
+ out->cr();
+ }
+}
+
void MetaspaceAux::verify_free_chunks() {
Metaspace::chunk_manager_metadata()->verify();
if (Metaspace::using_class_space()) {
@@ -3627,6 +3975,7 @@
}
LogStream ls(log.info());
MetaspaceAux::dump(&ls);
+ MetaspaceAux::print_metaspace_map(&ls, mdtype);
ChunkManager::print_all_chunkmanagers(&ls);
}
--- a/src/hotspot/share/memory/metaspace.hpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/memory/metaspace.hpp Wed Nov 08 16:03:35 2017 -0500
@@ -63,6 +63,7 @@
class MetaWord;
class Mutex;
class outputStream;
+class PrintCLDMetaspaceInfoClosure;
class SpaceManager;
class VirtualSpaceList;
@@ -87,6 +88,7 @@
friend class MetaspaceAux;
friend class MetaspaceShared;
friend class CollectorPolicy;
+ friend class PrintCLDMetaspaceInfoClosure;
public:
enum MetadataType {
@@ -347,6 +349,8 @@
return min_chunk_size_words() * BytesPerWord;
}
+ static void print_metadata_for_nmt(outputStream* out, size_t scale = K);
+
static bool has_chunk_free_list(Metaspace::MetadataType mdtype);
static MetaspaceChunkFreeListSummary chunk_free_list_summary(Metaspace::MetadataType mdtype);
@@ -357,6 +361,10 @@
static void print_class_waste(outputStream* out);
static void print_waste(outputStream* out);
+
+ // Prints an ASCII representation of the given space.
+ static void print_metaspace_map(outputStream* out, Metaspace::MetadataType mdtype);
+
static void dump(outputStream* out);
static void verify_free_chunks();
// Checks that the values returned by allocated_capacity_bytes() and
--- a/src/hotspot/share/oops/constantPool.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/oops/constantPool.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -305,14 +305,9 @@
constantPoolHandle cp(THREAD, this);
for (int index = 1; index < length(); index++) { // Index 0 is unused
- if (tag_at(index).is_string()) {
- Symbol* sym = cp->unresolved_string_at(index);
- // Look up only. Only resolve references to already interned strings.
- oop str = StringTable::lookup(sym);
- if (str != NULL) {
- int cache_index = cp->cp_to_object_index(index);
- cp->string_at_put(index, cache_index, str);
- }
+ if (tag_at(index).is_string() && !cp->is_pseudo_string_at(index)) {
+ int cache_index = cp->cp_to_object_index(index);
+ string_at_impl(cp, index, cache_index, CHECK);
}
}
}
--- a/src/hotspot/share/oops/method.hpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/oops/method.hpp Wed Nov 08 16:03:35 2017 -0500
@@ -271,7 +271,7 @@
int highest_osr_comp_level() const;
void set_highest_osr_comp_level(int level);
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
// Count of times method was exited via exception while interpreting
void interpreter_throwout_increment(TRAPS) {
MethodCounters* mcs = get_method_counters(CHECK);
@@ -426,7 +426,7 @@
return (mcs == NULL) ? 0 : mcs->interpreter_invocation_count();
}
}
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
int increment_interpreter_invocation_count(TRAPS) {
if (TieredCompilation) ShouldNotReachHere();
MethodCounters* mcs = get_method_counters(CHECK_0);
--- a/src/hotspot/share/oops/methodCounters.hpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/oops/methodCounters.hpp Wed Nov 08 16:03:35 2017 -0500
@@ -40,7 +40,7 @@
#if INCLUDE_AOT
Method* _method; // Back link to Method
#endif
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
int _interpreter_invocation_count; // Count of times invoked (reused as prev_event_count in tiered)
u2 _interpreter_throwout_count; // Count of times method was exited via exception while interpreting
#endif
@@ -130,7 +130,7 @@
MetaspaceObj::Type type() const { return MethodCountersType; }
void clear_counters();
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
int interpreter_invocation_count() {
return _interpreter_invocation_count;
@@ -154,7 +154,7 @@
_interpreter_throwout_count = count;
}
-#else // defined(COMPILER2) || INCLUDE_JVMCI
+#else // COMPILER2_OR_JVMCI
int interpreter_invocation_count() {
return 0;
@@ -170,7 +170,7 @@
assert(count == 0, "count must be 0");
}
-#endif // defined(COMPILER2) || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
#if INCLUDE_JVMTI
u2 number_of_breakpoints() const { return _number_of_breakpoints; }
@@ -213,7 +213,7 @@
return byte_offset_of(MethodCounters, _nmethod_age);
}
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
static ByteSize interpreter_invocation_counter_offset() {
return byte_offset_of(MethodCounters, _interpreter_invocation_count);
@@ -223,14 +223,14 @@
return offset_of(MethodCounters, _interpreter_invocation_count);
}
-#else // defined(COMPILER2) || INCLUDE_JVMCI
+#else // COMPILER2_OR_JVMCI
static ByteSize interpreter_invocation_counter_offset() {
ShouldNotReachHere();
return in_ByteSize(0);
}
-#endif // defined(COMPILER2) || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
static ByteSize invocation_counter_offset() {
return byte_offset_of(MethodCounters, _invocation_counter);
--- a/src/hotspot/share/prims/jni.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/prims/jni.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -3949,7 +3949,7 @@
// JVMCI is initialized on a CompilerThread
if (BootstrapJVMCI) {
JavaThread* THREAD = thread;
- JVMCICompiler* compiler = JVMCICompiler::instance(CATCH);
+ JVMCICompiler* compiler = JVMCICompiler::instance(true, CATCH);
compiler->bootstrap(THREAD);
if (HAS_PENDING_EXCEPTION) {
HandleMark hm;
--- a/src/hotspot/share/prims/whitebox.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/prims/whitebox.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -1715,6 +1715,10 @@
}
WB_END
+WB_ENTRY(jboolean, WB_AreOpenArchiveHeapObjectsMapped(JNIEnv* env))
+ return MetaspaceShared::open_archive_heap_region_mapped();
+WB_END
+
WB_ENTRY(jboolean, WB_IsCDSIncludedInVmBuild(JNIEnv* env))
#if INCLUDE_CDS
return true;
@@ -2031,6 +2035,7 @@
{CC"isSharedClass", CC"(Ljava/lang/Class;)Z", (void*)&WB_IsSharedClass },
{CC"areSharedStringsIgnored", CC"()Z", (void*)&WB_AreSharedStringsIgnored },
{CC"getResolvedReferences", CC"(Ljava/lang/Class;)Ljava/lang/Object;", (void*)&WB_GetResolvedReferences},
+ {CC"areOpenArchiveHeapObjectsMapped", CC"()Z", (void*)&WB_AreOpenArchiveHeapObjectsMapped},
{CC"isCDSIncludedInVmBuild", CC"()Z", (void*)&WB_IsCDSIncludedInVmBuild },
{CC"clearInlineCaches0", CC"(Z)V", (void*)&WB_ClearInlineCaches },
{CC"addCompilerDirective", CC"(Ljava/lang/String;)I",
--- a/src/hotspot/share/runtime/arguments.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/arguments.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -396,6 +396,10 @@
{ "MinSleepInterval", JDK_Version::jdk(9), JDK_Version::jdk(10), JDK_Version::jdk(11) },
{ "PermSize", JDK_Version::undefined(), JDK_Version::jdk(8), JDK_Version::undefined() },
{ "MaxPermSize", JDK_Version::undefined(), JDK_Version::jdk(8), JDK_Version::undefined() },
+ { "SharedReadWriteSize", JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
+ { "SharedReadOnlySize", JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
+ { "SharedMiscDataSize", JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
+ { "SharedMiscCodeSize", JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
#ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS
{ "dep > obs", JDK_Version::jdk(9), JDK_Version::jdk(8), JDK_Version::undefined() },
@@ -1860,7 +1864,7 @@
#endif
select_gc();
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
// Shared spaces work fine with other GCs but causes bytecode rewriting
// to be disabled, which hurts interpreter performance and decreases
// server performance. When -server is specified, keep the default off
@@ -2089,9 +2093,10 @@
// respecting the maximum and minimum sizes of the heap.
if (FLAG_IS_DEFAULT(MaxHeapSize)) {
julong reasonable_max = (julong)((phys_mem * MaxRAMPercentage) / 100);
- if (phys_mem <= (julong)((MaxHeapSize * MinRAMPercentage) / 100)) {
+ const julong reasonable_min = (julong)((phys_mem * MinRAMPercentage) / 100);
+ if (reasonable_min < MaxHeapSize) {
// Small physical memory, so use a minimum fraction of it for the heap
- reasonable_max = (julong)((phys_mem * MinRAMPercentage) / 100);
+ reasonable_max = reasonable_min;
} else {
// Not-small physical memory, so require a heap at least
// as large as MaxHeapSize
--- a/src/hotspot/share/runtime/deoptimization.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/deoptimization.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -192,7 +192,7 @@
bool realloc_failures = false;
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
// Reallocate the non-escaping objects and restore their fields. Then
// relock objects if synchronization on them was eliminated.
#ifndef INCLUDE_JVMCI
@@ -282,7 +282,7 @@
}
}
#endif // INCLUDE_JVMCI
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
ScopeDesc* trap_scope = chunk->at(0)->scope();
Handle exceptionObject;
@@ -303,7 +303,7 @@
NoSafepointVerifier no_safepoint;
vframeArray* array = create_vframeArray(thread, deoptee, &map, chunk, realloc_failures);
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
if (realloc_failures) {
pop_frames_failed_reallocs(thread, array);
}
@@ -792,7 +792,7 @@
Deoptimization::DeoptAction Deoptimization::_unloaded_action
= Deoptimization::Action_reinterpret;
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS) {
Handle pending_exception(THREAD, thread->pending_exception());
const char* exception_file = thread->exception_file();
@@ -1151,7 +1151,7 @@
}
}
#endif
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures) {
Events::log(thread, "DEOPT PACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT, p2i(fr.pc()), p2i(fr.sp()));
@@ -1211,7 +1211,7 @@
return array;
}
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
void Deoptimization::pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array) {
// Reallocation of some scalar replaced objects failed. Record
// that we need to pop all the interpreter frames for the
@@ -1443,7 +1443,7 @@
return mdo;
}
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
void Deoptimization::load_class_by_index(const constantPoolHandle& constant_pool, int index, TRAPS) {
// in case of an unresolved klass entry, load the class.
if (constant_pool->tag_at(index).is_unresolved_klass()) {
@@ -2350,7 +2350,7 @@
if (xtty != NULL) xtty->tail("statistics");
}
}
-#else // COMPILER2 || INCLUDE_JVMCI
+#else // COMPILER2_OR_JVMCI
// Stubs for C1 only system.
@@ -2386,4 +2386,4 @@
return buf;
}
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
--- a/src/hotspot/share/runtime/deoptimization.hpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/deoptimization.hpp Wed Nov 08 16:03:35 2017 -0500
@@ -151,7 +151,7 @@
// executing in a particular CodeBlob if UseBiasedLocking is enabled
static void revoke_biases_of_monitors(CodeBlob* cb);
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
JVMCI_ONLY(public:)
// Support for restoring non-escaping objects
@@ -162,7 +162,7 @@
static void relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread, bool realloc_failures);
static void pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array);
NOT_PRODUCT(static void print_objects(GrowableArray<ScopeValue*>* objects, bool realloc_failures);)
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
public:
static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures);
--- a/src/hotspot/share/runtime/frame.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/frame.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -1148,7 +1148,7 @@
// make sure we have the right receiver type
}
}
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
assert(DerivedPointerTable::is_empty(), "must be empty before verify");
#endif
oops_do_internal(&VerifyOopClosure::verify_oop, NULL, (RegisterMap*)map, false);
--- a/src/hotspot/share/runtime/globals.hpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/globals.hpp Wed Nov 08 16:03:35 2017 -0500
@@ -99,11 +99,11 @@
#define CI_COMPILER_COUNT 0
#else
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
#define CI_COMPILER_COUNT 2
#else
#define CI_COMPILER_COUNT 1
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
#endif // no compilers
@@ -3901,18 +3901,6 @@
"If PrintSharedArchiveAndExit is true, also print the shared " \
"dictionary") \
\
- product(size_t, SharedReadWriteSize, 0, \
- "Deprecated") \
- \
- product(size_t, SharedReadOnlySize, 0, \
- "Deprecated") \
- \
- product(size_t, SharedMiscDataSize, 0, \
- "Deprecated") \
- \
- product(size_t, SharedMiscCodeSize, 0, \
- "Deprecated") \
- \
product(size_t, SharedBaseAddress, LP64_ONLY(32*G) \
NOT_LP64(LINUX_ONLY(2*G) NOT_LINUX(0)), \
"Address to allocate shared memory region for class data") \
--- a/src/hotspot/share/runtime/rframe.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/rframe.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -155,7 +155,7 @@
void RFrame::print(const char* kind) {
#ifndef PRODUCT
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
int cnt = top_method()->interpreter_invocation_count();
#else
int cnt = top_method()->invocation_count();
--- a/src/hotspot/share/runtime/sharedRuntime.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -102,13 +102,13 @@
_resolve_static_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_static_call_C), "resolve_static_call");
_resolve_static_call_entry = _resolve_static_call_blob->entry_point();
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
// Vectors are generated only by C2 and JVMCI.
bool support_wide = is_wide_vector(MaxVectorSize);
if (support_wide) {
_polling_page_vectors_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_VECTOR_LOOP);
}
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
_polling_page_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_LOOP);
_polling_page_return_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_RETURN);
--- a/src/hotspot/share/runtime/thread.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/thread.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -3724,7 +3724,7 @@
}
// initialize compiler(s)
-#if defined(COMPILER1) || defined(COMPILER2) || INCLUDE_JVMCI
+#if defined(COMPILER1) || COMPILER2_OR_JVMCI
CompileBroker::compilation_init(CHECK_JNI_ERR);
#endif
--- a/src/hotspot/share/runtime/vm_operations.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/vm_operations.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -230,6 +230,10 @@
JNIHandles::print_on(_out);
}
+void VM_PrintMetadata::doit() {
+ MetaspaceAux::print_metadata_for_nmt(_out, _scale);
+}
+
VM_FindDeadlocks::~VM_FindDeadlocks() {
if (_deadlocks != NULL) {
DeadlockCycle* cycle = _deadlocks;
--- a/src/hotspot/share/runtime/vm_operations.hpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/vm_operations.hpp Wed Nov 08 16:03:35 2017 -0500
@@ -111,6 +111,7 @@
template(ThreadsSuspendJVMTI) \
template(ICBufferFull) \
template(ScavengeMonitors) \
+ template(PrintMetadata) \
class VM_Operation: public CHeapObj<mtInternal> {
public:
@@ -374,6 +375,17 @@
void doit();
};
+class VM_PrintMetadata : public VM_Operation {
+ private:
+ outputStream* _out;
+ size_t _scale;
+ public:
+ VM_PrintMetadata(outputStream* out, size_t scale) : _out(out), _scale(scale) {};
+
+ VMOp_Type type() const { return VMOp_PrintMetadata; }
+ void doit();
+};
+
class DeadlockCycle;
class VM_FindDeadlocks: public VM_Operation {
private:
--- a/src/hotspot/share/services/nmtDCmd.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/services/nmtDCmd.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, 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
@@ -24,6 +24,8 @@
#include "precompiled.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/mutexLocker.hpp"
+#include "runtime/vmThread.hpp"
+#include "runtime/vm_operations.hpp"
#include "services/nmtDCmd.hpp"
#include "services/memReporter.hpp"
#include "services/memTracker.hpp"
@@ -38,6 +40,8 @@
_detail("detail", "request runtime to report memory allocation >= "
"1K by each callsite.",
"BOOLEAN", false, "false"),
+ _metadata("metadata", "request runtime to report metadata information",
+ "BOOLEAN", false, "false"),
_baseline("baseline", "request runtime to baseline current memory usage, " \
"so it can be compared against in later time.",
"BOOLEAN", false, "false"),
@@ -57,6 +61,7 @@
"STRING", false, "KB") {
_dcmdparser.add_dcmd_option(&_summary);
_dcmdparser.add_dcmd_option(&_detail);
+ _dcmdparser.add_dcmd_option(&_metadata);
_dcmdparser.add_dcmd_option(&_baseline);
_dcmdparser.add_dcmd_option(&_summary_diff);
_dcmdparser.add_dcmd_option(&_detail_diff);
@@ -92,6 +97,7 @@
int nopt = 0;
if (_summary.is_set() && _summary.value()) { ++nopt; }
if (_detail.is_set() && _detail.value()) { ++nopt; }
+ if (_metadata.is_set() && _metadata.value()) { ++nopt; }
if (_baseline.is_set() && _baseline.value()) { ++nopt; }
if (_summary_diff.is_set() && _summary_diff.value()) { ++nopt; }
if (_detail_diff.is_set() && _detail_diff.value()) { ++nopt; }
@@ -100,7 +106,7 @@
if (nopt > 1) {
output()->print_cr("At most one of the following option can be specified: " \
- "summary, detail, baseline, summary.diff, detail.diff, shutdown");
+ "summary, detail, metadata, baseline, summary.diff, detail.diff, shutdown");
return;
} else if (nopt == 0) {
if (_summary.is_set()) {
@@ -118,9 +124,13 @@
report(true, scale_unit);
} else if (_detail.value()) {
if (!check_detail_tracking_level(output())) {
- return;
- }
+ return;
+ }
report(false, scale_unit);
+ } else if (_metadata.value()) {
+ size_t scale = get_scale(_scale.value());
+ VM_PrintMetadata op(output(), scale);
+ VMThread::execute(&op);
} else if (_baseline.value()) {
MemBaseline& baseline = MemTracker::get_baseline();
if (!baseline.baseline(MemTracker::tracking_level() != NMT_detail)) {
--- a/src/hotspot/share/services/nmtDCmd.hpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/services/nmtDCmd.hpp Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2014, 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
@@ -39,6 +39,7 @@
protected:
DCmdArgument<bool> _summary;
DCmdArgument<bool> _detail;
+ DCmdArgument<bool> _metadata;
DCmdArgument<bool> _baseline;
DCmdArgument<bool> _summary_diff;
DCmdArgument<bool> _detail_diff;
--- a/src/java.base/share/classes/java/io/FilePermission.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/io/FilePermission.java Wed Nov 08 16:03:35 2017 -0500
@@ -698,7 +698,7 @@
if (p2.equals(EMPTY_PATH)) {
return 0;
} else if (p2.getName(0).equals(DOTDOT_PATH)) {
- // "." contains p2 iif p2 has no "..". Since a
+ // "." contains p2 iff p2 has no "..". Since
// a normalized path can only have 0 or more
// ".." at the beginning. We only need to look
// at the head.
@@ -711,7 +711,7 @@
} else if (p2.equals(EMPTY_PATH)) {
int c1 = p1.getNameCount();
if (!p1.getName(c1 - 1).equals(DOTDOT_PATH)) {
- // "." is inside p1 iif p1 is 1 or more "..".
+ // "." is inside p1 iff p1 is 1 or more "..".
// For the same reason above, we only need to
// look at the tail.
return -1;
--- a/src/java.base/share/classes/java/lang/Module.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/lang/Module.java Wed Nov 08 16:03:35 2017 -0500
@@ -57,8 +57,6 @@
import jdk.internal.loader.BuiltinClassLoader;
import jdk.internal.loader.BootLoader;
import jdk.internal.loader.ClassLoaders;
-import jdk.internal.misc.JavaLangAccess;
-import jdk.internal.misc.SharedSecrets;
import jdk.internal.module.IllegalAccessLogger;
import jdk.internal.module.ModuleLoaderMap;
import jdk.internal.module.ServicesCatalog;
@@ -68,6 +66,7 @@
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
@@ -1432,7 +1431,7 @@
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
+ ClassWriter.COMPUTE_FRAMES);
- ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, cw) {
+ ClassVisitor cv = new ClassVisitor(Opcodes.ASM6, cw) {
@Override
public void visit(int version,
int access,
@@ -1458,6 +1457,11 @@
public void visitAttribute(Attribute attr) {
// drop non-annotation attributes
}
+ @Override
+ public ModuleVisitor visitModule(String name, int flags, String version) {
+ // drop Module attribute
+ return null;
+ }
};
ClassReader cr = new ClassReader(in);
--- a/src/java.base/share/classes/java/lang/System.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/lang/System.java Wed Nov 08 16:03:35 2017 -0500
@@ -1937,7 +1937,7 @@
// initialization. So make sure the "props" is available at the
// very beginning of the initialization and all system properties to
// be put into it directly.
- props = new Properties();
+ props = new Properties(84);
initProperties(props); // initialized by the VM
// There are certain system configurations that may be controlled by
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Wed Nov 08 16:03:35 2017 -0500
@@ -765,7 +765,7 @@
* In every other case, all conversions are applied <em>pairwise</em>,
* which means that each argument or return value is converted to
* exactly one argument or return value (or no return value).
- * The applied conversions are defined by consulting the
+ * The applied conversions are defined by consulting
* the corresponding component types of the old and new
* method handle types.
* <p>
--- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java Wed Nov 08 16:03:35 2017 -0500
@@ -194,7 +194,7 @@
static {
// In case we need to double-back onto the StringConcatFactory during this
// static initialization, make sure we have the reasonable defaults to complete
- // the static initialization properly. After that, actual users would use the
+ // the static initialization properly. After that, actual users would use
// the proper values we have read from the properties.
STRATEGY = DEFAULT_STRATEGY;
// CACHE_ENABLE = false; // implied
--- a/src/java.base/share/classes/java/lang/invoke/VarHandle.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandle.java Wed Nov 08 16:03:35 2017 -0500
@@ -205,7 +205,7 @@
* and {@code double} on 32-bit platforms.
*
* <p>Access modes will override any memory ordering effects specified at
- * the declaration site of a variable. For example, a VarHandle accessing a
+ * the declaration site of a variable. For example, a VarHandle accessing
* a field using the {@code get} access mode will access the field as
* specified <em>by its access mode</em> even if that field is declared
* {@code volatile}. When mixed access is performed extreme care should be
@@ -423,7 +423,7 @@
* {@link java.lang.invoke.MethodHandles#varHandleInvoker}.
*
* <h1>Interoperation between VarHandles and Java generics</h1>
- * A VarHandle can be obtained for a variable, such as a a field, which is
+ * A VarHandle can be obtained for a variable, such as a field, which is
* declared with Java generic types. As with the Core Reflection API, the
* VarHandle's variable type will be constructed from the erasure of the
* source-level type. When a VarHandle access mode method is invoked, the
--- a/src/java.base/share/classes/java/net/DatagramSocket.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/net/DatagramSocket.java Wed Nov 08 16:03:35 2017 -0500
@@ -988,7 +988,7 @@
/**
* Sets the SO_RCVBUF option to the specified value for this
- * {@code DatagramSocket}. The SO_RCVBUF option is used by the
+ * {@code DatagramSocket}. The SO_RCVBUF option is used by
* the network implementation as a hint to size the underlying
* network I/O buffers. The SO_RCVBUF setting may also be used
* by the network implementation to determine the maximum size
--- a/src/java.base/share/classes/java/net/Inet4Address.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/net/Inet4Address.java Wed Nov 08 16:03:35 2017 -0500
@@ -143,7 +143,7 @@
/**
* Prior to 1.4 an InetAddress was created with a family
* based on the platform AF_INET value (usually 2).
- * For compatibility reasons we must therefore write the
+ * For compatibility reasons we must therefore write
* the InetAddress with this family.
*/
inet.holder().family = 2;
--- a/src/java.base/share/classes/java/net/SocketImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/net/SocketImpl.java Wed Nov 08 16:03:35 2017 -0500
@@ -333,7 +333,7 @@
* latency, and low latency above short connection time, then it could
* invoke this method with the values {@code (0, 1, 2)}.
*
- * By default, this method does nothing, unless it is overridden in a
+ * By default, this method does nothing, unless it is overridden in
* a sub-class.
*
* @param connectionTime
--- a/src/java.base/share/classes/java/net/SocksSocketImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/net/SocksSocketImpl.java Wed Nov 08 16:03:35 2017 -0500
@@ -657,7 +657,7 @@
/**
* Sends the Bind request to the SOCKS proxy. In the SOCKS protocol, bind
- * means "accept incoming connection from", so the SocketAddress is the
+ * means "accept incoming connection from", so the SocketAddress is
* the one of the host we do accept connection from.
*
* @param saddr the Socket address of the remote host.
--- a/src/java.base/share/classes/java/net/URLConnection.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/net/URLConnection.java Wed Nov 08 16:03:35 2017 -0500
@@ -785,7 +785,7 @@
* required to make the connection. By default, this method
* returns {@code java.security.AllPermission}. Subclasses
* should override this method and return the permission
- * that best represents the permission required to make a
+ * that best represents the permission required to make
* a connection to the URL. For example, a {@code URLConnection}
* representing a {@code file:} URL would return a
* {@code java.io.FilePermission} object.
--- a/src/java.base/share/classes/java/nio/channels/AsynchronousFileChannel.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/nio/channels/AsynchronousFileChannel.java Wed Nov 08 16:03:35 2017 -0500
@@ -165,7 +165,7 @@
* <tr>
* <th scope="row" > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </th>
* <td> When this option is present then the implementation makes a
- * <em>best effort</em> attempt to delete the file when closed by the
+ * <em>best effort</em> attempt to delete the file when closed by
* the {@link #close close} method. If the {@code close} method is not
* invoked then a <em>best effort</em> attempt is made to delete the file
* when the Java virtual machine terminates. </td>
--- a/src/java.base/share/classes/java/nio/channels/Channels.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/nio/channels/Channels.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -368,6 +368,10 @@
@Override
public int read(ByteBuffer dst) throws IOException {
+ if (!isOpen()) {
+ throw new ClosedChannelException();
+ }
+
int len = dst.remaining();
int totalRead = 0;
int bytesRead = 0;
@@ -442,6 +446,10 @@
@Override
public int write(ByteBuffer src) throws IOException {
+ if (!isOpen()) {
+ throw new ClosedChannelException();
+ }
+
int len = src.remaining();
int totalWritten = 0;
synchronized (writeLock) {
--- a/src/java.base/share/classes/java/nio/channels/FileChannel.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/nio/channels/FileChannel.java Wed Nov 08 16:03:35 2017 -0500
@@ -216,7 +216,7 @@
* <tr>
* <th scope="row" > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </th>
* <td> When this option is present then the implementation makes a
- * <em>best effort</em> attempt to delete the file when closed by the
+ * <em>best effort</em> attempt to delete the file when closed by
* the {@link #close close} method. If the {@code close} method is not
* invoked then a <em>best effort</em> attempt is made to delete the file
* when the Java virtual machine terminates. </td>
--- a/src/java.base/share/classes/java/nio/file/Files.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/nio/file/Files.java Wed Nov 08 16:03:35 2017 -0500
@@ -2401,7 +2401,7 @@
*
* <p> Note that the result of this method is immediately outdated. If this
* method indicates the file exists then there is no guarantee that a
- * subsequence access will succeed. Care should be taken when using this
+ * subsequent access will succeed. Care should be taken when using this
* method in security sensitive applications.
*
* @param path
@@ -2458,7 +2458,7 @@
* or not then both methods return {@code false}. As with the {@code exists}
* method, the result of this method is immediately outdated. If this
* method indicates the file does exist then there is no guarantee that a
- * subsequence attempt to create the file will succeed. Care should be taken
+ * subsequent attempt to create the file will succeed. Care should be taken
* when using this method in security sensitive applications.
*
* @param path
@@ -3301,7 +3301,7 @@
}
/**
- * Writes bytes to a file. The {@code options} parameter specifies how the
+ * Writes bytes to a file. The {@code options} parameter specifies how
* the file is created or opened. If no options are present then this method
* works as if the {@link StandardOpenOption#CREATE CREATE}, {@link
* StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
--- a/src/java.base/share/classes/java/security/KeyPairGenerator.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/security/KeyPairGenerator.java Wed Nov 08 16:03:35 2017 -0500
@@ -84,7 +84,7 @@
* exists (e.g., so-called <i>community parameters</i> in DSA), there are two
* {@link #initialize(java.security.spec.AlgorithmParameterSpec)
* initialize} methods that have an {@code AlgorithmParameterSpec}
- * argument. One also has a {@code SecureRandom} argument, while the
+ * argument. One also has a {@code SecureRandom} argument, while
* the other uses the {@code SecureRandom}
* implementation of the highest-priority installed provider as the source
* of randomness. (If none of the installed providers supply an implementation
--- a/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java Wed Nov 08 16:03:35 2017 -0500
@@ -4775,7 +4775,7 @@
//-----------------------------------------------------------------------
/**
* Prints or parses a localized pattern from a localized field.
- * The specific formatter and parameters is not selected until the
+ * The specific formatter and parameters is not selected until
* the field is to be printed or parsed.
* The locale is needed to select the proper WeekFields from which
* the field for day-of-week, week-of-month, or week-of-year is selected.
--- a/src/java.base/share/classes/java/time/temporal/WeekFields.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/time/temporal/WeekFields.java Wed Nov 08 16:03:35 2017 -0500
@@ -311,7 +311,7 @@
* the new month or year.
* <p>
* WeekFields instances are singletons; for each unique combination
- * of {@code firstDayOfWeek} and {@code minimalDaysInFirstWeek} the
+ * of {@code firstDayOfWeek} and {@code minimalDaysInFirstWeek}
* the same instance will be returned.
*
* @param firstDayOfWeek the first day of the week, not null
--- a/src/java.base/share/classes/java/util/Base64.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/util/Base64.java Wed Nov 08 16:03:35 2017 -0500
@@ -56,7 +56,7 @@
* base64 alphabet.</p></li>
*
* <li><a id="mime"><b>MIME</b></a>
- * <p> Uses the "The Base64 Alphabet" as specified in Table 1 of
+ * <p> Uses "The Base64 Alphabet" as specified in Table 1 of
* RFC 2045 for encoding and decoding operation. The encoded output
* must be represented in lines of no more than 76 characters each
* and uses a carriage return {@code '\r'} followed immediately by
--- a/src/java.base/share/classes/java/util/DoubleSummaryStatistics.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/util/DoubleSummaryStatistics.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, 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
@@ -26,6 +26,7 @@
import java.util.function.DoubleConsumer;
import java.util.stream.Collector;
+import java.util.stream.DoubleStream;
/**
* A state object for collecting statistics such as count, min, max, sum, and
@@ -69,13 +70,66 @@
private double max = Double.NEGATIVE_INFINITY;
/**
- * Construct an empty instance with zero count, zero sum,
+ * Constructs an empty instance with zero count, zero sum,
* {@code Double.POSITIVE_INFINITY} min, {@code Double.NEGATIVE_INFINITY}
* max and zero average.
*/
public DoubleSummaryStatistics() { }
/**
+ * Constructs a non-empty instance with the specified {@code count},
+ * {@code min}, {@code max}, and {@code sum}.
+ *
+ * <p>If {@code count} is zero then the remaining arguments are ignored and
+ * an empty instance is constructed.
+ *
+ * <p>If the arguments are inconsistent then an {@code IllegalArgumentException}
+ * is thrown. The necessary consistent argument conditions are:
+ * <ul>
+ * <li>{@code count >= 0}</li>
+ * <li>{@code (min <= max && !isNaN(sum)) || (isNaN(min) && isNaN(max) && isNaN(sum))}</li>
+ * </ul>
+ * @apiNote
+ * The enforcement of argument correctness means that the retrieved set of
+ * recorded values obtained from a {@code DoubleSummaryStatistics} source
+ * instance may not be a legal set of arguments for this constructor due to
+ * arithmetic overflow of the source's recorded count of values.
+ * The consistent argument conditions are not sufficient to prevent the
+ * creation of an internally inconsistent instance. An example of such a
+ * state would be an instance with: {@code count} = 2, {@code min} = 1,
+ * {@code max} = 2, and {@code sum} = 0.
+ *
+ * @param count the count of values
+ * @param min the minimum value
+ * @param max the maximum value
+ * @param sum the sum of all values
+ * @throws IllegalArgumentException if the arguments are inconsistent
+ * @since 10
+ */
+ public DoubleSummaryStatistics(long count, double min, double max, double sum)
+ throws IllegalArgumentException {
+ if (count < 0L) {
+ throw new IllegalArgumentException("Negative count value");
+ } else if (count > 0L) {
+ if (min > max)
+ throw new IllegalArgumentException("Minimum greater than maximum");
+
+ // All NaN or non NaN
+ var ncount = DoubleStream.of(min, max, sum).filter(Double::isNaN).count();
+ if (ncount > 0 && ncount < 3)
+ throw new IllegalArgumentException("Some, not all, of the minimum, maximum, or sum is NaN");
+
+ this.count = count;
+ this.sum = sum;
+ this.simpleSum = sum;
+ this.sumCompensation = 0.0d;
+ this.min = min;
+ this.max = max;
+ }
+ // Use default field values if count == 0
+ }
+
+ /**
* Records another value into the summary information.
*
* @param value the input value
--- a/src/java.base/share/classes/java/util/EventObject.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/util/EventObject.java Wed Nov 08 16:03:35 2017 -0500
@@ -43,13 +43,13 @@
/**
* The object on which the Event initially occurred.
*/
- protected transient Object source;
+ protected transient Object source;
/**
* Constructs a prototypical Event.
*
- * @param source The object on which the Event initially occurred.
- * @exception IllegalArgumentException if source is null.
+ * @param source the object on which the Event initially occurred
+ * @throws IllegalArgumentException if source is null
*/
public EventObject(Object source) {
if (source == null)
@@ -61,7 +61,7 @@
/**
* The object on which the Event initially occurred.
*
- * @return The object on which the Event initially occurred.
+ * @return the object on which the Event initially occurred
*/
public Object getSource() {
return source;
@@ -70,7 +70,7 @@
/**
* Returns a String representation of this EventObject.
*
- * @return A a String representation of this EventObject.
+ * @return a String representation of this EventObject
*/
public String toString() {
return getClass().getName() + "[source=" + source + "]";
--- a/src/java.base/share/classes/java/util/FormattableFlags.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/util/FormattableFlags.java Wed Nov 08 16:03:35 2017 -0500
@@ -26,7 +26,7 @@
package java.util;
/**
- * FomattableFlags are passed to the {@link Formattable#formatTo
+ * FormattableFlags are passed to the {@link Formattable#formatTo
* Formattable.formatTo()} method and modify the output format for {@linkplain
* Formattable Formattables}. Implementations of {@link Formattable} are
* responsible for interpreting and validating any flags.
--- a/src/java.base/share/classes/java/util/IntSummaryStatistics.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/util/IntSummaryStatistics.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, 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
@@ -69,13 +69,58 @@
private int max = Integer.MIN_VALUE;
/**
- * Construct an empty instance with zero count, zero sum,
+ * Constructs an empty instance with zero count, zero sum,
* {@code Integer.MAX_VALUE} min, {@code Integer.MIN_VALUE} max and zero
* average.
*/
public IntSummaryStatistics() { }
/**
+ * Constructs a non-empty instance with the specified {@code count},
+ * {@code min}, {@code max}, and {@code sum}.
+ *
+ * <p>If {@code count} is zero then the remaining arguments are ignored and
+ * an empty instance is constructed.
+ *
+ * <p>If the arguments are inconsistent then an {@code IllegalArgumentException}
+ * is thrown. The necessary consistent argument conditions are:
+ * <ul>
+ * <li>{@code count >= 0}</li>
+ * <li>{@code min <= max}</li>
+ * </ul>
+ * @apiNote
+ * The enforcement of argument correctness means that the retrieved set of
+ * recorded values obtained from a {@code IntSummaryStatistics} source
+ * instance may not be a legal set of arguments for this constructor due to
+ * arithmetic overflow of the source's recorded count of values.
+ * The consistent argument conditions are not sufficient to prevent the
+ * creation of an internally inconsistent instance. An example of such a
+ * state would be an instance with: {@code count} = 2, {@code min} = 1,
+ * {@code max} = 2, and {@code sum} = 0.
+ *
+ * @param count the count of values
+ * @param min the minimum value
+ * @param max the maximum value
+ * @param sum the sum of all values
+ * @throws IllegalArgumentException if the arguments are inconsistent
+ * @since 10
+ */
+ public IntSummaryStatistics(long count, int min, int max, long sum)
+ throws IllegalArgumentException {
+ if (count < 0L) {
+ throw new IllegalArgumentException("Negative count value");
+ } else if (count > 0L) {
+ if (min > max) throw new IllegalArgumentException("Minimum greater than maximum");
+
+ this.count = count;
+ this.sum = sum;
+ this.min = min;
+ this.max = max;
+ }
+ // Use default field values if count == 0
+ }
+
+ /**
* Records a new value into the summary information
*
* @param value the input value
--- a/src/java.base/share/classes/java/util/LongSummaryStatistics.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/util/LongSummaryStatistics.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, 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
@@ -70,13 +70,58 @@
private long max = Long.MIN_VALUE;
/**
- * Construct an empty instance with zero count, zero sum,
+ * Constructs an empty instance with zero count, zero sum,
* {@code Long.MAX_VALUE} min, {@code Long.MIN_VALUE} max and zero
* average.
*/
public LongSummaryStatistics() { }
/**
+ * Constructs a non-empty instance with the specified {@code count},
+ * {@code min}, {@code max}, and {@code sum}.
+ *
+ * <p>If {@code count} is zero then the remaining arguments are ignored and
+ * an empty instance is constructed.
+ *
+ * <p>If the arguments are inconsistent then an {@code IllegalArgumentException}
+ * is thrown. The necessary consistent argument conditions are:
+ * <ul>
+ * <li>{@code count >= 0}</li>
+ * <li>{@code min <= max}</li>
+ * </ul>
+ * @apiNote
+ * The enforcement of argument correctness means that the retrieved set of
+ * recorded values obtained from a {@code LongSummaryStatistics} source
+ * instance may not be a legal set of arguments for this constructor due to
+ * arithmetic overflow of the source's recorded count of values.
+ * The consistent argument conditions are not sufficient to prevent the
+ * creation of an internally inconsistent instance. An example of such a
+ * state would be an instance with: {@code count} = 2, {@code min} = 1,
+ * {@code max} = 2, and {@code sum} = 0.
+ *
+ * @param count the count of values
+ * @param min the minimum value
+ * @param max the maximum value
+ * @param sum the sum of all values
+ * @throws IllegalArgumentException if the arguments are inconsistent
+ * @since 10
+ */
+ public LongSummaryStatistics(long count, long min, long max, long sum)
+ throws IllegalArgumentException {
+ if (count < 0L) {
+ throw new IllegalArgumentException("Negative count value");
+ } else if (count > 0L) {
+ if (min > max) throw new IllegalArgumentException("Minimum greater than maximum");
+
+ this.count = count;
+ this.sum = sum;
+ this.min = min;
+ this.max = max;
+ }
+ // Use default field values if count == 0
+ }
+
+ /**
* Records a new {@code int} value into the summary information.
*
* @param value the input value
--- a/src/java.base/share/classes/java/util/Properties.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/util/Properties.java Wed Nov 08 16:03:35 2017 -0500
@@ -122,6 +122,10 @@
* <p>This class is thread-safe: multiple threads can share a single
* {@code Properties} object without the need for external synchronization.
*
+ * @apiNote
+ * The {@code Properties} class does not inherit the concept of a load factor
+ * from its superclass, {@code Hashtable}.
+ *
* @author Arthur van Hoff
* @author Michael McCloskey
* @author Xueming Shen
@@ -148,25 +152,49 @@
* simple read operations. Writes and bulk operations remain synchronized,
* as in Hashtable.
*/
- private transient ConcurrentHashMap<Object, Object> map =
- new ConcurrentHashMap<>(8);
+ private transient ConcurrentHashMap<Object, Object> map;
/**
* Creates an empty property list with no default values.
+ *
+ * @implNote The initial capacity of a {@code Properties} object created
+ * with this constructor is unspecified.
*/
public Properties() {
- this(null);
+ this(null, 8);
+ }
+
+ /**
+ * Creates an empty property list with no default values, and with an
+ * initial size accommodating the specified number of elements without the
+ * need to dynamically resize.
+ *
+ * @param initialCapacity the {@code Properties} will be sized to
+ * accommodate this many elements
+ * @throws IllegalArgumentException if the initial capacity is less than
+ * zero.
+ */
+ public Properties(int initialCapacity) {
+ this(null, initialCapacity);
}
/**
* Creates an empty property list with the specified defaults.
*
+ * @implNote The initial capacity of a {@code Properties} object created
+ * with this constructor is unspecified.
+ *
* @param defaults the defaults.
*/
public Properties(Properties defaults) {
+ this(defaults, 8);
+ }
+
+ private Properties(Properties defaults, int initialCapacity) {
// use package-private constructor to
// initialize unused fields with dummy values
super((Void) null);
+ map = new ConcurrentHashMap<>(initialCapacity);
this.defaults = defaults;
}
--- a/src/java.base/share/classes/java/util/ResourceBundle.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/util/ResourceBundle.java Wed Nov 08 16:03:35 2017 -0500
@@ -2743,7 +2743,7 @@
* of multiple subtags separated by underscore, generate candidate
* <code>Locale</code>s by omitting the variant subtags one by one, then
* insert them after every occurrence of <code> Locale</code>s with the
- * full variant value in the original list. For example, if the
+ * full variant value in the original list. For example, if
* the variant consists of two subtags <em>V1</em> and <em>V2</em>:
*
* <ul>
--- a/src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java Wed Nov 08 16:03:35 2017 -0500
@@ -238,7 +238,7 @@
// This way we could simply do things like:
// push((logger) -> logger.log(level, msg));
// Unfortunately, if we come to here it means we are in the bootsraping
- // phase where using lambdas is not safe yet - so we have to use a
+ // phase where using lambdas is not safe yet - so we have to use
// a data object instead...
//
static final class LogEvent {
--- a/src/java.base/share/classes/jdk/internal/module/ClassFileAttributes.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,765 +0,0 @@
-/*
- * 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
- * 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.lang.module.ModuleDescriptor;
-import java.lang.module.ModuleDescriptor.Builder;
-import java.lang.module.ModuleDescriptor.Requires;
-import java.lang.module.ModuleDescriptor.Exports;
-import java.lang.module.ModuleDescriptor.Opens;
-import java.lang.module.ModuleDescriptor.Provides;
-import java.lang.module.ModuleDescriptor.Version;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import jdk.internal.misc.JavaLangModuleAccess;
-import jdk.internal.misc.SharedSecrets;
-import jdk.internal.org.objectweb.asm.Attribute;
-import jdk.internal.org.objectweb.asm.ByteVector;
-import jdk.internal.org.objectweb.asm.ClassReader;
-import jdk.internal.org.objectweb.asm.ClassWriter;
-import jdk.internal.org.objectweb.asm.Label;
-import static jdk.internal.module.ClassFileConstants.*;
-
-
-/**
- * Provides ASM implementations of {@code Attribute} to read and write the
- * class file attributes in a module-info class file.
- */
-
-public final class ClassFileAttributes {
-
- private ClassFileAttributes() { }
-
- /**
- * Module_attribute {
- * // See lang-vm.html for details.
- * }
- */
- public static class ModuleAttribute extends Attribute {
- private static final JavaLangModuleAccess JLMA
- = SharedSecrets.getJavaLangModuleAccess();
-
- private ModuleDescriptor descriptor;
- private Version replacementVersion;
-
- public ModuleAttribute(ModuleDescriptor descriptor) {
- super(MODULE);
- this.descriptor = descriptor;
- }
-
- public ModuleAttribute(Version v) {
- super(MODULE);
- this.replacementVersion = v;
- }
-
- public ModuleAttribute() {
- super(MODULE);
- }
-
- @Override
- protected Attribute read(ClassReader cr,
- int off,
- int len,
- char[] buf,
- int codeOff,
- Label[] labels)
- {
- // module_name (CONSTANT_Module_info)
- String mn = cr.readModule(off, buf);
- off += 2;
-
- // module_flags
- int module_flags = cr.readUnsignedShort(off);
- off += 2;
-
- Set<ModuleDescriptor.Modifier> modifiers = new HashSet<>();
- if ((module_flags & ACC_OPEN) != 0)
- modifiers.add(ModuleDescriptor.Modifier.OPEN);
- if ((module_flags & ACC_SYNTHETIC) != 0)
- modifiers.add(ModuleDescriptor.Modifier.SYNTHETIC);
- if ((module_flags & ACC_MANDATED) != 0)
- modifiers.add(ModuleDescriptor.Modifier.MANDATED);
-
- Builder builder = JLMA.newModuleBuilder(mn, false, modifiers);
-
- // module_version
- String module_version = cr.readUTF8(off, buf);
- off += 2;
- if (replacementVersion != null) {
- builder.version(replacementVersion);
- } else if (module_version != null) {
- builder.version(module_version);
- }
-
- // requires_count and requires[requires_count]
- int requires_count = cr.readUnsignedShort(off);
- off += 2;
- for (int i=0; i<requires_count; i++) {
- // CONSTANT_Module_info
- String dn = cr.readModule(off, buf);
- off += 2;
-
- // requires_flags
- int requires_flags = cr.readUnsignedShort(off);
- off += 2;
- Set<Requires.Modifier> mods;
- if (requires_flags == 0) {
- mods = Collections.emptySet();
- } else {
- mods = new HashSet<>();
- if ((requires_flags & ACC_TRANSITIVE) != 0)
- mods.add(Requires.Modifier.TRANSITIVE);
- if ((requires_flags & ACC_STATIC_PHASE) != 0)
- mods.add(Requires.Modifier.STATIC);
- if ((requires_flags & ACC_SYNTHETIC) != 0)
- mods.add(Requires.Modifier.SYNTHETIC);
- if ((requires_flags & ACC_MANDATED) != 0)
- mods.add(Requires.Modifier.MANDATED);
- }
-
- // requires_version
- String requires_version = cr.readUTF8(off, buf);
- off += 2;
- if (requires_version == null) {
- builder.requires(mods, dn);
- } else {
- JLMA.requires(builder, mods, dn, requires_version);
- }
- }
-
- // exports_count and exports[exports_count]
- int exports_count = cr.readUnsignedShort(off);
- off += 2;
- if (exports_count > 0) {
- for (int i=0; i<exports_count; i++) {
- // CONSTANT_Package_info
- String pkg = cr.readPackage(off, buf).replace('/', '.');
- off += 2;
-
- int exports_flags = cr.readUnsignedShort(off);
- off += 2;
- Set<Exports.Modifier> mods;
- if (exports_flags == 0) {
- mods = Collections.emptySet();
- } else {
- mods = new HashSet<>();
- if ((exports_flags & ACC_SYNTHETIC) != 0)
- mods.add(Exports.Modifier.SYNTHETIC);
- if ((exports_flags & ACC_MANDATED) != 0)
- mods.add(Exports.Modifier.MANDATED);
- }
-
- int exports_to_count = cr.readUnsignedShort(off);
- off += 2;
- if (exports_to_count > 0) {
- Set<String> targets = new HashSet<>();
- for (int j=0; j<exports_to_count; j++) {
- String t = cr.readModule(off, buf);
- off += 2;
- targets.add(t);
- }
- builder.exports(mods, pkg, targets);
- } else {
- builder.exports(mods, pkg);
- }
- }
- }
-
- // opens_count and opens[opens_count]
- int open_count = cr.readUnsignedShort(off);
- off += 2;
- if (open_count > 0) {
- for (int i=0; i<open_count; i++) {
- // CONSTANT_Package_info
- String pkg = cr.readPackage(off, buf).replace('/', '.');
- off += 2;
-
- int opens_flags = cr.readUnsignedShort(off);
- off += 2;
- Set<Opens.Modifier> mods;
- if (opens_flags == 0) {
- mods = Collections.emptySet();
- } else {
- mods = new HashSet<>();
- if ((opens_flags & ACC_SYNTHETIC) != 0)
- mods.add(Opens.Modifier.SYNTHETIC);
- if ((opens_flags & ACC_MANDATED) != 0)
- mods.add(Opens.Modifier.MANDATED);
- }
-
- int opens_to_count = cr.readUnsignedShort(off);
- off += 2;
- if (opens_to_count > 0) {
- Set<String> targets = new HashSet<>();
- for (int j=0; j<opens_to_count; j++) {
- String t = cr.readModule(off, buf);
- off += 2;
- targets.add(t);
- }
- builder.opens(mods, pkg, targets);
- } else {
- builder.opens(mods, pkg);
- }
- }
- }
-
- // uses_count and uses_index[uses_count]
- int uses_count = cr.readUnsignedShort(off);
- off += 2;
- if (uses_count > 0) {
- for (int i=0; i<uses_count; i++) {
- String sn = cr.readClass(off, buf).replace('/', '.');
- builder.uses(sn);
- off += 2;
- }
- }
-
- // provides_count and provides[provides_count]
- int provides_count = cr.readUnsignedShort(off);
- off += 2;
- if (provides_count > 0) {
- for (int i=0; i<provides_count; i++) {
- String service = cr.readClass(off, buf).replace('/', '.');
- off += 2;
- int with_count = cr.readUnsignedShort(off);
- off += 2;
- List<String> providers = new ArrayList<>();
- for (int j=0; j<with_count; j++) {
- String cn = cr.readClass(off, buf).replace('/', '.');
- off += 2;
- providers.add(cn);
- }
- builder.provides(service, providers);
- }
- }
-
- return new ModuleAttribute(builder.build());
- }
-
- @Override
- protected ByteVector write(ClassWriter cw,
- byte[] code,
- int len,
- int maxStack,
- int maxLocals)
- {
- assert descriptor != null;
- ByteVector attr = new ByteVector();
-
- // module_name
- String mn = descriptor.name();
- int module_name_index = cw.newModule(mn);
- attr.putShort(module_name_index);
-
- // module_flags
- Set<ModuleDescriptor.Modifier> modifiers = descriptor.modifiers();
- int module_flags = 0;
- if (modifiers.contains(ModuleDescriptor.Modifier.OPEN))
- module_flags |= ACC_OPEN;
- if (modifiers.contains(ModuleDescriptor.Modifier.SYNTHETIC))
- module_flags |= ACC_SYNTHETIC;
- if (modifiers.contains(ModuleDescriptor.Modifier.MANDATED))
- module_flags |= ACC_MANDATED;
- attr.putShort(module_flags);
-
- // module_version
- String vs = descriptor.rawVersion().orElse(null);
- if (vs == null) {
- attr.putShort(0);
- } else {
- int module_version_index = cw.newUTF8(vs);
- attr.putShort(module_version_index);
- }
-
- // requires_count
- attr.putShort(descriptor.requires().size());
-
- // requires[requires_count]
- for (Requires r : descriptor.requires()) {
- int requires_index = cw.newModule(r.name());
- attr.putShort(requires_index);
-
- int requires_flags = 0;
- if (r.modifiers().contains(Requires.Modifier.TRANSITIVE))
- requires_flags |= ACC_TRANSITIVE;
- if (r.modifiers().contains(Requires.Modifier.STATIC))
- requires_flags |= ACC_STATIC_PHASE;
- if (r.modifiers().contains(Requires.Modifier.SYNTHETIC))
- requires_flags |= ACC_SYNTHETIC;
- if (r.modifiers().contains(Requires.Modifier.MANDATED))
- requires_flags |= ACC_MANDATED;
- attr.putShort(requires_flags);
-
- int requires_version_index;
- vs = r.rawCompiledVersion().orElse(null);
- if (vs == null) {
- requires_version_index = 0;
- } else {
- requires_version_index = cw.newUTF8(vs);
- }
- attr.putShort(requires_version_index);
- }
-
- // exports_count and exports[exports_count];
- attr.putShort(descriptor.exports().size());
- for (Exports e : descriptor.exports()) {
- String pkg = e.source().replace('.', '/');
- attr.putShort(cw.newPackage(pkg));
-
- int exports_flags = 0;
- if (e.modifiers().contains(Exports.Modifier.SYNTHETIC))
- exports_flags |= ACC_SYNTHETIC;
- if (e.modifiers().contains(Exports.Modifier.MANDATED))
- exports_flags |= ACC_MANDATED;
- attr.putShort(exports_flags);
-
- if (e.isQualified()) {
- Set<String> ts = e.targets();
- attr.putShort(ts.size());
- ts.forEach(target -> attr.putShort(cw.newModule(target)));
- } else {
- attr.putShort(0);
- }
- }
-
- // opens_counts and opens[opens_counts]
- attr.putShort(descriptor.opens().size());
- for (Opens obj : descriptor.opens()) {
- String pkg = obj.source().replace('.', '/');
- attr.putShort(cw.newPackage(pkg));
-
- int opens_flags = 0;
- if (obj.modifiers().contains(Opens.Modifier.SYNTHETIC))
- opens_flags |= ACC_SYNTHETIC;
- if (obj.modifiers().contains(Opens.Modifier.MANDATED))
- opens_flags |= ACC_MANDATED;
- attr.putShort(opens_flags);
-
- if (obj.isQualified()) {
- Set<String> ts = obj.targets();
- attr.putShort(ts.size());
- ts.forEach(target -> attr.putShort(cw.newModule(target)));
- } else {
- attr.putShort(0);
- }
- }
-
- // uses_count and uses_index[uses_count]
- if (descriptor.uses().isEmpty()) {
- attr.putShort(0);
- } else {
- attr.putShort(descriptor.uses().size());
- for (String s : descriptor.uses()) {
- String service = s.replace('.', '/');
- int index = cw.newClass(service);
- attr.putShort(index);
- }
- }
-
- // provides_count and provides[provides_count]
- if (descriptor.provides().isEmpty()) {
- attr.putShort(0);
- } else {
- attr.putShort(descriptor.provides().size());
- for (Provides p : descriptor.provides()) {
- String service = p.service().replace('.', '/');
- attr.putShort(cw.newClass(service));
- int with_count = p.providers().size();
- attr.putShort(with_count);
- for (String provider : p.providers()) {
- attr.putShort(cw.newClass(provider.replace('.', '/')));
- }
- }
- }
-
- return attr;
- }
- }
-
- /**
- * ModulePackages attribute.
- *
- * <pre> {@code
- *
- * ModulePackages_attribute {
- * // index to CONSTANT_utf8_info structure in constant pool representing
- * // the string "ModulePackages"
- * u2 attribute_name_index;
- * u4 attribute_length;
- *
- * // the number of entries in the packages table
- * u2 packages_count;
- * { // index to CONSTANT_Package_info structure with the package name
- * u2 package_index
- * } packages[package_count];
- *
- * }</pre>
- */
- public static class ModulePackagesAttribute extends Attribute {
- private final Set<String> packages;
-
- public ModulePackagesAttribute(Set<String> packages) {
- super(MODULE_PACKAGES);
- this.packages = packages;
- }
-
- public ModulePackagesAttribute() {
- this(null);
- }
-
- @Override
- protected Attribute read(ClassReader cr,
- int off,
- int len,
- char[] buf,
- int codeOff,
- Label[] labels)
- {
- // package count
- int package_count = cr.readUnsignedShort(off);
- off += 2;
-
- // packages
- Set<String> packages = new HashSet<>();
- for (int i=0; i<package_count; i++) {
- String pkg = cr.readPackage(off, buf).replace('/', '.');
- packages.add(pkg);
- off += 2;
- }
-
- return new ModulePackagesAttribute(packages);
- }
-
- @Override
- protected ByteVector write(ClassWriter cw,
- byte[] code,
- int len,
- int maxStack,
- int maxLocals)
- {
- assert packages != null;
-
- ByteVector attr = new ByteVector();
-
- // package_count
- attr.putShort(packages.size());
-
- // packages
- packages.stream()
- .map(p -> p.replace('.', '/'))
- .forEach(p -> attr.putShort(cw.newPackage(p)));
-
- return attr;
- }
-
- }
-
- /**
- * ModuleMainClass attribute.
- *
- * <pre> {@code
- *
- * MainClass_attribute {
- * // index to CONSTANT_utf8_info structure in constant pool representing
- * // the string "ModuleMainClass"
- * u2 attribute_name_index;
- * u4 attribute_length;
- *
- * // index to CONSTANT_Class_info structure with the main class name
- * u2 main_class_index;
- * }
- *
- * } </pre>
- */
- public static class ModuleMainClassAttribute extends Attribute {
- private final String mainClass;
-
- public ModuleMainClassAttribute(String mainClass) {
- super(MODULE_MAIN_CLASS);
- this.mainClass = mainClass;
- }
-
- public ModuleMainClassAttribute() {
- this(null);
- }
-
- @Override
- protected Attribute read(ClassReader cr,
- int off,
- int len,
- char[] buf,
- int codeOff,
- Label[] labels)
- {
- String value = cr.readClass(off, buf).replace('/', '.');
- return new ModuleMainClassAttribute(value);
- }
-
- @Override
- protected ByteVector write(ClassWriter cw,
- byte[] code,
- int len,
- int maxStack,
- int maxLocals)
- {
- ByteVector attr = new ByteVector();
- int index = cw.newClass(mainClass.replace('.', '/'));
- attr.putShort(index);
- return attr;
- }
- }
-
- /**
- * ModuleTarget attribute.
- *
- * <pre> {@code
- *
- * TargetPlatform_attribute {
- * // index to CONSTANT_utf8_info structure in constant pool representing
- * // the string "ModuleTarget"
- * u2 attribute_name_index;
- * u4 attribute_length;
- *
- * // index to CONSTANT_utf8_info structure with the target platform
- * u2 target_platform_index;
- * }
- *
- * } </pre>
- */
- public static class ModuleTargetAttribute extends Attribute {
- private final String targetPlatform;
-
- public ModuleTargetAttribute(String targetPlatform) {
- super(MODULE_TARGET);
- this.targetPlatform = targetPlatform;
- }
-
- public ModuleTargetAttribute() {
- this(null);
- }
-
- public String targetPlatform() {
- return targetPlatform;
- }
-
- @Override
- protected Attribute read(ClassReader cr,
- int off,
- int len,
- char[] buf,
- int codeOff,
- Label[] labels)
- {
-
- String targetPlatform = null;
-
- int target_platform_index = cr.readUnsignedShort(off);
- if (target_platform_index != 0)
- targetPlatform = cr.readUTF8(off, buf);
- off += 2;
-
- return new ModuleTargetAttribute(targetPlatform);
- }
-
- @Override
- protected ByteVector write(ClassWriter cw,
- byte[] code,
- int len,
- int maxStack,
- int maxLocals)
- {
- ByteVector attr = new ByteVector();
-
- int target_platform_index = 0;
- if (targetPlatform != null && targetPlatform.length() > 0)
- target_platform_index = cw.newUTF8(targetPlatform);
- attr.putShort(target_platform_index);
-
- return attr;
- }
- }
-
- /**
- * ModuleHashes attribute.
- *
- * <pre> {@code
- *
- * ModuleHashes_attribute {
- * // index to CONSTANT_utf8_info structure in constant pool representing
- * // the string "ModuleHashes"
- * u2 attribute_name_index;
- * u4 attribute_length;
- *
- * // index to CONSTANT_utf8_info structure with algorithm name
- * u2 algorithm_index;
- *
- * // the number of entries in the hashes table
- * u2 hashes_count;
- * { u2 module_name_index (index to CONSTANT_Module_info structure)
- * u2 hash_length;
- * u1 hash[hash_length];
- * } hashes[hashes_count];
- *
- * } </pre>
- */
- static class ModuleHashesAttribute extends Attribute {
- private final ModuleHashes hashes;
-
- ModuleHashesAttribute(ModuleHashes hashes) {
- super(MODULE_HASHES);
- this.hashes = hashes;
- }
-
- ModuleHashesAttribute() {
- this(null);
- }
-
- @Override
- protected Attribute read(ClassReader cr,
- int off,
- int len,
- char[] buf,
- int codeOff,
- Label[] labels)
- {
- String algorithm = cr.readUTF8(off, buf);
- off += 2;
-
- int hashes_count = cr.readUnsignedShort(off);
- off += 2;
-
- Map<String, byte[]> map = new HashMap<>();
- for (int i=0; i<hashes_count; i++) {
- String mn = cr.readModule(off, buf);
- off += 2;
-
- int hash_length = cr.readUnsignedShort(off);
- off += 2;
- byte[] hash = new byte[hash_length];
- for (int j=0; j<hash_length; j++) {
- hash[j] = (byte) (0xff & cr.readByte(off+j));
- }
- off += hash_length;
-
- map.put(mn, hash);
- }
-
- ModuleHashes hashes = new ModuleHashes(algorithm, map);
-
- return new ModuleHashesAttribute(hashes);
- }
-
- @Override
- protected ByteVector write(ClassWriter cw,
- byte[] code,
- int len,
- int maxStack,
- int maxLocals)
- {
- ByteVector attr = new ByteVector();
-
- int index = cw.newUTF8(hashes.algorithm());
- attr.putShort(index);
-
- Set<String> names = hashes.names();
- attr.putShort(names.size());
-
- for (String mn : names) {
- byte[] hash = hashes.hashFor(mn);
- assert hash != null;
- attr.putShort(cw.newModule(mn));
-
- attr.putShort(hash.length);
- for (byte b: hash) {
- attr.putByte(b);
- }
- }
-
- return attr;
- }
- }
-
- /**
- * ModuleResolution_attribute {
- * u2 attribute_name_index; // "ModuleResolution"
- * u4 attribute_length; // 2
- * u2 resolution_flags;
- *
- * The value of the resolution_flags item is a mask of flags used to denote
- * properties of module resolution. The flags are as follows:
- *
- * // Optional
- * 0x0001 (DO_NOT_RESOLVE_BY_DEFAULT)
- *
- * // At most one of:
- * 0x0002 (WARN_DEPRECATED)
- * 0x0004 (WARN_DEPRECATED_FOR_REMOVAL)
- * 0x0008 (WARN_INCUBATING)
- */
- static class ModuleResolutionAttribute extends Attribute {
- private final int value;
-
- ModuleResolutionAttribute() {
- super(MODULE_RESOLUTION);
- value = 0;
- }
-
- ModuleResolutionAttribute(int value) {
- super(MODULE_RESOLUTION);
- this.value = value;
- }
-
- @Override
- protected Attribute read(ClassReader cr,
- int off,
- int len,
- char[] buf,
- int codeOff,
- Label[] labels)
- {
- int flags = cr.readUnsignedShort(off);
- return new ModuleResolutionAttribute(flags);
- }
-
- @Override
- protected ByteVector write(ClassWriter cw,
- byte[] code,
- int len,
- int maxStack,
- int maxLocals)
- {
- ByteVector attr = new ByteVector();
- attr.putShort(value);
- return attr;
- }
- }
-}
--- a/src/java.base/share/classes/jdk/internal/module/ModuleInfoExtender.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/module/ModuleInfoExtender.java Wed Nov 08 16:03:35 2017 -0500
@@ -31,18 +31,18 @@
import java.lang.module.ModuleDescriptor.Version;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import jdk.internal.org.objectweb.asm.Attribute;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
-
-import static jdk.internal.module.ClassFileAttributes.*;
+import jdk.internal.org.objectweb.asm.commons.ModuleHashesAttribute;
+import jdk.internal.org.objectweb.asm.commons.ModuleResolutionAttribute;
+import jdk.internal.org.objectweb.asm.commons.ModuleTargetAttribute;
/**
* Utility class to extend a module-info.class with additional attributes.
@@ -133,43 +133,6 @@
}
/**
- * A ClassVisitor that supports adding class file attributes. If an
- * attribute already exists then the first occurrence of the attribute
- * is replaced.
- */
- private static class AttributeAddingClassVisitor extends ClassVisitor {
- private Map<String, Attribute> attrs = new HashMap<>();
-
- AttributeAddingClassVisitor(int api, ClassVisitor cv) {
- super(api, cv);
- }
-
- void addAttribute(Attribute attr) {
- attrs.put(attr.type, attr);
- }
-
- @Override
- public void visitAttribute(Attribute attr) {
- String name = attr.type;
- Attribute replacement = attrs.get(name);
- if (replacement != null) {
- attr = replacement;
- attrs.remove(name);
- }
- super.visitAttribute(attr);
- }
-
- /**
- * Adds any remaining attributes that weren't replaced to the
- * class file.
- */
- void finish() {
- attrs.values().forEach(a -> super.visitAttribute(a));
- attrs.clear();
- }
- }
-
- /**
* Outputs the modified module-info.class to the given output stream.
* Once this method has been called then the Extender object should
* be discarded.
@@ -185,38 +148,86 @@
* be discarded.
*/
public byte[] toByteArray() throws IOException {
- ClassWriter cw
- = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
-
- AttributeAddingClassVisitor cv
- = new AttributeAddingClassVisitor(Opcodes.ASM5, cw);
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
+ + ClassWriter.COMPUTE_FRAMES);
ClassReader cr = new ClassReader(in);
- if (packages != null)
- cv.addAttribute(new ModulePackagesAttribute(packages));
- if (mainClass != null)
- cv.addAttribute(new ModuleMainClassAttribute(mainClass));
- if (targetPlatform != null)
- cv.addAttribute(new ModuleTargetAttribute(targetPlatform));
- if (hashes != null)
- cv.addAttribute(new ModuleHashesAttribute(hashes));
- if (moduleResolution != null)
- cv.addAttribute(new ModuleResolutionAttribute(moduleResolution.value()));
+ ClassVisitor cv = new ClassVisitor(Opcodes.ASM6, cw) {
+ @Override
+ public ModuleVisitor visitModule(String name, int flags, String version) {
+ Version v = ModuleInfoExtender.this.version;
+ String vs = (v != null) ? v.toString() : version;
+ ModuleVisitor mv = super.visitModule(name, flags, vs);
+
+ // ModuleMainClass attribute
+ if (mainClass != null) {
+ mv.visitMainClass(mainClass.replace('.', '/'));
+ }
+
+ // ModulePackages attribute
+ if (packages != null) {
+ packages.forEach(pn -> mv.visitPackage(pn.replace('.', '/')));
+ }
+
+ return new ModuleVisitor(Opcodes.ASM6, mv) {
+ public void visitMainClass(String existingMainClass) {
+ // skip main class if there is a new value
+ if (mainClass == null) {
+ super.visitMainClass(existingMainClass);
+ }
+ }
+ public void visitPackage(String existingPackage) {
+ // skip packages if there is a new set of packages
+ if (packages == null) {
+ super.visitPackage(existingPackage);
+ }
+ }
+ };
+ }
+ @Override
+ public void visitAttribute(Attribute attr) {
+ String name = attr.type;
+ // drop existing attributes if there are replacements
+ if (name.equals(ClassFileConstants.MODULE_TARGET)
+ && targetPlatform != null)
+ return;
+ if (name.equals(ClassFileConstants.MODULE_RESOLUTION)
+ && moduleResolution != null)
+ return;
+ if (name.equals(ClassFileConstants.MODULE_HASHES)
+ && hashes != null)
+ return;
+
+ super.visitAttribute(attr);
+
+ }
+ };
List<Attribute> attrs = new ArrayList<>();
-
- // prototypes of attributes that should be parsed
- attrs.add(new ModuleAttribute(version));
- attrs.add(new ModulePackagesAttribute());
- attrs.add(new ModuleMainClassAttribute());
attrs.add(new ModuleTargetAttribute());
+ attrs.add(new ModuleResolutionAttribute());
attrs.add(new ModuleHashesAttribute());
-
cr.accept(cv, attrs.toArray(new Attribute[0]), 0);
- // add any attributes that didn't replace previous attributes
- cv.finish();
+ // add ModuleTarget, ModuleResolution and ModuleHashes attributes
+ if (targetPlatform != null) {
+ cw.visitAttribute(new ModuleTargetAttribute(targetPlatform));
+ }
+ if (moduleResolution != null) {
+ int flags = moduleResolution.value();
+ cw.visitAttribute(new ModuleResolutionAttribute(flags));
+ }
+ if (hashes != null) {
+ String algorithm = hashes.algorithm();
+ List<String> names = new ArrayList<>();
+ List<byte[]> values = new ArrayList<>();
+ for (String name : hashes.names()) {
+ names.add(name);
+ values.add(hashes.hashFor(name));
+ }
+ cw.visitAttribute(new ModuleHashesAttribute(algorithm, names, values));
+ }
return cw.toByteArray();
}
--- a/src/java.base/share/classes/jdk/internal/module/ModuleInfoWriter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/module/ModuleInfoWriter.java Wed Nov 08 16:03:35 2017 -0500
@@ -28,13 +28,14 @@
import java.io.OutputStream;
import java.lang.module.ModuleDescriptor;
import java.nio.ByteBuffer;
+import java.util.Map;
import java.util.stream.Stream;
import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
-
-import static jdk.internal.module.ClassFileAttributes.*;
-import static jdk.internal.module.ClassFileConstants.ACC_MODULE;
+import jdk.internal.org.objectweb.asm.commons.ModuleTargetAttribute;
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
/**
* Utility class to write a ModuleDescriptor as a module-info.class.
@@ -42,6 +43,35 @@
public final class ModuleInfoWriter {
+ private static final Map<ModuleDescriptor.Modifier, Integer>
+ MODULE_MODS_TO_FLAGS = Map.of(
+ ModuleDescriptor.Modifier.OPEN, ACC_OPEN,
+ ModuleDescriptor.Modifier.SYNTHETIC, ACC_SYNTHETIC,
+ ModuleDescriptor.Modifier.MANDATED, ACC_MANDATED
+ );
+
+ private static final Map<ModuleDescriptor.Requires.Modifier, Integer>
+ REQUIRES_MODS_TO_FLAGS = Map.of(
+ ModuleDescriptor.Requires.Modifier.TRANSITIVE, ACC_TRANSITIVE,
+ ModuleDescriptor.Requires.Modifier.STATIC, ACC_STATIC_PHASE,
+ ModuleDescriptor.Requires.Modifier.SYNTHETIC, ACC_SYNTHETIC,
+ ModuleDescriptor.Requires.Modifier.MANDATED, ACC_MANDATED
+ );
+
+ private static final Map<ModuleDescriptor.Exports.Modifier, Integer>
+ EXPORTS_MODS_TO_FLAGS = Map.of(
+ ModuleDescriptor.Exports.Modifier.SYNTHETIC, ACC_SYNTHETIC,
+ ModuleDescriptor.Exports.Modifier.MANDATED, ACC_MANDATED
+ );
+
+ private static final Map<ModuleDescriptor.Opens.Modifier, Integer>
+ OPENS_MODS_TO_FLAGS = Map.of(
+ ModuleDescriptor.Opens.Modifier.SYNTHETIC, ACC_SYNTHETIC,
+ ModuleDescriptor.Opens.Modifier.MANDATED, ACC_MANDATED
+ );
+
+ private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
private ModuleInfoWriter() { }
/**
@@ -50,24 +80,75 @@
*/
private static byte[] toModuleInfo(ModuleDescriptor md, ModuleTarget target) {
ClassWriter cw = new ClassWriter(0);
- cw.visit(Opcodes.V1_9, ACC_MODULE, "module-info", null, null, null);
- cw.visitAttribute(new ModuleAttribute(md));
+ cw.visit(Opcodes.V9, ACC_MODULE, "module-info", null, null, null);
+
+ int moduleFlags = md.modifiers().stream()
+ .map(MODULE_MODS_TO_FLAGS::get)
+ .reduce(0, (x, y) -> (x | y));
+ String vs = md.rawVersion().orElse(null);
+ ModuleVisitor mv = cw.visitModule(md.name(), moduleFlags, vs);
+
+ // requires
+ for (ModuleDescriptor.Requires r : md.requires()) {
+ int flags = r.modifiers().stream()
+ .map(REQUIRES_MODS_TO_FLAGS::get)
+ .reduce(0, (x, y) -> (x | y));
+ vs = r.rawCompiledVersion().orElse(null);
+ mv.visitRequire(r.name(), flags, vs);
+ }
- // for tests: write the ModulePackages attribute when there are packages
- // that aren't exported or open
+ // exports
+ for (ModuleDescriptor.Exports e : md.exports()) {
+ int flags = e.modifiers().stream()
+ .map(EXPORTS_MODS_TO_FLAGS::get)
+ .reduce(0, (x, y) -> (x | y));
+ String[] targets = e.targets().toArray(EMPTY_STRING_ARRAY);
+ mv.visitExport(e.source().replace('.', '/'), flags, targets);
+ }
+
+ // opens
+ for (ModuleDescriptor.Opens opens : md.opens()) {
+ int flags = opens.modifiers().stream()
+ .map(OPENS_MODS_TO_FLAGS::get)
+ .reduce(0, (x, y) -> (x | y));
+ String[] targets = opens.targets().toArray(EMPTY_STRING_ARRAY);
+ mv.visitOpen(opens.source().replace('.', '/'), flags, targets);
+ }
+
+ // uses
+ md.uses().stream().map(sn -> sn.replace('.', '/')).forEach(mv::visitUse);
+
+ // provides
+ for (ModuleDescriptor.Provides p : md.provides()) {
+ mv.visitProvide(p.service().replace('.', '/'),
+ p.providers()
+ .stream()
+ .map(pn -> pn.replace('.', '/'))
+ .toArray(String[]::new));
+ }
+
+ // add the ModulePackages attribute when there are packages that aren't
+ // exported or open
Stream<String> exported = md.exports().stream()
.map(ModuleDescriptor.Exports::source);
Stream<String> open = md.opens().stream()
.map(ModuleDescriptor.Opens::source);
long exportedOrOpen = Stream.concat(exported, open).distinct().count();
- if (md.packages().size() > exportedOrOpen)
- cw.visitAttribute(new ModulePackagesAttribute(md.packages()));
+ if (md.packages().size() > exportedOrOpen) {
+ md.packages().stream()
+ .map(pn -> pn.replace('.', '/'))
+ .forEach(mv::visitPackage);
+ }
- // write ModuleMainClass if the module has a main class
- md.mainClass().ifPresent(mc -> cw.visitAttribute(new ModuleMainClassAttribute(mc)));
+ // ModuleMainClass attribute
+ md.mainClass()
+ .map(mc -> mc.replace('.', '/'))
+ .ifPresent(mv::visitMainClass);
- // write ModuleTarget if there is a target platform
- if (target != null) {
+ mv.visitEnd();
+
+ // write ModuleTarget attribute if there is a target platform
+ if (target != null && target.targetPlatform().length() > 0) {
cw.visitAttribute(new ModuleTargetAttribute(target.targetPlatform()));
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationVisitor.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationVisitor.java Wed Nov 08 16:03:35 2017 -0500
@@ -70,7 +70,7 @@
/**
* The ASM API version implemented by this visitor. The value of this field
- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected final int api;
@@ -85,7 +85,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public AnnotationVisitor(final int api) {
this(api, null);
@@ -96,13 +96,13 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param av
* the annotation visitor to which this visitor must delegate
* method calls. May be null.
*/
public AnnotationVisitor(final int api, final AnnotationVisitor av) {
- if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+ if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
throw new IllegalArgumentException();
}
this.api = api;
@@ -118,7 +118,7 @@
* the actual value, whose type must be {@link Byte},
* {@link Boolean}, {@link Character}, {@link Short},
* {@link Integer} , {@link Long}, {@link Float}, {@link Double},
- * {@link String} or {@link Type} or OBJECT or ARRAY sort. This
+ * {@link String} or {@link Type} of OBJECT or ARRAY sort. This
* value can also be an array of byte, boolean, short, char, int,
* long, float or double values (this is equivalent to using
* {@link #visitArray visitArray} and visiting each array element
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationWriter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationWriter.java Wed Nov 08 16:03:35 2017 -0500
@@ -133,7 +133,7 @@
*/
AnnotationWriter(final ClassWriter cw, final boolean named,
final ByteVector bv, final ByteVector parent, final int offset) {
- super(Opcodes.ASM5);
+ super(Opcodes.ASM6);
this.cw = cw;
this.named = named;
this.bv = bv;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java Wed Nov 08 16:03:35 2017 -0500
@@ -73,31 +73,6 @@
public class ClassReader {
/**
- * True to enable signatures support.
- */
- static final boolean SIGNATURES = true;
-
- /**
- * True to enable annotations support.
- */
- static final boolean ANNOTATIONS = true;
-
- /**
- * True to enable stack map frames support.
- */
- static final boolean FRAMES = true;
-
- /**
- * True to enable bytecode writing support.
- */
- static final boolean WRITER = true;
-
- /**
- * True to enable JSR_W and GOTO_W support.
- */
- static final boolean RESIZE = true;
-
- /**
* Flag to skip method code. If this class is set <code>CODE</code>
* attribute won't be visited. This can be used, for example, to retrieve
* annotations for methods and method parameters.
@@ -134,6 +109,21 @@
public static final int EXPAND_FRAMES = 8;
/**
+ * Flag to expand the ASM pseudo instructions into an equivalent sequence of
+ * standard bytecode instructions. When resolving a forward jump it may
+ * happen that the signed 2 bytes offset reserved for it is not sufficient
+ * to store the bytecode offset. In this case the jump instruction is
+ * replaced with a temporary ASM pseudo instruction using an unsigned 2
+ * bytes offset (see Label#resolve). This internal flag is used to re-read
+ * classes containing such instructions, in order to replace them with
+ * standard instructions. In addition, when this flag is used, GOTO_W and
+ * JSR_W are <i>not</i> converted into GOTO and JSR, to make sure that
+ * infinite loops where a GOTO_W is replaced with a GOTO in ClassReader and
+ * converted back to a GOTO_W in ClassWriter cannot occur.
+ */
+ static final int EXPAND_ASM_INSNS = 256;
+
+ /**
* The class to be parsed. <i>The content of this array must not be
* modified. This field is intended for {@link Attribute} sub classes, and
* is normally not needed by class generators or adapters.</i>
@@ -195,7 +185,7 @@
public ClassReader(final byte[] b, final int off, final int len) {
this.b = b;
// checks the class version
- if (readShort(off + 6) > Opcodes.V1_9) {
+ if (readShort(off + 6) > Opcodes.V9) {
throw new IllegalArgumentException();
}
// parses the constant pool
@@ -234,6 +224,8 @@
// case ClassWriter.CLASS:
// case ClassWriter.STR:
// case ClassWriter.MTYPE
+ // case ClassWriter.PACKAGE:
+ // case ClassWriter.MODULE:
default:
size = 3;
break;
@@ -377,7 +369,9 @@
break;
// case ClassWriter.STR:
// case ClassWriter.CLASS:
- // case ClassWriter.MTYPE
+ // case ClassWriter.MTYPE:
+ // case ClassWriter.MODULE:
+ // case ClassWriter.PACKAGE:
default:
item.set(tag, readUTF8(index, buf), null, null);
break;
@@ -584,11 +578,14 @@
String enclosingOwner = null;
String enclosingName = null;
String enclosingDesc = null;
+ String moduleMainClass = null;
int anns = 0;
int ianns = 0;
int tanns = 0;
int itanns = 0;
int innerClasses = 0;
+ int module = 0;
+ int packages = 0;
Attribute attributes = null;
u = getAttributes();
@@ -607,13 +604,11 @@
enclosingName = readUTF8(items[item], c);
enclosingDesc = readUTF8(items[item] + 2, c);
}
- } else if (SIGNATURES && "Signature".equals(attrName)) {
+ } else if ("Signature".equals(attrName)) {
signature = readUTF8(u + 8, c);
- } else if (ANNOTATIONS
- && "RuntimeVisibleAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleAnnotations".equals(attrName)) {
anns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
tanns = u + 8;
} else if ("Deprecated".equals(attrName)) {
access |= Opcodes.ACC_DEPRECATED;
@@ -623,12 +618,16 @@
} else if ("SourceDebugExtension".equals(attrName)) {
int len = readInt(u + 4);
sourceDebug = readUTF(u + 8, len, new char[len]);
- } else if (ANNOTATIONS
- && "RuntimeInvisibleAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleAnnotations".equals(attrName)) {
ianns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
itanns = u + 8;
+ } else if ("Module".equals(attrName)) {
+ module = u + 8;
+ } else if ("ModuleMainClass".equals(attrName)) {
+ moduleMainClass = readClass(u + 8, c);
+ } else if ("ModulePackages".equals(attrName)) {
+ packages = u + 10;
} else if ("BootstrapMethods".equals(attrName)) {
int[] bootstrapMethods = new int[readUnsignedShort(u + 8)];
for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) {
@@ -657,6 +656,12 @@
classVisitor.visitSource(sourceFile, sourceDebug);
}
+ // visits the module info and associated attributes
+ if (module != 0) {
+ readModule(classVisitor, context, module,
+ moduleMainClass, packages);
+ }
+
// visits the outer class
if (enclosingOwner != null) {
classVisitor.visitOuterClass(enclosingOwner, enclosingName,
@@ -664,19 +669,19 @@
}
// visits the class annotations and type annotations
- if (ANNOTATIONS && anns != 0) {
+ if (anns != 0) {
for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
classVisitor.visitAnnotation(readUTF8(v, c), true));
}
}
- if (ANNOTATIONS && ianns != 0) {
+ if (ianns != 0) {
for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
classVisitor.visitAnnotation(readUTF8(v, c), false));
}
}
- if (ANNOTATIONS && tanns != 0) {
+ if (tanns != 0) {
for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
v = readAnnotationTarget(context, v);
v = readAnnotationValues(v + 2, c, true,
@@ -684,7 +689,7 @@
context.typePath, readUTF8(v, c), true));
}
}
- if (ANNOTATIONS && itanns != 0) {
+ if (itanns != 0) {
for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
v = readAnnotationTarget(context, v);
v = readAnnotationValues(v + 2, c, true,
@@ -727,6 +732,120 @@
}
/**
+ * Reads the module attribute and visit it.
+ *
+ * @param classVisitor
+ * the current class visitor
+ * @param context
+ * information about the class being parsed.
+ * @param u
+ * start offset of the module attribute in the class file.
+ * @param mainClass
+ * name of the main class of a module or null.
+ * @param packages
+ * start offset of the concealed package attribute.
+ */
+ private void readModule(final ClassVisitor classVisitor,
+ final Context context, int u,
+ final String mainClass, int packages) {
+
+ char[] buffer = context.buffer;
+
+ // reads module name, flags and version
+ String name = readModule(u, buffer);
+ int flags = readUnsignedShort(u + 2);
+ String version = readUTF8(u + 4, buffer);
+ u += 6;
+
+ ModuleVisitor mv = classVisitor.visitModule(name, flags, version);
+ if (mv == null) {
+ return;
+ }
+
+ // module attributes (main class, packages)
+ if (mainClass != null) {
+ mv.visitMainClass(mainClass);
+ }
+
+ if (packages != 0) {
+ for (int i = readUnsignedShort(packages - 2); i > 0; --i) {
+ String packaze = readPackage(packages, buffer);
+ mv.visitPackage(packaze);
+ packages += 2;
+ }
+ }
+
+ // reads requires
+ u += 2;
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ String module = readModule(u, buffer);
+ int access = readUnsignedShort(u + 2);
+ String requireVersion = readUTF8(u + 4, buffer);
+ mv.visitRequire(module, access, requireVersion);
+ u += 6;
+ }
+
+ // reads exports
+ u += 2;
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ String export = readPackage(u, buffer);
+ int access = readUnsignedShort(u + 2);
+ int exportToCount = readUnsignedShort(u + 4);
+ u += 6;
+ String[] tos = null;
+ if (exportToCount != 0) {
+ tos = new String[exportToCount];
+ for (int j = 0; j < tos.length; ++j) {
+ tos[j] = readModule(u, buffer);
+ u += 2;
+ }
+ }
+ mv.visitExport(export, access, tos);
+ }
+
+ // reads opens
+ u += 2;
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ String open = readPackage(u, buffer);
+ int access = readUnsignedShort(u + 2);
+ int openToCount = readUnsignedShort(u + 4);
+ u += 6;
+ String[] tos = null;
+ if (openToCount != 0) {
+ tos = new String[openToCount];
+ for (int j = 0; j < tos.length; ++j) {
+ tos[j] = readModule(u, buffer);
+ u += 2;
+ }
+ }
+ mv.visitOpen(open, access, tos);
+ }
+
+ // read uses
+ u += 2;
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ mv.visitUse(readClass(u, buffer));
+ u += 2;
+ }
+
+ // read provides
+ u += 2;
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ String service = readClass(u, buffer);
+ int provideWithCount = readUnsignedShort(u + 2);
+ u += 4;
+ String[] withs = new String[provideWithCount];
+ for (int j = 0; j < withs.length; ++j) {
+ withs[j] = readClass(u, buffer);
+ u += 2;
+ }
+ mv.visitProvide(service, withs);
+ }
+
+ mv.visitEnd();
+ }
+
+ /**
* Reads a field and makes the given visitor visit it.
*
* @param classVisitor
@@ -762,24 +881,20 @@
if ("ConstantValue".equals(attrName)) {
int item = readUnsignedShort(u + 8);
value = item == 0 ? null : readConst(item, c);
- } else if (SIGNATURES && "Signature".equals(attrName)) {
+ } else if ("Signature".equals(attrName)) {
signature = readUTF8(u + 8, c);
} else if ("Deprecated".equals(attrName)) {
access |= Opcodes.ACC_DEPRECATED;
} else if ("Synthetic".equals(attrName)) {
access |= Opcodes.ACC_SYNTHETIC
| ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
- } else if (ANNOTATIONS
- && "RuntimeVisibleAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleAnnotations".equals(attrName)) {
anns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
tanns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeInvisibleAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleAnnotations".equals(attrName)) {
ianns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
itanns = u + 8;
} else {
Attribute attr = readAttribute(context.attrs, attrName, u + 8,
@@ -801,19 +916,19 @@
}
// visits the field annotations and type annotations
- if (ANNOTATIONS && anns != 0) {
+ if (anns != 0) {
for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
fv.visitAnnotation(readUTF8(v, c), true));
}
}
- if (ANNOTATIONS && ianns != 0) {
+ if (ianns != 0) {
for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
fv.visitAnnotation(readUTF8(v, c), false));
}
}
- if (ANNOTATIONS && tanns != 0) {
+ if (tanns != 0) {
for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
v = readAnnotationTarget(context, v);
v = readAnnotationValues(v + 2, c, true,
@@ -821,7 +936,7 @@
context.typePath, readUTF8(v, c), true));
}
}
- if (ANNOTATIONS && itanns != 0) {
+ if (itanns != 0) {
for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
v = readAnnotationTarget(context, v);
v = readAnnotationValues(v + 2, c, true,
@@ -895,32 +1010,26 @@
exceptions[j] = readClass(exception, c);
exception += 2;
}
- } else if (SIGNATURES && "Signature".equals(attrName)) {
+ } else if ("Signature".equals(attrName)) {
signature = readUTF8(u + 8, c);
} else if ("Deprecated".equals(attrName)) {
context.access |= Opcodes.ACC_DEPRECATED;
- } else if (ANNOTATIONS
- && "RuntimeVisibleAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleAnnotations".equals(attrName)) {
anns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
tanns = u + 8;
- } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
+ } else if ("AnnotationDefault".equals(attrName)) {
dann = u + 8;
} else if ("Synthetic".equals(attrName)) {
context.access |= Opcodes.ACC_SYNTHETIC
| ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
- } else if (ANNOTATIONS
- && "RuntimeInvisibleAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleAnnotations".equals(attrName)) {
ianns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
itanns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeVisibleParameterAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleParameterAnnotations".equals(attrName)) {
mpanns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeInvisibleParameterAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleParameterAnnotations".equals(attrName)) {
impanns = u + 8;
} else if ("MethodParameters".equals(attrName)) {
methodParameters = u + 8;
@@ -953,7 +1062,7 @@
* access, name and descriptor can have been changed, this is not
* important since they are not copied as is from the reader).
*/
- if (WRITER && mv instanceof MethodWriter) {
+ if (mv instanceof MethodWriter) {
MethodWriter mw = (MethodWriter) mv;
if (mw.cw.cr == this && signature == mw.signature) {
boolean sameExceptions = false;
@@ -990,26 +1099,26 @@
}
// visits the method annotations
- if (ANNOTATIONS && dann != 0) {
+ if (dann != 0) {
AnnotationVisitor dv = mv.visitAnnotationDefault();
readAnnotationValue(dann, c, null, dv);
if (dv != null) {
dv.visitEnd();
}
}
- if (ANNOTATIONS && anns != 0) {
+ if (anns != 0) {
for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
mv.visitAnnotation(readUTF8(v, c), true));
}
}
- if (ANNOTATIONS && ianns != 0) {
+ if (ianns != 0) {
for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
mv.visitAnnotation(readUTF8(v, c), false));
}
}
- if (ANNOTATIONS && tanns != 0) {
+ if (tanns != 0) {
for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
v = readAnnotationTarget(context, v);
v = readAnnotationValues(v + 2, c, true,
@@ -1017,7 +1126,7 @@
context.typePath, readUTF8(v, c), true));
}
}
- if (ANNOTATIONS && itanns != 0) {
+ if (itanns != 0) {
for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
v = readAnnotationTarget(context, v);
v = readAnnotationValues(v + 2, c, true,
@@ -1025,10 +1134,10 @@
context.typePath, readUTF8(v, c), false));
}
}
- if (ANNOTATIONS && mpanns != 0) {
+ if (mpanns != 0) {
readParameterAnnotations(mv, context, mpanns, true);
}
- if (ANNOTATIONS && impanns != 0) {
+ if (impanns != 0) {
readParameterAnnotations(mv, context, impanns, false);
}
@@ -1075,7 +1184,7 @@
int codeStart = u;
int codeEnd = u + codeLength;
Label[] labels = context.labels = new Label[codeLength + 2];
- readLabel(codeLength + 1, labels);
+ createLabel(codeLength + 1, labels);
while (u < codeEnd) {
int offset = u - codeStart;
int opcode = b[u] & 0xFF;
@@ -1085,11 +1194,16 @@
u += 1;
break;
case ClassWriter.LABEL_INSN:
- readLabel(offset + readShort(u + 1), labels);
+ createLabel(offset + readShort(u + 1), labels);
+ u += 3;
+ break;
+ case ClassWriter.ASM_LABEL_INSN:
+ createLabel(offset + readUnsignedShort(u + 1), labels);
u += 3;
break;
case ClassWriter.LABELW_INSN:
- readLabel(offset + readInt(u + 1), labels);
+ case ClassWriter.ASM_LABELW_INSN:
+ createLabel(offset + readInt(u + 1), labels);
u += 5;
break;
case ClassWriter.WIDE_INSN:
@@ -1104,9 +1218,9 @@
// skips 0 to 3 padding bytes
u = u + 4 - (offset & 3);
// reads instruction
- readLabel(offset + readInt(u), labels);
+ createLabel(offset + readInt(u), labels);
for (int i = readInt(u + 8) - readInt(u + 4) + 1; i > 0; --i) {
- readLabel(offset + readInt(u + 12), labels);
+ createLabel(offset + readInt(u + 12), labels);
u += 4;
}
u += 12;
@@ -1115,9 +1229,9 @@
// skips 0 to 3 padding bytes
u = u + 4 - (offset & 3);
// reads instruction
- readLabel(offset + readInt(u), labels);
+ createLabel(offset + readInt(u), labels);
for (int i = readInt(u + 4); i > 0; --i) {
- readLabel(offset + readInt(u + 12), labels);
+ createLabel(offset + readInt(u + 12), labels);
u += 8;
}
u += 8;
@@ -1147,9 +1261,9 @@
// reads the try catch entries to find the labels, and also visits them
for (int i = readUnsignedShort(u); i > 0; --i) {
- Label start = readLabel(readUnsignedShort(u + 2), labels);
- Label end = readLabel(readUnsignedShort(u + 4), labels);
- Label handler = readLabel(readUnsignedShort(u + 6), labels);
+ Label start = createLabel(readUnsignedShort(u + 2), labels);
+ Label end = createLabel(readUnsignedShort(u + 4), labels);
+ Label handler = createLabel(readUnsignedShort(u + 6), labels);
String type = readUTF8(items[readUnsignedShort(u + 8)], c);
mv.visitTryCatchBlock(start, end, handler, type);
u += 8;
@@ -1180,13 +1294,9 @@
varTable = u + 8;
for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
int label = readUnsignedShort(v + 10);
- if (labels[label] == null) {
- readLabel(label, labels).status |= Label.DEBUG;
- }
+ createDebugLabel(label, labels);
label += readUnsignedShort(v + 12);
- if (labels[label] == null) {
- readLabel(label, labels).status |= Label.DEBUG;
- }
+ createDebugLabel(label, labels);
v += 10;
}
}
@@ -1196,9 +1306,7 @@
if ((context.flags & SKIP_DEBUG) == 0) {
for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
int label = readUnsignedShort(v + 10);
- if (labels[label] == null) {
- readLabel(label, labels).status |= Label.DEBUG;
- }
+ createDebugLabel(label, labels);
Label l = labels[label];
while (l.line > 0) {
if (l.next == null) {
@@ -1210,17 +1318,15 @@
v += 4;
}
}
- } else if (ANNOTATIONS
- && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
tanns = readTypeAnnotations(mv, context, u + 8, true);
ntoff = tanns.length == 0 || readByte(tanns[0]) < 0x43 ? -1
: readUnsignedShort(tanns[0] + 1);
- } else if (ANNOTATIONS
- && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
itanns = readTypeAnnotations(mv, context, u + 8, false);
nitoff = itanns.length == 0 || readByte(itanns[0]) < 0x43 ? -1
: readUnsignedShort(itanns[0] + 1);
- } else if (FRAMES && "StackMapTable".equals(attrName)) {
+ } else if ("StackMapTable".equals(attrName)) {
if ((context.flags & SKIP_FRAMES) == 0) {
stackMap = u + 10;
stackMapSize = readInt(u + 4);
@@ -1244,7 +1350,7 @@
* this by parsing the stack map table without a full decoding
* (see below).
*/
- } else if (FRAMES && "StackMap".equals(attrName)) {
+ } else if ("StackMap".equals(attrName)) {
if ((context.flags & SKIP_FRAMES) == 0) {
zip = false;
stackMap = u + 10;
@@ -1273,7 +1379,7 @@
u += 2;
// generates the first (implicit) stack map frame
- if (FRAMES && stackMap != 0) {
+ if (stackMap != 0) {
/*
* for the first explicit frame the offset is not offset_delta + 1
* but only offset_delta; setting the implicit frame offset to -1
@@ -1306,14 +1412,31 @@
int v = readUnsignedShort(i + 1);
if (v >= 0 && v < codeLength) {
if ((b[codeStart + v] & 0xFF) == Opcodes.NEW) {
- readLabel(v, labels);
+ createLabel(v, labels);
}
}
}
}
}
+ if ((context.flags & EXPAND_ASM_INSNS) != 0
+ && (context.flags & EXPAND_FRAMES) != 0) {
+ // Expanding the ASM pseudo instructions can introduce F_INSERT
+ // frames, even if the method does not currently have any frame.
+ // Also these inserted frames must be computed by simulating the
+ // effect of the bytecode instructions one by one, starting from the
+ // first one and the last existing frame (or the implicit first
+ // one). Finally, due to the way MethodWriter computes this (with
+ // the compute = INSERTED_FRAMES option), MethodWriter needs to know
+ // maxLocals before the first instruction is visited. For all these
+ // reasons we always visit the implicit first frame in this case
+ // (passing only maxLocals - the rest can be and is computed in
+ // MethodWriter).
+ mv.visitFrame(Opcodes.F_NEW, maxLocals, null, 0, null);
+ }
// visits the instructions
+ int opcodeDelta = (context.flags & EXPAND_ASM_INSNS) == 0 ? -33 : 0;
+ boolean insertFrame = false;
u = codeStart;
while (u < codeEnd) {
int offset = u - codeStart;
@@ -1334,7 +1457,7 @@
}
// visits the frame for this offset, if any
- while (FRAMES && frame != null
+ while (frame != null
&& (frame.offset == offset || frame.offset == -1)) {
// if there is a frame for this offset, makes the visitor visit
// it, and reads the next frame if there is one.
@@ -1346,6 +1469,9 @@
mv.visitFrame(frame.mode, frame.localDiff, frame.local,
frame.stackCount, frame.stack);
}
+ // if there is already a frame for this offset, there is no
+ // need to insert a new one.
+ insertFrame = false;
}
if (frameCount > 0) {
stackMap = readFrame(stackMap, zip, unzip, frame);
@@ -1354,6 +1480,13 @@
frame = null;
}
}
+ // inserts a frame for this offset, if requested by setting
+ // insertFrame to true during the previous iteration. The actual
+ // frame content will be computed in MethodWriter.
+ if (insertFrame) {
+ mv.visitFrame(ClassWriter.F_INSERT, 0, null, 0, null);
+ insertFrame = false;
+ }
// visits the instruction at this offset
int opcode = b[u] & 0xFF;
@@ -1378,9 +1511,47 @@
u += 3;
break;
case ClassWriter.LABELW_INSN:
- mv.visitJumpInsn(opcode - 33, labels[offset + readInt(u + 1)]);
+ mv.visitJumpInsn(opcode + opcodeDelta, labels[offset
+ + readInt(u + 1)]);
u += 5;
break;
+ case ClassWriter.ASM_LABEL_INSN: {
+ // changes temporary opcodes 202 to 217 (inclusive), 218
+ // and 219 to IFEQ ... JSR (inclusive), IFNULL and
+ // IFNONNULL
+ opcode = opcode < 218 ? opcode - 49 : opcode - 20;
+ Label target = labels[offset + readUnsignedShort(u + 1)];
+ // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
+ // <l> with IFNOTxxx <L> GOTO_W <l> L:..., where IFNOTxxx is
+ // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
+ // and where <L> designates the instruction just after
+ // the GOTO_W.
+ if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
+ mv.visitJumpInsn(opcode + 33, target);
+ } else {
+ opcode = opcode <= 166 ? ((opcode + 1) ^ 1) - 1
+ : opcode ^ 1;
+ Label endif = createLabel(offset + 3, labels);
+ mv.visitJumpInsn(opcode, endif);
+ mv.visitJumpInsn(200, target); // GOTO_W
+ // endif designates the instruction just after GOTO_W,
+ // and is visited as part of the next instruction. Since
+ // it is a jump target, we need to insert a frame here.
+ insertFrame = true;
+ }
+ u += 3;
+ break;
+ }
+ case ClassWriter.ASM_LABELW_INSN: {
+ // replaces the pseudo GOTO_W instruction with a real one.
+ mv.visitJumpInsn(200, labels[offset + readInt(u + 1)]);
+ // The instruction just after is a jump target (because pseudo
+ // GOTO_W are used in patterns IFNOTxxx <L> GOTO_W <l> L:...,
+ // see MethodWriter), so we need to insert a frame here.
+ insertFrame = true;
+ u += 5;
+ break;
+ }
case ClassWriter.WIDE_INSN:
opcode = b[u + 1] & 0xFF;
if (opcode == Opcodes.IINC) {
@@ -1636,8 +1807,8 @@
for (int j = readUnsignedShort(u + 1); j > 0; --j) {
int start = readUnsignedShort(u + 3);
int length = readUnsignedShort(u + 5);
- readLabel(start, context.labels);
- readLabel(start + length, context.labels);
+ createLabel(start, context.labels);
+ createLabel(start + length, context.labels);
u += 6;
}
u += 3;
@@ -1716,8 +1887,8 @@
for (int i = 0; i < n; ++i) {
int start = readUnsignedShort(u);
int length = readUnsignedShort(u + 2);
- context.start[i] = readLabel(start, context.labels);
- context.end[i] = readLabel(start + length, context.labels);
+ context.start[i] = createLabel(start, context.labels);
+ context.end[i] = createLabel(start + length, context.labels);
context.index[i] = readUnsignedShort(u + 4);
u += 6;
}
@@ -2137,7 +2308,7 @@
}
}
frame.offset += delta + 1;
- readLabel(frame.offset, labels);
+ createLabel(frame.offset, labels);
return stackMap;
}
@@ -2190,7 +2361,7 @@
v += 2;
break;
default: // Uninitialized
- frame[index] = readLabel(readUnsignedShort(v), labels);
+ frame[index] = createLabel(readUnsignedShort(v), labels);
v += 2;
}
return v;
@@ -2217,6 +2388,39 @@
}
/**
+ * Creates a label without the Label.DEBUG flag set, for the given offset.
+ * The label is created with a call to {@link #readLabel} and its
+ * Label.DEBUG flag is cleared.
+ *
+ * @param offset
+ * a bytecode offset in a method.
+ * @param labels
+ * the already created labels, indexed by their offset.
+ * @return a Label without the Label.DEBUG flag set.
+ */
+ private Label createLabel(int offset, Label[] labels) {
+ Label label = readLabel(offset, labels);
+ label.status &= ~Label.DEBUG;
+ return label;
+ }
+
+ /**
+ * Creates a label with the Label.DEBUG flag set, if there is no already
+ * existing label for the given offset (otherwise does nothing). The label
+ * is created with a call to {@link #readLabel}.
+ *
+ * @param offset
+ * a bytecode offset in a method.
+ * @param labels
+ * the already created labels, indexed by their offset.
+ */
+ private void createDebugLabel(int offset, Label[] labels) {
+ if (labels[offset] == null) {
+ readLabel(offset, labels).status |= Label.DEBUG;
+ }
+ }
+
+ /**
* Returns the start index of the attribute_info structure of this class.
*
* @return the start index of the attribute_info structure of this class.
@@ -2471,6 +2675,20 @@
}
/**
+ * Read a stringish constant item (CONSTANT_Class, CONSTANT_String,
+ * CONSTANT_MethodType, CONSTANT_Module or CONSTANT_Package
+ * @param index
+ * @param buf
+ * @return
+ */
+ private String readStringish(final int index, final char[] buf) {
+ // computes the start index of the item in b
+ // and reads the CONSTANT_Utf8 item designated by
+ // the first two bytes of this item
+ return readUTF8(items[readUnsignedShort(index)], buf);
+ }
+
+ /**
* Reads a class constant pool item in {@link #b b}. <i>This method is
* intended for {@link Attribute} sub classes, and is normally not needed by
* class generators or adapters.</i>
@@ -2484,44 +2702,41 @@
* @return the String corresponding to the specified class item.
*/
public String readClass(final int index, final char[] buf) {
- // computes the start index of the CONSTANT_Class item in b
- // and reads the CONSTANT_Utf8 item designated by
- // the first two bytes of this CONSTANT_Class item
- return readUTF8(items[readUnsignedShort(index)], buf);
+ return readStringish(index, buf);
}
/**
- * Reads a CONSTANT_Module_info item in {@code b}. This method is intended
- * for {@link Attribute} sub classes, and is normally not needed by class
- * generators or adapters.</i>
+ * Reads a module constant pool item in {@link #b b}. <i>This method is
+ * intended for {@link Attribute} sub classes, and is normally not needed by
+ * class generators or adapters.</i>
*
- * @param index
- * the start index of an unsigned short value in {@link #b b},
- * whose value is the index of a module constant pool item.
- * @param buf
- * buffer to be used to read the item. This buffer must be
- * sufficiently large. It is not automatically resized.
+ * @param index
+ * the start index of an unsigned short value in {@link #b b},
+ * whose value is the index of a module constant pool item.
+ * @param buf
+ * buffer to be used to read the item. This buffer must be
+ * sufficiently large. It is not automatically resized.
* @return the String corresponding to the specified module item.
*/
- public String readModule(int index, char[] buf) {
- return readUTF8(items[readUnsignedShort(index)], buf);
+ public String readModule(final int index, final char[] buf) {
+ return readStringish(index, buf);
}
/**
- * 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.</i>
+ * Reads a module constant pool item in {@link #b b}. <i>This method is
+ * intended for {@link Attribute} sub classes, and is normally not needed by
+ * class generators or adapters.</i>
*
- * @param index
- * the start index of an unsigned short value in {@link #b b},
- * whose value is the index of a package constant pool item.
- * @param buf
- * buffer to be used to read the item. This buffer must be
- * sufficiently large. It is not automatically resized.
- * @return the String corresponding to the specified package item.
+ * @param index
+ * the start index of an unsigned short value in {@link #b b},
+ * whose value is the index of a module constant pool item.
+ * @param buf
+ * buffer to be used to read the item. This buffer must be
+ * sufficiently large. It is not automatically resized.
+ * @return the String corresponding to the specified module item.
*/
- public String readPackage(int index, char[] buf) {
- return readUTF8(items[readUnsignedShort(index)], buf);
+ public String readPackage(final int index, final char[] buf) {
+ return readStringish(index, buf);
}
/**
@@ -2550,8 +2765,6 @@
case ClassWriter.DOUBLE:
return Double.longBitsToDouble(readLong(index));
case ClassWriter.CLASS:
- case ClassWriter.MODULE:
- case ClassWriter.PACKAGE:
return Type.getObjectType(readUTF8(index, buf));
case ClassWriter.STR:
return readUTF8(index, buf);
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassVisitor.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassVisitor.java Wed Nov 08 16:03:35 2017 -0500
@@ -61,7 +61,7 @@
/**
* A visitor to visit a Java class. The methods of this class must be called in
* the following order: <tt>visit</tt> [ <tt>visitSource</tt> ] [
- * <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
+ * <tt>visitModule</tt> ][ <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
* <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* (
* <tt>visitInnerClass</tt> | <tt>visitField</tt> | <tt>visitMethod</tt> )*
* <tt>visitEnd</tt>.
@@ -72,7 +72,7 @@
/**
* The ASM API version implemented by this visitor. The value of this field
- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected final int api;
@@ -87,7 +87,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public ClassVisitor(final int api) {
this(api, null);
@@ -98,13 +98,13 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param cv
* the class visitor to which this visitor must delegate method
* calls. May be null.
*/
public ClassVisitor(final int api, final ClassVisitor cv) {
- if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+ if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
throw new IllegalArgumentException();
}
this.api = api;
@@ -161,6 +161,28 @@
}
/**
+ * Visit the module corresponding to the class.
+ * @param name
+ * module name
+ * @param access
+ * module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC}
+ * and {@code ACC_MANDATED}.
+ * @param version
+ * module version or null.
+ * @return a visitor to visit the module values, or <tt>null</tt> if
+ * this visitor is not interested in visiting this module.
+ */
+ public ModuleVisitor visitModule(String name, int access, String version) {
+ if (api < Opcodes.ASM6) {
+ throw new RuntimeException();
+ }
+ if (cv != null) {
+ return cv.visitModule(name, access, version);
+ }
+ return null;
+ }
+
+ /**
* Visits the enclosing class of the class. This method must be called only
* if the class has an enclosing class.
*
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java Wed Nov 08 16:03:35 2017 -0500
@@ -87,8 +87,8 @@
* {@link MethodVisitor#visitFrame} method are ignored, and the stack map
* frames are recomputed from the methods bytecode. The arguments of the
* {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and
- * recomputed from the bytecode. In other words, computeFrames implies
- * computeMaxs.
+ * recomputed from the bytecode. In other words, COMPUTE_FRAMES implies
+ * COMPUTE_MAXS.
*
* @see #ClassWriter(int)
*/
@@ -197,6 +197,27 @@
static final int WIDE_INSN = 17;
/**
+ * The type of the ASM pseudo instructions with an unsigned 2 bytes offset
+ * label (see Label#resolve).
+ */
+ static final int ASM_LABEL_INSN = 18;
+
+ /**
+ * The type of the ASM pseudo instructions with a 4 bytes offset label.
+ */
+ static final int ASM_LABELW_INSN = 19;
+
+ /**
+ * Represents a frame inserted between already existing frames. This kind of
+ * frame can only be used if the frame content can be computed from the
+ * previous existing frame and from the instructions between this existing
+ * frame and the inserted one, without any knowledge of the type hierarchy.
+ * This kind of frame is only used when an unconditional jump is inserted in
+ * a method while expanding an ASM pseudo instruction (see ClassReader).
+ */
+ static final int F_INSERT = 256;
+
+ /**
* The instruction types of all JVM opcodes.
*/
static final byte[] TYPE;
@@ -284,7 +305,7 @@
/**
* The base value for all CONSTANT_MethodHandle constant pool items.
* Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 9
- * different items.
+ * different items (from 21 to 29).
*/
static final int HANDLE_BASE = 20;
@@ -434,6 +455,11 @@
private ByteVector sourceDebug;
/**
+ * The module attribute of this class.
+ */
+ private ModuleWriter moduleWriter;
+
+ /**
* The constant pool item that contains the name of the enclosing class of
* this class.
*/
@@ -523,25 +549,19 @@
MethodWriter lastMethod;
/**
- * <tt>true</tt> if the maximum stack size and number of local variables
- * must be automatically computed.
+ * Indicates what must be automatically computed.
+ *
+ * @see MethodWriter#compute
*/
- private boolean computeMaxs;
+ private int compute;
/**
- * <tt>true</tt> if the stack map frames must be recomputed from scratch.
+ * <tt>true</tt> if some methods have wide forward jumps using ASM pseudo
+ * instructions, which need to be expanded into sequences of standard
+ * bytecode instructions. In this case the class is re-read and re-written
+ * with a ClassReader -> ClassWriter chain to perform this transformation.
*/
- private boolean computeFrames;
-
- /**
- * <tt>true</tt> if the stack map tables of this class are invalid. The
- * {@link MethodWriter#resizeInstructions} method cannot transform existing
- * stack map tables, and so produces potentially invalid classes when it is
- * executed. In this case the class is reread and rewritten with the
- * {@link #COMPUTE_FRAMES} option (the resizeInstructions method can resize
- * stack map tables when this option is used).
- */
- boolean invalidFrames;
+ boolean hasAsmInsns;
// ------------------------------------------------------------------------
// Static initializer
@@ -552,11 +572,11 @@
*/
static {
int i;
- byte[] b = new byte[220];
+ byte[] b = new byte[221];
String s = "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
+ "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ "AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA"
- + "AAAAGGGGGGGHIFBFAAFFAARQJJKKJJJJJJJJJJJJJJJJJJ";
+ + "AAAAGGGGGGGHIFBFAAFFAARQJJKKSSSSSSSSSSSSSSSSSST";
for (i = 0; i < b.length; ++i) {
b[i] = (byte) (s.charAt(i) - 'A');
}
@@ -610,8 +630,9 @@
// // temporary opcodes used internally by ASM - see Label and
// MethodWriter
// for (i = 202; i < 220; ++i) {
- // b[i] = LABEL_INSN;
+ // b[i] = ASM_LABEL_INSN;
// }
+ // b[220] = ASM_LABELW_INSN;
//
// // LDC(_W) instructions
// b[Constants.LDC] = LDC_INSN;
@@ -644,7 +665,7 @@
* {@link #COMPUTE_FRAMES}.
*/
public ClassWriter(final int flags) {
- super(Opcodes.ASM5);
+ super(Opcodes.ASM6);
index = 1;
pool = new ByteVector();
items = new Item[256];
@@ -653,8 +674,9 @@
key2 = new Item();
key3 = new Item();
key4 = new Item();
- this.computeMaxs = (flags & COMPUTE_MAXS) != 0;
- this.computeFrames = (flags & COMPUTE_FRAMES) != 0;
+ this.compute = (flags & COMPUTE_FRAMES) != 0 ? MethodWriter.FRAMES
+ : ((flags & COMPUTE_MAXS) != 0 ? MethodWriter.MAXS
+ : MethodWriter.NOTHING);
}
/**
@@ -684,9 +706,9 @@
* @param flags
* option flags that can be used to modify the default behavior
* of this class. <i>These option flags do not affect methods
- * that are copied as is in the new class. This means that the
- * maximum stack size nor the stack frames will be computed for
- * these methods</i>. See {@link #COMPUTE_MAXS},
+ * that are copied as is in the new class. This means that
+ * neither the maximum stack size nor the stack frames will be
+ * computed for these methods</i>. See {@link #COMPUTE_MAXS},
* {@link #COMPUTE_FRAMES}.
*/
public ClassWriter(final ClassReader classReader, final int flags) {
@@ -705,9 +727,9 @@
final String[] interfaces) {
this.version = version;
this.access = access;
- this.name = (name == null) ? 0 : newClass(name);
+ this.name = newClass(name);
thisName = name;
- if (ClassReader.SIGNATURES && signature != null) {
+ if (signature != null) {
this.signature = newUTF8(signature);
}
this.superName = superName == null ? 0 : newClass(superName);
@@ -732,6 +754,14 @@
}
@Override
+ public final ModuleVisitor visitModule(final String name,
+ final int access, final String version) {
+ return moduleWriter = new ModuleWriter(this,
+ newModule(name), access,
+ version == null ? 0 : newUTF8(version));
+ }
+
+ @Override
public final void visitOuterClass(final String owner, final String name,
final String desc) {
enclosingMethodOwner = newClass(owner);
@@ -743,9 +773,6 @@
@Override
public final AnnotationVisitor visitAnnotation(final String desc,
final boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write type, and reserve space for values count
bv.putShort(newUTF8(desc)).putShort(0);
@@ -763,9 +790,6 @@
@Override
public final AnnotationVisitor visitTypeAnnotation(int typeRef,
TypePath typePath, final String desc, final boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write target_type and target_info
AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -805,7 +829,7 @@
// and equality tests). If so we store the index of this inner class
// entry (plus one) in intVal. This hack allows duplicate detection in
// O(1) time.
- Item nameItem = newClassItem(name);
+ Item nameItem = newStringishItem(CLASS, name);
if (nameItem.intVal == 0) {
++innerClassesCount;
innerClasses.putShort(nameItem.index);
@@ -830,7 +854,7 @@
public final MethodVisitor visitMethod(final int access, final String name,
final String desc, final String signature, final String[] exceptions) {
return new MethodWriter(this, access, name, desc, signature,
- exceptions, computeMaxs, computeFrames);
+ exceptions, compute);
}
@Override
@@ -874,7 +898,7 @@
size += 8 + bootstrapMethods.length;
newUTF8("BootstrapMethods");
}
- if (ClassReader.SIGNATURES && signature != 0) {
+ if (signature != 0) {
++attributeCount;
size += 8;
newUTF8("Signature");
@@ -912,26 +936,31 @@
size += 8 + innerClasses.length;
newUTF8("InnerClasses");
}
- if (ClassReader.ANNOTATIONS && anns != null) {
+ if (anns != null) {
++attributeCount;
size += 8 + anns.getSize();
newUTF8("RuntimeVisibleAnnotations");
}
- if (ClassReader.ANNOTATIONS && ianns != null) {
+ if (ianns != null) {
++attributeCount;
size += 8 + ianns.getSize();
newUTF8("RuntimeInvisibleAnnotations");
}
- if (ClassReader.ANNOTATIONS && tanns != null) {
+ if (tanns != null) {
++attributeCount;
size += 8 + tanns.getSize();
newUTF8("RuntimeVisibleTypeAnnotations");
}
- if (ClassReader.ANNOTATIONS && itanns != null) {
+ if (itanns != null) {
++attributeCount;
size += 8 + itanns.getSize();
newUTF8("RuntimeInvisibleTypeAnnotations");
}
+ if (moduleWriter != null) {
+ attributeCount += 1 + moduleWriter.attributeCount;
+ size += 6 + moduleWriter.size + moduleWriter.attributesSize;
+ newUTF8("Module");
+ }
if (attrs != null) {
attributeCount += attrs.getCount();
size += attrs.getSize(this, null, 0, -1, -1);
@@ -968,7 +997,7 @@
bootstrapMethodsCount);
out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length);
}
- if (ClassReader.SIGNATURES && signature != 0) {
+ if (signature != 0) {
out.putShort(newUTF8("Signature")).putInt(2).putShort(signature);
}
if (sourceFile != 0) {
@@ -979,6 +1008,11 @@
out.putShort(newUTF8("SourceDebugExtension")).putInt(len);
out.putByteArray(sourceDebug.data, 0, len);
}
+ if (moduleWriter != null) {
+ out.putShort(newUTF8("Module"));
+ moduleWriter.put(out);
+ moduleWriter.putAttributes(out);
+ }
if (enclosingMethodOwner != 0) {
out.putShort(newUTF8("EnclosingMethod")).putInt(4);
out.putShort(enclosingMethodOwner).putShort(enclosingMethod);
@@ -997,41 +1031,46 @@
out.putInt(innerClasses.length + 2).putShort(innerClassesCount);
out.putByteArray(innerClasses.data, 0, innerClasses.length);
}
- if (ClassReader.ANNOTATIONS && anns != null) {
+ if (anns != null) {
out.putShort(newUTF8("RuntimeVisibleAnnotations"));
anns.put(out);
}
- if (ClassReader.ANNOTATIONS && ianns != null) {
+ if (ianns != null) {
out.putShort(newUTF8("RuntimeInvisibleAnnotations"));
ianns.put(out);
}
- if (ClassReader.ANNOTATIONS && tanns != null) {
+ if (tanns != null) {
out.putShort(newUTF8("RuntimeVisibleTypeAnnotations"));
tanns.put(out);
}
- if (ClassReader.ANNOTATIONS && itanns != null) {
+ if (itanns != null) {
out.putShort(newUTF8("RuntimeInvisibleTypeAnnotations"));
itanns.put(out);
}
if (attrs != null) {
attrs.put(this, null, 0, -1, -1, out);
}
- if (invalidFrames) {
+ if (hasAsmInsns) {
+ boolean hasFrames = false;
+ mb = firstMethod;
+ while (mb != null) {
+ hasFrames |= mb.frameCount > 0;
+ mb = (MethodWriter) mb.mv;
+ }
anns = null;
ianns = null;
attrs = null;
- innerClassesCount = 0;
- innerClasses = null;
- bootstrapMethodsCount = 0;
- bootstrapMethods = null;
+ moduleWriter = null;
firstField = null;
lastField = null;
firstMethod = null;
lastMethod = null;
- computeMaxs = false;
- computeFrames = true;
- invalidFrames = false;
- new ClassReader(out.data).accept(this, ClassReader.SKIP_FRAMES);
+ compute =
+ hasFrames ? MethodWriter.INSERTED_FRAMES : MethodWriter.NOTHING;
+ hasAsmInsns = false;
+ new ClassReader(out.data).accept(this,
+ (hasFrames ? ClassReader.EXPAND_FRAMES : 0)
+ | ClassReader.EXPAND_ASM_INSNS);
return toByteArray();
}
return out.data;
@@ -1078,16 +1117,16 @@
double val = ((Double) cst).doubleValue();
return newDouble(val);
} else if (cst instanceof String) {
- return newString((String) cst);
+ return newStringishItem(STR, (String) cst);
} else if (cst instanceof Type) {
Type t = (Type) cst;
int s = t.getSort();
if (s == Type.OBJECT) {
- return newClassItem(t.getInternalName());
+ return newStringishItem(CLASS, t.getInternalName());
} else if (s == Type.METHOD) {
- return newMethodTypeItem(t.getDescriptor());
+ return newStringishItem(MTYPE, t.getDescriptor());
} else { // s == primitive type or array
- return newClassItem(t.getDescriptor());
+ return newStringishItem(CLASS, t.getDescriptor());
}
} else if (cst instanceof Handle) {
Handle h = (Handle) cst;
@@ -1136,20 +1175,21 @@
}
/**
- * Adds a class reference to the constant pool of the class being build.
+ * Adds a string reference, a class reference, a method type, a module
+ * or a package to the constant pool of the class being build.
* Does nothing if the constant pool already contains a similar item.
- * <i>This method is intended for {@link Attribute} sub classes, and is
- * normally not needed by class generators or adapters.</i>
*
+ * @param type
+ * a type among STR, CLASS, MTYPE, MODULE or PACKAGE
* @param value
- * the internal name of the class.
- * @return a new or already existing class reference item.
+ * string value of the reference.
+ * @return a new or already existing reference item.
*/
- Item newClassItem(final String value) {
- key2.set(CLASS, value, null, null);
+ Item newStringishItem(final int type, final String value) {
+ key2.set(type, value, null, null);
Item result = get(key2);
if (result == null) {
- pool.put12(CLASS, newUTF8(value));
+ pool.put12(type, newUTF8(value));
result = new Item(index++, key2);
put(result);
}
@@ -1167,72 +1207,7 @@
* @return the index of a new or already existing class reference item.
*/
public int newClass(final String value) {
- return newClassItem(value).index;
- }
-
- /**
- * Adds a module name to the constant pool.
- *
- * Does nothing if the constant pool already contains a similar item.
- * <i>This method is intended for {@link Attribute} sub classes, and is
- * normally not needed by class generators or adapters.</i>
- *
- * @param value
- * the module name
- * @return the index of a new or already existing module reference item.
- */
- public int newModule(String value) {
- key2.set(MODULE, value, null, null);
- Item result = get(key2);
- if (result == null) {
- pool.put12(MODULE, newUTF8(value));
- result = new Item(index++, key2);
- put(result);
- }
- return result.index;
- }
-
- /**
- * Adds a package name to the constant pool.
- *
- * Does nothing if the constant pool already contains a similar item.
- * <i>This method is intended for {@link Attribute} sub classes, and is
- * normally not needed by class generators or adapters.</i>
- *
- * @param value
- * the internal name of the package.
- * @return the index of a new or already existing package reference item.
- */
- public int newPackage(String value) {
- key2.set(PACKAGE, value, null, null);
- Item result = get(key2);
- if (result == null) {
- pool.put12(PACKAGE, newUTF8(value));
- result = new Item(index++, key2);
- put(result);
- }
- return result.index;
- }
-
- /**
- * Adds a method type reference to the constant pool of the class being
- * build. Does nothing if the constant pool already contains a similar item.
- * <i>This method is intended for {@link Attribute} sub classes, and is
- * normally not needed by class generators or adapters.</i>
- *
- * @param methodDesc
- * method descriptor of the method type.
- * @return a new or already existing method type reference item.
- */
- Item newMethodTypeItem(final String methodDesc) {
- key2.set(MTYPE, methodDesc, null, null);
- Item result = get(key2);
- if (result == null) {
- pool.put12(MTYPE, newUTF8(methodDesc));
- result = new Item(index++, key2);
- put(result);
- }
- return result;
+ return newStringishItem(CLASS, value).index;
}
/**
@@ -1247,7 +1222,37 @@
* item.
*/
public int newMethodType(final String methodDesc) {
- return newMethodTypeItem(methodDesc).index;
+ return newStringishItem(MTYPE, methodDesc).index;
+ }
+
+ /**
+ * Adds a module reference to the constant pool of the class being
+ * build. Does nothing if the constant pool already contains a similar item.
+ * <i>This method is intended for {@link Attribute} sub classes, and is
+ * normally not needed by class generators or adapters.</i>
+ *
+ * @param moduleName
+ * name of the module.
+ * @return the index of a new or already existing module reference
+ * item.
+ */
+ public int newModule(final String moduleName) {
+ return newStringishItem(MODULE, moduleName).index;
+ }
+
+ /**
+ * Adds a package reference to the constant pool of the class being
+ * build. Does nothing if the constant pool already contains a similar item.
+ * <i>This method is intended for {@link Attribute} sub classes, and is
+ * normally not needed by class generators or adapters.</i>
+ *
+ * @param packageName
+ * name of the package in its internal form.
+ * @return the index of a new or already existing module reference
+ * item.
+ */
+ public int newPackage(final String packageName) {
+ return newStringishItem(PACKAGE, packageName).index;
}
/**
@@ -1629,25 +1634,6 @@
}
/**
- * Adds a string to the constant pool of the class being build. Does nothing
- * if the constant pool already contains a similar item.
- *
- * @param value
- * the String value.
- * @return a new or already existing string item.
- */
- private Item newString(final String value) {
- key2.set(STR, value, null, null);
- Item result = get(key2);
- if (result == null) {
- pool.put12(STR, newUTF8(value));
- result = new Item(index++, key2);
- put(result);
- }
- return result;
- }
-
- /**
* Adds a name and type to the constant pool of the class being build. Does
* nothing if the constant pool already contains a similar item. <i>This
* method is intended for {@link Attribute} sub classes, and is normally not
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/CurrentFrame.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm;
+
+/**
+ * Information about the input stack map frame at the "current" instruction of a
+ * method. This is implemented as a Frame subclass for a "basic block"
+ * containing only one instruction.
+ *
+ * @author Eric Bruneton
+ */
+class CurrentFrame extends Frame {
+
+ /**
+ * Sets this CurrentFrame to the input stack map frame of the next "current"
+ * instruction, i.e. the instruction just after the given one. It is assumed
+ * that the value of this object when this method is called is the stack map
+ * frame status just before the given instruction is executed.
+ */
+ @Override
+ void execute(int opcode, int arg, ClassWriter cw, Item item) {
+ super.execute(opcode, arg, cw, item);
+ Frame successor = new Frame();
+ merge(cw, successor, 0);
+ set(successor);
+ owner.inputStackTop = 0;
+ }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldVisitor.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldVisitor.java Wed Nov 08 16:03:35 2017 -0500
@@ -69,7 +69,7 @@
/**
* The ASM API version implemented by this visitor. The value of this field
- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected final int api;
@@ -84,7 +84,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public FieldVisitor(final int api) {
this(api, null);
@@ -95,13 +95,13 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param fv
* the field visitor to which this visitor must delegate method
* calls. May be null.
*/
public FieldVisitor(final int api, final FieldVisitor fv) {
- if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+ if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
throw new IllegalArgumentException();
}
this.api = api;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldWriter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldWriter.java Wed Nov 08 16:03:35 2017 -0500
@@ -147,7 +147,7 @@
*/
FieldWriter(final ClassWriter cw, final int access, final String name,
final String desc, final String signature, final Object value) {
- super(Opcodes.ASM5);
+ super(Opcodes.ASM6);
if (cw.firstField == null) {
cw.firstField = this;
} else {
@@ -158,7 +158,7 @@
this.access = access;
this.name = cw.newUTF8(name);
this.desc = cw.newUTF8(desc);
- if (ClassReader.SIGNATURES && signature != null) {
+ if (signature != null) {
this.signature = cw.newUTF8(signature);
}
if (value != null) {
@@ -173,9 +173,6 @@
@Override
public AnnotationVisitor visitAnnotation(final String desc,
final boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write type, and reserve space for values count
bv.putShort(cw.newUTF8(desc)).putShort(0);
@@ -193,9 +190,6 @@
@Override
public AnnotationVisitor visitTypeAnnotation(final int typeRef,
final TypePath typePath, final String desc, final boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write target_type and target_info
AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -249,23 +243,23 @@
cw.newUTF8("Deprecated");
size += 6;
}
- if (ClassReader.SIGNATURES && signature != 0) {
+ if (signature != 0) {
cw.newUTF8("Signature");
size += 8;
}
- if (ClassReader.ANNOTATIONS && anns != null) {
+ if (anns != null) {
cw.newUTF8("RuntimeVisibleAnnotations");
size += 8 + anns.getSize();
}
- if (ClassReader.ANNOTATIONS && ianns != null) {
+ if (ianns != null) {
cw.newUTF8("RuntimeInvisibleAnnotations");
size += 8 + ianns.getSize();
}
- if (ClassReader.ANNOTATIONS && tanns != null) {
+ if (tanns != null) {
cw.newUTF8("RuntimeVisibleTypeAnnotations");
size += 8 + tanns.getSize();
}
- if (ClassReader.ANNOTATIONS && itanns != null) {
+ if (itanns != null) {
cw.newUTF8("RuntimeInvisibleTypeAnnotations");
size += 8 + itanns.getSize();
}
@@ -299,19 +293,19 @@
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
++attributeCount;
}
- if (ClassReader.SIGNATURES && signature != 0) {
+ if (signature != 0) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && anns != null) {
+ if (anns != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && ianns != null) {
+ if (ianns != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && tanns != null) {
+ if (tanns != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && itanns != null) {
+ if (itanns != null) {
++attributeCount;
}
if (attrs != null) {
@@ -331,23 +325,23 @@
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
out.putShort(cw.newUTF8("Deprecated")).putInt(0);
}
- if (ClassReader.SIGNATURES && signature != 0) {
+ if (signature != 0) {
out.putShort(cw.newUTF8("Signature"));
out.putInt(2).putShort(signature);
}
- if (ClassReader.ANNOTATIONS && anns != null) {
+ if (anns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
anns.put(out);
}
- if (ClassReader.ANNOTATIONS && ianns != null) {
+ if (ianns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
ianns.put(out);
}
- if (ClassReader.ANNOTATIONS && tanns != null) {
+ if (tanns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
tanns.put(out);
}
- if (ClassReader.ANNOTATIONS && itanns != null) {
+ if (itanns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
itanns.put(out);
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Frame.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Frame.java Wed Nov 08 16:03:35 2017 -0500
@@ -63,7 +63,7 @@
*
* @author Eric Bruneton
*/
-final class Frame {
+class Frame {
/*
* Frames are computed in a two steps process: during the visit of each
@@ -525,7 +525,7 @@
* When the stack map frames are completely computed, this field is the
* actual number of types in {@link #outputStack}.
*/
- private int outputStackTop;
+ int outputStackTop;
/**
* Number of types that are initialized in the basic block.
@@ -550,6 +550,110 @@
private int[] initializations;
/**
+ * Sets this frame to the given value.
+ *
+ * @param cw
+ * the ClassWriter to which this label belongs.
+ * @param nLocal
+ * the number of local variables.
+ * @param local
+ * the local variable types. Primitive types are represented by
+ * {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
+ * {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+ * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
+ * {@link Opcodes#UNINITIALIZED_THIS} (long and double are
+ * represented by a single element). Reference types are
+ * represented by String objects (representing internal names),
+ * and uninitialized types by Label objects (this label
+ * designates the NEW instruction that created this uninitialized
+ * value).
+ * @param nStack
+ * the number of operand stack elements.
+ * @param stack
+ * the operand stack types (same format as the "local" array).
+ */
+ final void set(ClassWriter cw, final int nLocal, final Object[] local,
+ final int nStack, final Object[] stack) {
+ int i = convert(cw, nLocal, local, inputLocals);
+ while (i < local.length) {
+ inputLocals[i++] = TOP;
+ }
+ int nStackTop = 0;
+ for (int j = 0; j < nStack; ++j) {
+ if (stack[j] == Opcodes.LONG || stack[j] == Opcodes.DOUBLE) {
+ ++nStackTop;
+ }
+ }
+ inputStack = new int[nStack + nStackTop];
+ convert(cw, nStack, stack, inputStack);
+ outputStackTop = 0;
+ initializationCount = 0;
+ }
+
+ /**
+ * Converts types from the MethodWriter.visitFrame() format to the Frame
+ * format.
+ *
+ * @param cw
+ * the ClassWriter to which this label belongs.
+ * @param nInput
+ * the number of types to convert.
+ * @param input
+ * the types to convert. Primitive types are represented by
+ * {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
+ * {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+ * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
+ * {@link Opcodes#UNINITIALIZED_THIS} (long and double are
+ * represented by a single element). Reference types are
+ * represented by String objects (representing internal names),
+ * and uninitialized types by Label objects (this label
+ * designates the NEW instruction that created this uninitialized
+ * value).
+ * @param output
+ * where to store the converted types.
+ * @return the number of output elements.
+ */
+ private static int convert(ClassWriter cw, int nInput, Object[] input,
+ int[] output) {
+ int i = 0;
+ for (int j = 0; j < nInput; ++j) {
+ if (input[j] instanceof Integer) {
+ output[i++] = BASE | ((Integer) input[j]).intValue();
+ if (input[j] == Opcodes.LONG || input[j] == Opcodes.DOUBLE) {
+ output[i++] = TOP;
+ }
+ } else if (input[j] instanceof String) {
+ output[i++] = type(cw, Type.getObjectType((String) input[j])
+ .getDescriptor());
+ } else {
+ output[i++] = UNINITIALIZED
+ | cw.addUninitializedType("",
+ ((Label) input[j]).position);
+ }
+ }
+ return i;
+ }
+
+ /**
+ * Sets this frame to the value of the given frame. WARNING: after this
+ * method is called the two frames share the same data structures. It is
+ * recommended to discard the given frame f to avoid unexpected side
+ * effects.
+ *
+ * @param f
+ * The new frame value.
+ */
+ final void set(final Frame f) {
+ inputLocals = f.inputLocals;
+ inputStack = f.inputStack;
+ outputLocals = f.outputLocals;
+ outputStack = f.outputStack;
+ outputStackTop = f.outputStackTop;
+ initializationCount = f.initializationCount;
+ initializations = f.initializations;
+ }
+
+ /**
* Returns the output frame local variable type at the given index.
*
* @param local
@@ -614,7 +718,7 @@
}
// pushes the type on the output stack
outputStack[outputStackTop++] = type;
- // updates the maximun height reached by the output stack, if needed
+ // updates the maximum height reached by the output stack, if needed
int top = owner.inputStackTop + outputStackTop;
if (top > owner.outputStackMax) {
owner.outputStackMax = top;
@@ -650,7 +754,7 @@
* a type descriptor.
* @return the int encoding of the given type.
*/
- private static int type(final ClassWriter cw, final String desc) {
+ static int type(final ClassWriter cw, final String desc) {
String t;
int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
switch (desc.charAt(index)) {
@@ -838,7 +942,7 @@
* @param maxLocals
* the maximum number of local variables of this method.
*/
- void initInputFrame(final ClassWriter cw, final int access,
+ final void initInputFrame(final ClassWriter cw, final int access,
final Type[] args, final int maxLocals) {
inputLocals = new int[maxLocals];
inputStack = new int[0];
@@ -981,7 +1085,7 @@
case Opcodes.AALOAD:
pop(1);
t1 = pop();
- push(ELEMENT_OF + t1);
+ push(t1 == NULL ? t1 : ELEMENT_OF + t1);
break;
case Opcodes.ISTORE:
case Opcodes.FSTORE:
@@ -1312,7 +1416,7 @@
* @return <tt>true</tt> if the input frame of the given label has been
* changed by this operation.
*/
- boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
+ final boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
boolean changed = false;
int i, s, dim, kind, t;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Item.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Item.java Wed Nov 08 16:03:35 2017 -0500
@@ -80,6 +80,7 @@
* {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
* {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
* {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
+ * {@link ClassWriter#MODULE}, {@link ClassWriter#PACKAGE},
* {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
*
* MethodHandle constant 9 variations are stored using a range of 9 values
@@ -239,12 +240,12 @@
this.strVal3 = strVal3;
switch (type) {
case ClassWriter.CLASS:
- case ClassWriter.MODULE:
- case ClassWriter.PACKAGE:
this.intVal = 0; // intVal of a class must be zero, see visitInnerClass
case ClassWriter.UTF8:
case ClassWriter.STR:
case ClassWriter.MTYPE:
+ case ClassWriter.MODULE:
+ case ClassWriter.PACKAGE:
case ClassWriter.TYPE_NORMAL:
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
return;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Label.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Label.java Wed Nov 08 16:03:35 2017 -0500
@@ -389,13 +389,12 @@
* the position of this label in the bytecode.
* @param data
* the bytecode of the method.
- * @return <tt>true</tt> if a blank that was left for this label was to
+ * @return <tt>true</tt> if a blank that was left for this label was too
* small to store the offset. In such a case the corresponding jump
* instruction is replaced with a pseudo instruction (using unused
* opcodes) using an unsigned two bytes offset. These pseudo
- * instructions will need to be replaced with true instructions with
- * wider offsets (4 bytes instead of 2). This is done in
- * {@link MethodWriter#resizeInstructions}.
+ * instructions will be replaced with standard bytecode instructions
+ * with wider offsets (4 bytes instead of 2), in ClassReader.
* @throws IllegalArgumentException
* if this label has already been resolved, or if it has not
* been created by the given code writer.
@@ -454,7 +453,7 @@
* @return the first label of the series to which this label belongs.
*/
Label getFirst() {
- return !ClassReader.FRAMES || frame == null ? this : frame.owner;
+ return frame == null ? this : frame.owner;
}
// ------------------------------------------------------------------------
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java Wed Nov 08 16:03:35 2017 -0500
@@ -86,7 +86,7 @@
/**
* The ASM API version implemented by this visitor. The value of this field
- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected final int api;
@@ -101,7 +101,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public MethodVisitor(final int api) {
this(api, null);
@@ -112,13 +112,13 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param mv
* the method visitor to which this visitor must delegate method
* calls. May be null.
*/
public MethodVisitor(final int api, final MethodVisitor mv) {
- if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+ if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
throw new IllegalArgumentException();
}
this.api = api;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java Wed Nov 08 16:03:35 2017 -0500
@@ -128,7 +128,19 @@
*
* @see #compute
*/
- private static final int FRAMES = 0;
+ static final int FRAMES = 0;
+
+ /**
+ * Indicates that the stack map frames of type F_INSERT must be computed.
+ * The other frames are not (re)computed. They should all be of type F_NEW
+ * and should be sufficient to compute the content of the F_INSERT frames,
+ * together with the bytecode instructions between a F_NEW and a F_INSERT
+ * frame - and without any knowledge of the type hierarchy (by definition of
+ * F_INSERT).
+ *
+ * @see #compute
+ */
+ static final int INSERTED_FRAMES = 1;
/**
* Indicates that the maximum stack size and number of local variables must
@@ -136,14 +148,14 @@
*
* @see #compute
*/
- private static final int MAXS = 1;
+ static final int MAXS = 2;
/**
* Indicates that nothing must be automatically computed.
*
* @see #compute
*/
- private static final int NOTHING = 2;
+ static final int NOTHING = 3;
/**
* The class writer to which this method must be added.
@@ -277,7 +289,7 @@
/**
* Number of stack map frames in the StackMapTable attribute.
*/
- private int frameCount;
+ int frameCount;
/**
* The StackMapTable attribute.
@@ -384,11 +396,6 @@
private Attribute cattrs;
/**
- * Indicates if some jump instructions are too small and need to be resized.
- */
- private boolean resize;
-
- /**
* The number of subroutines in this method.
*/
private int subroutines;
@@ -409,6 +416,7 @@
* Indicates what must be automatically computed.
*
* @see #FRAMES
+ * @see #INSERTED_FRAMES
* @see #MAXS
* @see #NOTHING
*/
@@ -471,18 +479,13 @@
* @param exceptions
* the internal names of the method's exceptions. May be
* <tt>null</tt>.
- * @param computeMaxs
- * <tt>true</tt> if the maximum stack size and number of local
- * variables must be automatically computed.
- * @param computeFrames
- * <tt>true</tt> if the stack map tables must be recomputed from
- * scratch.
+ * @param compute
+ * Indicates what must be automatically computed (see #compute).
*/
MethodWriter(final ClassWriter cw, final int access, final String name,
final String desc, final String signature,
- final String[] exceptions, final boolean computeMaxs,
- final boolean computeFrames) {
- super(Opcodes.ASM5);
+ final String[] exceptions, final int compute) {
+ super(Opcodes.ASM6);
if (cw.firstMethod == null) {
cw.firstMethod = this;
} else {
@@ -497,9 +500,7 @@
this.name = cw.newUTF8(name);
this.desc = cw.newUTF8(desc);
this.descriptor = desc;
- if (ClassReader.SIGNATURES) {
- this.signature = signature;
- }
+ this.signature = signature;
if (exceptions != null && exceptions.length > 0) {
exceptionCount = exceptions.length;
this.exceptions = new int[exceptionCount];
@@ -507,8 +508,8 @@
this.exceptions[i] = cw.newClass(exceptions[i]);
}
}
- this.compute = computeFrames ? FRAMES : (computeMaxs ? MAXS : NOTHING);
- if (computeMaxs || computeFrames) {
+ this.compute = compute;
+ if (compute != NOTHING) {
// updates maxLocals
int size = Type.getArgumentsAndReturnSizes(descriptor) >> 2;
if ((access & Opcodes.ACC_STATIC) != 0) {
@@ -539,9 +540,6 @@
@Override
public AnnotationVisitor visitAnnotationDefault() {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
annd = new ByteVector();
return new AnnotationWriter(cw, false, annd, null, 0);
}
@@ -549,9 +547,6 @@
@Override
public AnnotationVisitor visitAnnotation(final String desc,
final boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write type, and reserve space for values count
bv.putShort(cw.newUTF8(desc)).putShort(0);
@@ -569,9 +564,6 @@
@Override
public AnnotationVisitor visitTypeAnnotation(final int typeRef,
final TypePath typePath, final String desc, final boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write target_type and target_info
AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -592,9 +584,6 @@
@Override
public AnnotationVisitor visitParameterAnnotation(final int parameter,
final String desc, final boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
if ("Ljava/lang/Synthetic;".equals(desc)) {
// workaround for a bug in javac with synthetic parameters
@@ -639,11 +628,33 @@
@Override
public void visitFrame(final int type, final int nLocal,
final Object[] local, final int nStack, final Object[] stack) {
- if (!ClassReader.FRAMES || compute == FRAMES) {
+ if (compute == FRAMES) {
return;
}
- if (type == Opcodes.F_NEW) {
+ if (compute == INSERTED_FRAMES) {
+ if (currentBlock.frame == null) {
+ // This should happen only once, for the implicit first frame
+ // (which is explicitly visited in ClassReader if the
+ // EXPAND_ASM_INSNS option is used).
+ currentBlock.frame = new CurrentFrame();
+ currentBlock.frame.owner = currentBlock;
+ currentBlock.frame.initInputFrame(cw, access,
+ Type.getArgumentTypes(descriptor), nLocal);
+ visitImplicitFirstFrame();
+ } else {
+ if (type == Opcodes.F_NEW) {
+ currentBlock.frame.set(cw, nLocal, local, nStack, stack);
+ } else {
+ // In this case type is equal to F_INSERT by hypothesis, and
+ // currentBlock.frame contains the stack map frame at the
+ // current instruction, computed from the last F_NEW frame
+ // and the bytecode instructions in between (via calls to
+ // CurrentFrame#execute).
+ }
+ visitFrame(currentBlock.frame);
+ }
+ } else if (type == Opcodes.F_NEW) {
if (previousFrame == null) {
visitImplicitFirstFrame();
}
@@ -651,10 +662,10 @@
int frameIndex = startFrame(code.length, nLocal, nStack);
for (int i = 0; i < nLocal; ++i) {
if (local[i] instanceof String) {
- frame[frameIndex++] = Frame.OBJECT
- | cw.addType((String) local[i]);
+ String desc = Type.getObjectType((String) local[i]).getDescriptor();
+ frame[frameIndex++] = Frame.type(cw, desc);
} else if (local[i] instanceof Integer) {
- frame[frameIndex++] = ((Integer) local[i]).intValue();
+ frame[frameIndex++] = Frame.BASE | ((Integer) local[i]).intValue();
} else {
frame[frameIndex++] = Frame.UNINITIALIZED
| cw.addUninitializedType("",
@@ -663,10 +674,10 @@
}
for (int i = 0; i < nStack; ++i) {
if (stack[i] instanceof String) {
- frame[frameIndex++] = Frame.OBJECT
- | cw.addType((String) stack[i]);
+ String desc = Type.getObjectType((String) stack[i]).getDescriptor();
+ frame[frameIndex++] = Frame.type(cw, desc);
} else if (stack[i] instanceof Integer) {
- frame[frameIndex++] = ((Integer) stack[i]).intValue();
+ frame[frameIndex++] = Frame.BASE | ((Integer) stack[i]).intValue();
} else {
frame[frameIndex++] = Frame.UNINITIALIZED
| cw.addUninitializedType("",
@@ -747,7 +758,7 @@
// update currentBlock
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(opcode, 0, null, null);
} else {
// updates current and max stack sizes
@@ -770,7 +781,7 @@
lastCodeOffset = code.length;
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(opcode, operand, null, null);
} else if (opcode != Opcodes.NEWARRAY) {
// updates current and max stack sizes only for NEWARRAY
@@ -795,7 +806,7 @@
lastCodeOffset = code.length;
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(opcode, var, null, null);
} else {
// updates current and max stack sizes
@@ -852,10 +863,10 @@
@Override
public void visitTypeInsn(final int opcode, final String type) {
lastCodeOffset = code.length;
- Item i = cw.newClassItem(type);
+ Item i = cw.newStringishItem(ClassWriter.CLASS, type);
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(opcode, code.length, cw, i);
} else if (opcode == Opcodes.NEW) {
// updates current and max stack sizes only if opcode == NEW
@@ -878,7 +889,7 @@
Item i = cw.newFieldItem(owner, name, desc);
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(opcode, 0, cw, i);
} else {
int size;
@@ -918,7 +929,7 @@
int argSize = i.intVal;
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(opcode, 0, cw, i);
} else {
/*
@@ -970,7 +981,7 @@
int argSize = i.intVal;
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(Opcodes.INVOKEDYNAMIC, 0, cw, i);
} else {
/*
@@ -1004,7 +1015,9 @@
}
@Override
- public void visitJumpInsn(final int opcode, final Label label) {
+ public void visitJumpInsn(int opcode, final Label label) {
+ boolean isWide = opcode >= 200; // GOTO_W
+ opcode = isWide ? opcode - 33 : opcode;
lastCodeOffset = code.length;
Label nextInsn = null;
// Label currentBlock = this.currentBlock;
@@ -1019,6 +1032,8 @@
// creates a Label for the next basic block
nextInsn = new Label();
}
+ } else if (compute == INSERTED_FRAMES) {
+ currentBlock.frame.execute(opcode, 0, null, null);
} else {
if (opcode == Opcodes.JSR) {
if ((label.status & Label.SUBROUTINE) == 0) {
@@ -1050,8 +1065,8 @@
/*
* case of a backward jump with an offset < -32768. In this case we
* automatically replace GOTO with GOTO_W, JSR with JSR_W and IFxxx
- * <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is the
- * "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) and where <l'>
+ * <l> with IFNOTxxx <L> GOTO_W <l> L:..., where IFNOTxxx is the
+ * "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) and where <L>
* designates the instruction just after the GOTO_W.
*/
if (opcode == Opcodes.GOTO) {
@@ -1067,9 +1082,21 @@
code.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
: opcode ^ 1);
code.putShort(8); // jump offset
- code.putByte(200); // GOTO_W
+ // ASM pseudo GOTO_W insn, see ClassReader. We don't use a real
+ // GOTO_W because we might need to insert a frame just after (as
+ // the target of the IFNOTxxx jump instruction).
+ code.putByte(220);
+ cw.hasAsmInsns = true;
}
label.put(this, code, code.length - 1, true);
+ } else if (isWide) {
+ /*
+ * case of a GOTO_W or JSR_W specified by the user (normally
+ * ClassReader when used to resize instructions). In this case we
+ * keep the original instruction.
+ */
+ code.putByte(opcode + 33);
+ label.put(this, code, code.length - 1, true);
} else {
/*
* case of a backward jump with an offset >= -32768, or of a forward
@@ -1097,7 +1124,7 @@
@Override
public void visitLabel(final Label label) {
// resolves previous forward references to label, if any
- resize |= label.resolve(this, code.length, code.data);
+ cw.hasAsmInsns |= label.resolve(this, code.length, code.data);
// updates currentBlock
if ((label.status & Label.DEBUG) != 0) {
return;
@@ -1130,6 +1157,18 @@
previousBlock.successor = label;
}
previousBlock = label;
+ } else if (compute == INSERTED_FRAMES) {
+ if (currentBlock == null) {
+ // This case should happen only once, for the visitLabel call in
+ // the constructor. Indeed, if compute is equal to
+ // INSERTED_FRAMES currentBlock can not be set back to null (see
+ // #noSuccessor).
+ currentBlock = label;
+ } else {
+ // Updates the frame owner so that a correct frame offset is
+ // computed in visitFrame(Frame).
+ currentBlock.frame.owner = label;
+ }
} else if (compute == MAXS) {
if (currentBlock != null) {
// ends current block (with one new successor)
@@ -1155,7 +1194,7 @@
Item i = cw.newConstItem(cst);
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(Opcodes.LDC, 0, cw, i);
} else {
int size;
@@ -1187,7 +1226,7 @@
public void visitIincInsn(final int var, final int increment) {
lastCodeOffset = code.length;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(Opcodes.IINC, var, null, null);
}
}
@@ -1271,10 +1310,10 @@
@Override
public void visitMultiANewArrayInsn(final String desc, final int dims) {
lastCodeOffset = code.length;
- Item i = cw.newClassItem(desc);
+ Item i = cw.newStringishItem(ClassWriter.CLASS, desc);
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(Opcodes.MULTIANEWARRAY, dims, cw, i);
} else {
// updates current stack size (max stack size unchanged because
@@ -1289,9 +1328,6 @@
@Override
public AnnotationVisitor visitInsnAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write target_type and target_info
typeRef = (typeRef & 0xFF0000FF) | (lastCodeOffset << 8);
@@ -1331,9 +1367,6 @@
@Override
public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write target_type and target_info
AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -1387,9 +1420,6 @@
public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
TypePath typePath, Label[] start, Label[] end, int[] index,
String desc, boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write target_type and target_info
bv.putByte(typeRef >>> 24).putShort(start.length);
@@ -1430,15 +1460,7 @@
@Override
public void visitMaxs(final int maxStack, final int maxLocals) {
- if (resize) {
- // replaces the temporary jump opcodes introduced by Label.resolve.
- if (ClassReader.RESIZE) {
- resizeInstructions();
- } else {
- throw new RuntimeException("Method code too large!");
- }
- }
- if (ClassReader.FRAMES && compute == FRAMES) {
+ if (compute == FRAMES) {
// completes the control flow graph with exception handler blocks
Handler handler = firstHandler;
while (handler != null) {
@@ -1468,8 +1490,8 @@
// creates and visits the first (implicit) frame
Frame f = labels.frame;
- Type[] args = Type.getArgumentTypes(descriptor);
- f.initInputFrame(cw, access, args, this.maxLocals);
+ f.initInputFrame(cw, access, Type.getArgumentTypes(descriptor),
+ this.maxLocals);
visitFrame(f);
/*
@@ -1717,7 +1739,9 @@
} else {
currentBlock.outputStackMax = maxStackSize;
}
- currentBlock = null;
+ if (compute != INSERTED_FRAMES) {
+ currentBlock = null;
+ }
}
// ------------------------------------------------------------------------
@@ -1789,7 +1813,7 @@
if ((access & ACC_CONSTRUCTOR) == 0) {
frame[frameIndex++] = Frame.OBJECT | cw.addType(cw.thisName);
} else {
- frame[frameIndex++] = 6; // Opcodes.UNINITIALIZED_THIS;
+ frame[frameIndex++] = Frame.UNINITIALIZED_THIS;
}
}
int i = 1;
@@ -1801,16 +1825,16 @@
case 'B':
case 'S':
case 'I':
- frame[frameIndex++] = 1; // Opcodes.INTEGER;
+ frame[frameIndex++] = Frame.INTEGER;
break;
case 'F':
- frame[frameIndex++] = 2; // Opcodes.FLOAT;
+ frame[frameIndex++] = Frame.FLOAT;
break;
case 'J':
- frame[frameIndex++] = 4; // Opcodes.LONG;
+ frame[frameIndex++] = Frame.LONG;
break;
case 'D':
- frame[frameIndex++] = 3; // Opcodes.DOUBLE;
+ frame[frameIndex++] = Frame.DOUBLE;
break;
case '[':
while (descriptor.charAt(i) == '[') {
@@ -1822,8 +1846,7 @@
++i;
}
}
- frame[frameIndex++] = Frame.OBJECT
- | cw.addType(descriptor.substring(j, ++i));
+ frame[frameIndex++] = Frame.type(cw, descriptor.substring(j, ++i));
break;
case 'L':
while (descriptor.charAt(i) != ';') {
@@ -2083,11 +2106,11 @@
cw.newUTF8(zip ? "StackMapTable" : "StackMap");
size += 8 + stackMap.length;
}
- if (ClassReader.ANNOTATIONS && ctanns != null) {
+ if (ctanns != null) {
cw.newUTF8("RuntimeVisibleTypeAnnotations");
size += 8 + ctanns.getSize();
}
- if (ClassReader.ANNOTATIONS && ictanns != null) {
+ if (ictanns != null) {
cw.newUTF8("RuntimeInvisibleTypeAnnotations");
size += 8 + ictanns.getSize();
}
@@ -2111,7 +2134,7 @@
cw.newUTF8("Deprecated");
size += 6;
}
- if (ClassReader.SIGNATURES && signature != null) {
+ if (signature != null) {
cw.newUTF8("Signature");
cw.newUTF8(signature);
size += 8;
@@ -2120,34 +2143,34 @@
cw.newUTF8("MethodParameters");
size += 7 + methodParameters.length;
}
- if (ClassReader.ANNOTATIONS && annd != null) {
+ if (annd != null) {
cw.newUTF8("AnnotationDefault");
size += 6 + annd.length;
}
- if (ClassReader.ANNOTATIONS && anns != null) {
+ if (anns != null) {
cw.newUTF8("RuntimeVisibleAnnotations");
size += 8 + anns.getSize();
}
- if (ClassReader.ANNOTATIONS && ianns != null) {
+ if (ianns != null) {
cw.newUTF8("RuntimeInvisibleAnnotations");
size += 8 + ianns.getSize();
}
- if (ClassReader.ANNOTATIONS && tanns != null) {
+ if (tanns != null) {
cw.newUTF8("RuntimeVisibleTypeAnnotations");
size += 8 + tanns.getSize();
}
- if (ClassReader.ANNOTATIONS && itanns != null) {
+ if (itanns != null) {
cw.newUTF8("RuntimeInvisibleTypeAnnotations");
size += 8 + itanns.getSize();
}
- if (ClassReader.ANNOTATIONS && panns != null) {
+ if (panns != null) {
cw.newUTF8("RuntimeVisibleParameterAnnotations");
size += 7 + 2 * (panns.length - synthetics);
for (int i = panns.length - 1; i >= synthetics; --i) {
size += panns[i] == null ? 0 : panns[i].getSize();
}
}
- if (ClassReader.ANNOTATIONS && ipanns != null) {
+ if (ipanns != null) {
cw.newUTF8("RuntimeInvisibleParameterAnnotations");
size += 7 + 2 * (ipanns.length - synthetics);
for (int i = ipanns.length - 1; i >= synthetics; --i) {
@@ -2193,31 +2216,31 @@
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
++attributeCount;
}
- if (ClassReader.SIGNATURES && signature != null) {
+ if (signature != null) {
++attributeCount;
}
if (methodParameters != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && annd != null) {
+ if (annd != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && anns != null) {
+ if (anns != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && ianns != null) {
+ if (ianns != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && tanns != null) {
+ if (tanns != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && itanns != null) {
+ if (itanns != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && panns != null) {
+ if (panns != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && ipanns != null) {
+ if (ipanns != null) {
++attributeCount;
}
if (attrs != null) {
@@ -2238,10 +2261,10 @@
if (stackMap != null) {
size += 8 + stackMap.length;
}
- if (ClassReader.ANNOTATIONS && ctanns != null) {
+ if (ctanns != null) {
size += 8 + ctanns.getSize();
}
- if (ClassReader.ANNOTATIONS && ictanns != null) {
+ if (ictanns != null) {
size += 8 + ictanns.getSize();
}
if (cattrs != null) {
@@ -2273,10 +2296,10 @@
if (stackMap != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && ctanns != null) {
+ if (ctanns != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && ictanns != null) {
+ if (ictanns != null) {
++attributeCount;
}
if (cattrs != null) {
@@ -2304,11 +2327,11 @@
out.putInt(stackMap.length + 2).putShort(frameCount);
out.putByteArray(stackMap.data, 0, stackMap.length);
}
- if (ClassReader.ANNOTATIONS && ctanns != null) {
+ if (ctanns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
ctanns.put(out);
}
- if (ClassReader.ANNOTATIONS && ictanns != null) {
+ if (ictanns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
ictanns.put(out);
}
@@ -2333,7 +2356,7 @@
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
out.putShort(cw.newUTF8("Deprecated")).putInt(0);
}
- if (ClassReader.SIGNATURES && signature != null) {
+ if (signature != null) {
out.putShort(cw.newUTF8("Signature")).putInt(2)
.putShort(cw.newUTF8(signature));
}
@@ -2343,32 +2366,32 @@
methodParametersCount);
out.putByteArray(methodParameters.data, 0, methodParameters.length);
}
- if (ClassReader.ANNOTATIONS && annd != null) {
+ if (annd != null) {
out.putShort(cw.newUTF8("AnnotationDefault"));
out.putInt(annd.length);
out.putByteArray(annd.data, 0, annd.length);
}
- if (ClassReader.ANNOTATIONS && anns != null) {
+ if (anns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
anns.put(out);
}
- if (ClassReader.ANNOTATIONS && ianns != null) {
+ if (ianns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
ianns.put(out);
}
- if (ClassReader.ANNOTATIONS && tanns != null) {
+ if (tanns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
tanns.put(out);
}
- if (ClassReader.ANNOTATIONS && itanns != null) {
+ if (itanns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
itanns.put(out);
}
- if (ClassReader.ANNOTATIONS && panns != null) {
+ if (panns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleParameterAnnotations"));
AnnotationWriter.put(panns, synthetics, out);
}
- if (ClassReader.ANNOTATIONS && ipanns != null) {
+ if (ipanns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleParameterAnnotations"));
AnnotationWriter.put(ipanns, synthetics, out);
}
@@ -2376,569 +2399,4 @@
attrs.put(cw, null, 0, -1, -1, out);
}
}
-
- // ------------------------------------------------------------------------
- // Utility methods: instruction resizing (used to handle GOTO_W and JSR_W)
- // ------------------------------------------------------------------------
-
- /**
- * Resizes and replaces the temporary instructions inserted by
- * {@link Label#resolve} for wide forward jumps, while keeping jump offsets
- * and instruction addresses consistent. This may require to resize other
- * existing instructions, or even to introduce new instructions: for
- * example, increasing the size of an instruction by 2 at the middle of a
- * method can increases the offset of an IFEQ instruction from 32766 to
- * 32768, in which case IFEQ 32766 must be replaced with IFNEQ 8 GOTO_W
- * 32765. This, in turn, may require to increase the size of another jump
- * instruction, and so on... All these operations are handled automatically
- * by this method.
- * <p>
- * <i>This method must be called after all the method that is being built
- * has been visited</i>. In particular, the {@link Label Label} objects used
- * to construct the method are no longer valid after this method has been
- * called.
- */
- private void resizeInstructions() {
- byte[] b = code.data; // bytecode of the method
- int u, v, label; // indexes in b
- int i, j; // loop indexes
- /*
- * 1st step: As explained above, resizing an instruction may require to
- * resize another one, which may require to resize yet another one, and
- * so on. The first step of the algorithm consists in finding all the
- * instructions that need to be resized, without modifying the code.
- * This is done by the following "fix point" algorithm:
- *
- * Parse the code to find the jump instructions whose offset will need
- * more than 2 bytes to be stored (the future offset is computed from
- * the current offset and from the number of bytes that will be inserted
- * or removed between the source and target instructions). For each such
- * instruction, adds an entry in (a copy of) the indexes and sizes
- * arrays (if this has not already been done in a previous iteration!).
- *
- * If at least one entry has been added during the previous step, go
- * back to the beginning, otherwise stop.
- *
- * In fact the real algorithm is complicated by the fact that the size
- * of TABLESWITCH and LOOKUPSWITCH instructions depends on their
- * position in the bytecode (because of padding). In order to ensure the
- * convergence of the algorithm, the number of bytes to be added or
- * removed from these instructions is over estimated during the previous
- * loop, and computed exactly only after the loop is finished (this
- * requires another pass to parse the bytecode of the method).
- */
- int[] allIndexes = new int[0]; // copy of indexes
- int[] allSizes = new int[0]; // copy of sizes
- boolean[] resize; // instructions to be resized
- int newOffset; // future offset of a jump instruction
-
- resize = new boolean[code.length];
-
- // 3 = loop again, 2 = loop ended, 1 = last pass, 0 = done
- int state = 3;
- do {
- if (state == 3) {
- state = 2;
- }
- u = 0;
- while (u < b.length) {
- int opcode = b[u] & 0xFF; // opcode of current instruction
- int insert = 0; // bytes to be added after this instruction
-
- switch (ClassWriter.TYPE[opcode]) {
- case ClassWriter.NOARG_INSN:
- case ClassWriter.IMPLVAR_INSN:
- u += 1;
- break;
- case ClassWriter.LABEL_INSN:
- if (opcode > 201) {
- // converts temporary opcodes 202 to 217, 218 and
- // 219 to IFEQ ... JSR (inclusive), IFNULL and
- // IFNONNULL
- opcode = opcode < 218 ? opcode - 49 : opcode - 20;
- label = u + readUnsignedShort(b, u + 1);
- } else {
- label = u + readShort(b, u + 1);
- }
- newOffset = getNewOffset(allIndexes, allSizes, u, label);
- if (newOffset < Short.MIN_VALUE
- || newOffset > Short.MAX_VALUE) {
- if (!resize[u]) {
- if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
- // two additional bytes will be required to
- // replace this GOTO or JSR instruction with
- // a GOTO_W or a JSR_W
- insert = 2;
- } else {
- // five additional bytes will be required to
- // replace this IFxxx <l> instruction with
- // IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx
- // is the "opposite" opcode of IFxxx (i.e.,
- // IFNE for IFEQ) and where <l'> designates
- // the instruction just after the GOTO_W.
- insert = 5;
- }
- resize[u] = true;
- }
- }
- u += 3;
- break;
- case ClassWriter.LABELW_INSN:
- u += 5;
- break;
- case ClassWriter.TABL_INSN:
- if (state == 1) {
- // true number of bytes to be added (or removed)
- // from this instruction = (future number of padding
- // bytes - current number of padding byte) -
- // previously over estimated variation =
- // = ((3 - newOffset%4) - (3 - u%4)) - u%4
- // = (-newOffset%4 + u%4) - u%4
- // = -(newOffset & 3)
- newOffset = getNewOffset(allIndexes, allSizes, 0, u);
- insert = -(newOffset & 3);
- } else if (!resize[u]) {
- // over estimation of the number of bytes to be
- // added to this instruction = 3 - current number
- // of padding bytes = 3 - (3 - u%4) = u%4 = u & 3
- insert = u & 3;
- resize[u] = true;
- }
- // skips instruction
- u = u + 4 - (u & 3);
- u += 4 * (readInt(b, u + 8) - readInt(b, u + 4) + 1) + 12;
- break;
- case ClassWriter.LOOK_INSN:
- if (state == 1) {
- // like TABL_INSN
- newOffset = getNewOffset(allIndexes, allSizes, 0, u);
- insert = -(newOffset & 3);
- } else if (!resize[u]) {
- // like TABL_INSN
- insert = u & 3;
- resize[u] = true;
- }
- // skips instruction
- u = u + 4 - (u & 3);
- u += 8 * readInt(b, u + 4) + 8;
- break;
- case ClassWriter.WIDE_INSN:
- opcode = b[u + 1] & 0xFF;
- if (opcode == Opcodes.IINC) {
- u += 6;
- } else {
- u += 4;
- }
- break;
- case ClassWriter.VAR_INSN:
- case ClassWriter.SBYTE_INSN:
- case ClassWriter.LDC_INSN:
- u += 2;
- break;
- case ClassWriter.SHORT_INSN:
- case ClassWriter.LDCW_INSN:
- case ClassWriter.FIELDORMETH_INSN:
- case ClassWriter.TYPE_INSN:
- case ClassWriter.IINC_INSN:
- u += 3;
- break;
- case ClassWriter.ITFMETH_INSN:
- case ClassWriter.INDYMETH_INSN:
- u += 5;
- break;
- // case ClassWriter.MANA_INSN:
- default:
- u += 4;
- break;
- }
- if (insert != 0) {
- // adds a new (u, insert) entry in the allIndexes and
- // allSizes arrays
- int[] newIndexes = new int[allIndexes.length + 1];
- int[] newSizes = new int[allSizes.length + 1];
- System.arraycopy(allIndexes, 0, newIndexes, 0,
- allIndexes.length);
- System.arraycopy(allSizes, 0, newSizes, 0, allSizes.length);
- newIndexes[allIndexes.length] = u;
- newSizes[allSizes.length] = insert;
- allIndexes = newIndexes;
- allSizes = newSizes;
- if (insert > 0) {
- state = 3;
- }
- }
- }
- if (state < 3) {
- --state;
- }
- } while (state != 0);
-
- // 2nd step:
- // copies the bytecode of the method into a new bytevector, updates the
- // offsets, and inserts (or removes) bytes as requested.
-
- ByteVector newCode = new ByteVector(code.length);
-
- u = 0;
- while (u < code.length) {
- int opcode = b[u] & 0xFF;
- switch (ClassWriter.TYPE[opcode]) {
- case ClassWriter.NOARG_INSN:
- case ClassWriter.IMPLVAR_INSN:
- newCode.putByte(opcode);
- u += 1;
- break;
- case ClassWriter.LABEL_INSN:
- if (opcode > 201) {
- // changes temporary opcodes 202 to 217 (inclusive), 218
- // and 219 to IFEQ ... JSR (inclusive), IFNULL and
- // IFNONNULL
- opcode = opcode < 218 ? opcode - 49 : opcode - 20;
- label = u + readUnsignedShort(b, u + 1);
- } else {
- label = u + readShort(b, u + 1);
- }
- newOffset = getNewOffset(allIndexes, allSizes, u, label);
- if (resize[u]) {
- // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
- // <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is
- // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
- // and where <l'> designates the instruction just after
- // the GOTO_W.
- if (opcode == Opcodes.GOTO) {
- newCode.putByte(200); // GOTO_W
- } else if (opcode == Opcodes.JSR) {
- newCode.putByte(201); // JSR_W
- } else {
- newCode.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
- : opcode ^ 1);
- newCode.putShort(8); // jump offset
- newCode.putByte(200); // GOTO_W
- // newOffset now computed from start of GOTO_W
- newOffset -= 3;
- }
- newCode.putInt(newOffset);
- } else {
- newCode.putByte(opcode);
- newCode.putShort(newOffset);
- }
- u += 3;
- break;
- case ClassWriter.LABELW_INSN:
- label = u + readInt(b, u + 1);
- newOffset = getNewOffset(allIndexes, allSizes, u, label);
- newCode.putByte(opcode);
- newCode.putInt(newOffset);
- u += 5;
- break;
- case ClassWriter.TABL_INSN:
- // skips 0 to 3 padding bytes
- v = u;
- u = u + 4 - (v & 3);
- // reads and copies instruction
- newCode.putByte(Opcodes.TABLESWITCH);
- newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
- label = v + readInt(b, u);
- u += 4;
- newOffset = getNewOffset(allIndexes, allSizes, v, label);
- newCode.putInt(newOffset);
- j = readInt(b, u);
- u += 4;
- newCode.putInt(j);
- j = readInt(b, u) - j + 1;
- u += 4;
- newCode.putInt(readInt(b, u - 4));
- for (; j > 0; --j) {
- label = v + readInt(b, u);
- u += 4;
- newOffset = getNewOffset(allIndexes, allSizes, v, label);
- newCode.putInt(newOffset);
- }
- break;
- case ClassWriter.LOOK_INSN:
- // skips 0 to 3 padding bytes
- v = u;
- u = u + 4 - (v & 3);
- // reads and copies instruction
- newCode.putByte(Opcodes.LOOKUPSWITCH);
- newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
- label = v + readInt(b, u);
- u += 4;
- newOffset = getNewOffset(allIndexes, allSizes, v, label);
- newCode.putInt(newOffset);
- j = readInt(b, u);
- u += 4;
- newCode.putInt(j);
- for (; j > 0; --j) {
- newCode.putInt(readInt(b, u));
- u += 4;
- label = v + readInt(b, u);
- u += 4;
- newOffset = getNewOffset(allIndexes, allSizes, v, label);
- newCode.putInt(newOffset);
- }
- break;
- case ClassWriter.WIDE_INSN:
- opcode = b[u + 1] & 0xFF;
- if (opcode == Opcodes.IINC) {
- newCode.putByteArray(b, u, 6);
- u += 6;
- } else {
- newCode.putByteArray(b, u, 4);
- u += 4;
- }
- break;
- case ClassWriter.VAR_INSN:
- case ClassWriter.SBYTE_INSN:
- case ClassWriter.LDC_INSN:
- newCode.putByteArray(b, u, 2);
- u += 2;
- break;
- case ClassWriter.SHORT_INSN:
- case ClassWriter.LDCW_INSN:
- case ClassWriter.FIELDORMETH_INSN:
- case ClassWriter.TYPE_INSN:
- case ClassWriter.IINC_INSN:
- newCode.putByteArray(b, u, 3);
- u += 3;
- break;
- case ClassWriter.ITFMETH_INSN:
- case ClassWriter.INDYMETH_INSN:
- newCode.putByteArray(b, u, 5);
- u += 5;
- break;
- // case MANA_INSN:
- default:
- newCode.putByteArray(b, u, 4);
- u += 4;
- break;
- }
- }
-
- // updates the stack map frame labels
- if (compute == FRAMES) {
- Label l = labels;
- while (l != null) {
- /*
- * Detects the labels that are just after an IF instruction that
- * has been resized with the IFNOT GOTO_W pattern. These labels
- * are now the target of a jump instruction (the IFNOT
- * instruction). Note that we need the original label position
- * here. getNewOffset must therefore never have been called for
- * this label.
- */
- u = l.position - 3;
- if (u >= 0 && resize[u]) {
- l.status |= Label.TARGET;
- }
- getNewOffset(allIndexes, allSizes, l);
- l = l.successor;
- }
- // Update the offsets in the uninitialized types
- if (cw.typeTable != null) {
- for (i = 0; i < cw.typeTable.length; ++i) {
- Item item = cw.typeTable[i];
- if (item != null && item.type == ClassWriter.TYPE_UNINIT) {
- item.intVal = getNewOffset(allIndexes, allSizes, 0,
- item.intVal);
- }
- }
- }
- // The stack map frames are not serialized yet, so we don't need
- // to update them. They will be serialized in visitMaxs.
- } else if (frameCount > 0) {
- /*
- * Resizing an existing stack map frame table is really hard. Not
- * only the table must be parsed to update the offets, but new
- * frames may be needed for jump instructions that were inserted by
- * this method. And updating the offsets or inserting frames can
- * change the format of the following frames, in case of packed
- * frames. In practice the whole table must be recomputed. For this
- * the frames are marked as potentially invalid. This will cause the
- * whole class to be reread and rewritten with the COMPUTE_FRAMES
- * option (see the ClassWriter.toByteArray method). This is not very
- * efficient but is much easier and requires much less code than any
- * other method I can think of.
- */
- cw.invalidFrames = true;
- }
- // updates the exception handler block labels
- Handler h = firstHandler;
- while (h != null) {
- getNewOffset(allIndexes, allSizes, h.start);
- getNewOffset(allIndexes, allSizes, h.end);
- getNewOffset(allIndexes, allSizes, h.handler);
- h = h.next;
- }
- // updates the instructions addresses in the
- // local var and line number tables
- for (i = 0; i < 2; ++i) {
- ByteVector bv = i == 0 ? localVar : localVarType;
- if (bv != null) {
- b = bv.data;
- u = 0;
- while (u < bv.length) {
- label = readUnsignedShort(b, u);
- newOffset = getNewOffset(allIndexes, allSizes, 0, label);
- writeShort(b, u, newOffset);
- label += readUnsignedShort(b, u + 2);
- newOffset = getNewOffset(allIndexes, allSizes, 0, label)
- - newOffset;
- writeShort(b, u + 2, newOffset);
- u += 10;
- }
- }
- }
- if (lineNumber != null) {
- b = lineNumber.data;
- u = 0;
- while (u < lineNumber.length) {
- writeShort(
- b,
- u,
- getNewOffset(allIndexes, allSizes, 0,
- readUnsignedShort(b, u)));
- u += 4;
- }
- }
- // updates the labels of the other attributes
- Attribute attr = cattrs;
- while (attr != null) {
- Label[] labels = attr.getLabels();
- if (labels != null) {
- for (i = labels.length - 1; i >= 0; --i) {
- getNewOffset(allIndexes, allSizes, labels[i]);
- }
- }
- attr = attr.next;
- }
-
- // replaces old bytecodes with new ones
- code = newCode;
- }
-
- /**
- * Reads an unsigned short value in the given byte array.
- *
- * @param b
- * a byte array.
- * @param index
- * the start index of the value to be read.
- * @return the read value.
- */
- static int readUnsignedShort(final byte[] b, final int index) {
- return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
- }
-
- /**
- * Reads a signed short value in the given byte array.
- *
- * @param b
- * a byte array.
- * @param index
- * the start index of the value to be read.
- * @return the read value.
- */
- static short readShort(final byte[] b, final int index) {
- return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
- }
-
- /**
- * Reads a signed int value in the given byte array.
- *
- * @param b
- * a byte array.
- * @param index
- * the start index of the value to be read.
- * @return the read value.
- */
- static int readInt(final byte[] b, final int index) {
- return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16)
- | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF);
- }
-
- /**
- * Writes a short value in the given byte array.
- *
- * @param b
- * a byte array.
- * @param index
- * where the first byte of the short value must be written.
- * @param s
- * the value to be written in the given byte array.
- */
- static void writeShort(final byte[] b, final int index, final int s) {
- b[index] = (byte) (s >>> 8);
- b[index + 1] = (byte) s;
- }
-
- /**
- * Computes the future value of a bytecode offset.
- * <p>
- * Note: it is possible to have several entries for the same instruction in
- * the <tt>indexes</tt> and <tt>sizes</tt>: two entries (index=a,size=b) and
- * (index=a,size=b') are equivalent to a single entry (index=a,size=b+b').
- *
- * @param indexes
- * current positions of the instructions to be resized. Each
- * instruction must be designated by the index of its <i>last</i>
- * byte, plus one (or, in other words, by the index of the
- * <i>first</i> byte of the <i>next</i> instruction).
- * @param sizes
- * the number of bytes to be <i>added</i> to the above
- * instructions. More precisely, for each i < <tt>len</tt>,
- * <tt>sizes</tt>[i] bytes will be added at the end of the
- * instruction designated by <tt>indexes</tt>[i] or, if
- * <tt>sizes</tt>[i] is negative, the <i>last</i> |
- * <tt>sizes[i]</tt>| bytes of the instruction will be removed
- * (the instruction size <i>must not</i> become negative or
- * null).
- * @param begin
- * index of the first byte of the source instruction.
- * @param end
- * index of the first byte of the target instruction.
- * @return the future value of the given bytecode offset.
- */
- static int getNewOffset(final int[] indexes, final int[] sizes,
- final int begin, final int end) {
- int offset = end - begin;
- for (int i = 0; i < indexes.length; ++i) {
- if (begin < indexes[i] && indexes[i] <= end) {
- // forward jump
- offset += sizes[i];
- } else if (end < indexes[i] && indexes[i] <= begin) {
- // backward jump
- offset -= sizes[i];
- }
- }
- return offset;
- }
-
- /**
- * Updates the offset of the given label.
- *
- * @param indexes
- * current positions of the instructions to be resized. Each
- * instruction must be designated by the index of its <i>last</i>
- * byte, plus one (or, in other words, by the index of the
- * <i>first</i> byte of the <i>next</i> instruction).
- * @param sizes
- * the number of bytes to be <i>added</i> to the above
- * instructions. More precisely, for each i < <tt>len</tt>,
- * <tt>sizes</tt>[i] bytes will be added at the end of the
- * instruction designated by <tt>indexes</tt>[i] or, if
- * <tt>sizes</tt>[i] is negative, the <i>last</i> |
- * <tt>sizes[i]</tt>| bytes of the instruction will be removed
- * (the instruction size <i>must not</i> become negative or
- * null).
- * @param label
- * the label whose offset must be updated.
- */
- static void getNewOffset(final int[] indexes, final int[] sizes,
- final Label label) {
- if ((label.status & Label.RESIZED) == 0) {
- label.position = getNewOffset(indexes, sizes, 0, label.position);
- label.status |= Label.RESIZED;
- }
- }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ModuleVisitor.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,219 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm;
+
+/**
+ * A visitor to visit a Java module. The methods of this class must be called in
+ * the following order: <tt>visitMainClass</tt> | ( <tt>visitPackage</tt> |
+ * <tt>visitRequire</tt> | <tt>visitExport</tt> | <tt>visitOpen</tt> |
+ * <tt>visitUse</tt> | <tt>visitProvide</tt> )* <tt>visitEnd</tt>.
+ *
+ * The methods {@link #visitRequire(String, int, String)}, {@link #visitExport(String, int, String...)},
+ * {@link #visitOpen(String, int, String...)} and {@link #visitPackage(String)}
+ * take as parameter a package name or a module name. Unlike the other names which are internal names
+ * (names separated by slash), module and package names are qualified names (names separated by dot).
+ *
+ * @author Remi Forax
+ */
+public abstract class ModuleVisitor {
+ /**
+ * The ASM API version implemented by this visitor. The value of this field
+ * must be {@link Opcodes#ASM6}.
+ */
+ protected final int api;
+
+ /**
+ * The module visitor to which this visitor must delegate method calls. May
+ * be null.
+ */
+ protected ModuleVisitor mv;
+
+ /**
+ * Constructs a new {@link ModuleVisitor}.
+ *
+ * @param api
+ * the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
+ */
+ public ModuleVisitor(final int api) {
+ this(api, null);
+ }
+
+ /**
+ * Constructs a new {@link ModuleVisitor}.
+ *
+ * @param api
+ * the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
+ * @param mv
+ * the module visitor to which this visitor must delegate method
+ * calls. May be null.
+ */
+ public ModuleVisitor(final int api, final ModuleVisitor mv) {
+ if (api != Opcodes.ASM6) {
+ throw new IllegalArgumentException();
+ }
+ this.api = api;
+ this.mv = mv;
+ }
+
+ /**
+ * Visit the main class of the current module.
+ *
+ * @param mainClass the internal name of the main class of the current module.
+ */
+ public void visitMainClass(String mainClass) {
+ if (mv != null) {
+ mv.visitMainClass(mainClass);
+ }
+ }
+
+ /**
+ * Visit a package of the current module.
+ *
+ * @param packaze the qualified name of a package.
+ */
+ public void visitPackage(String packaze) {
+ if (mv != null) {
+ mv.visitPackage(packaze);
+ }
+ }
+
+ /**
+ * Visits a dependence of the current module.
+ *
+ * @param module the qualified name of the dependence.
+ * @param access the access flag of the dependence among
+ * ACC_TRANSITIVE, ACC_STATIC_PHASE, ACC_SYNTHETIC
+ * and ACC_MANDATED.
+ * @param version the module version at compile time or null.
+ */
+ public void visitRequire(String module, int access, String version) {
+ if (mv != null) {
+ mv.visitRequire(module, access, version);
+ }
+ }
+
+ /**
+ * Visit an exported package of the current module.
+ *
+ * @param packaze the qualified name of the exported package.
+ * @param access the access flag of the exported package,
+ * valid values are among {@code ACC_SYNTHETIC} and
+ * {@code ACC_MANDATED}.
+ * @param modules the qualified names of the modules that can access to
+ * the public classes of the exported package or
+ * <tt>null</tt>.
+ */
+ public void visitExport(String packaze, int access, String... modules) {
+ if (mv != null) {
+ mv.visitExport(packaze, access, modules);
+ }
+ }
+
+ /**
+ * Visit an open package of the current module.
+ *
+ * @param packaze the qualified name of the opened package.
+ * @param access the access flag of the opened package,
+ * valid values are among {@code ACC_SYNTHETIC} and
+ * {@code ACC_MANDATED}.
+ * @param modules the qualified names of the modules that can use deep
+ * reflection to the classes of the open package or
+ * <tt>null</tt>.
+ */
+ public void visitOpen(String packaze, int access, String... modules) {
+ if (mv != null) {
+ mv.visitOpen(packaze, access, modules);
+ }
+ }
+
+ /**
+ * Visit a service used by the current module.
+ * The name must be the internal name of an interface or a class.
+ *
+ * @param service the internal name of the service.
+ */
+ public void visitUse(String service) {
+ if (mv != null) {
+ mv.visitUse(service);
+ }
+ }
+
+ /**
+ * Visit an implementation of a service.
+ *
+ * @param service the internal name of the service
+ * @param providers the internal names of the implementations
+ * of the service (there is at least one provider).
+ */
+ public void visitProvide(String service, String... providers) {
+ if (mv != null) {
+ mv.visitProvide(service, providers);
+ }
+ }
+
+ /**
+ * Visits the end of the module. This method, which is the last one to be
+ * called, is used to inform the visitor that everything have been visited.
+ */
+ public void visitEnd() {
+ if (mv != null) {
+ mv.visitEnd();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ModuleWriter.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,322 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm;
+
+/**
+ * @author Remi Forax
+ */
+final class ModuleWriter extends ModuleVisitor {
+ /**
+ * The class writer to which this Module attribute must be added.
+ */
+ private final ClassWriter cw;
+
+ /**
+ * size in byte of the Module attribute.
+ */
+ int size;
+
+ /**
+ * Number of attributes associated with the current module
+ * (Version, ConcealPackages, etc)
+ */
+ int attributeCount;
+
+ /**
+ * Size in bytes of the attributes associated with the current module
+ */
+ int attributesSize;
+
+ /**
+ * module name index in the constant pool
+ */
+ private final int name;
+
+ /**
+ * module access flags
+ */
+ private final int access;
+
+ /**
+ * module version index in the constant pool or 0
+ */
+ private final int version;
+
+ /**
+ * module main class index in the constant pool or 0
+ */
+ private int mainClass;
+
+ /**
+ * number of packages
+ */
+ private int packageCount;
+
+ /**
+ * The packages in bytecode form. This byte vector only contains
+ * the items themselves, the number of items is store in packageCount
+ */
+ private ByteVector packages;
+
+ /**
+ * number of requires items
+ */
+ private int requireCount;
+
+ /**
+ * The requires items in bytecode form. This byte vector only contains
+ * the items themselves, the number of items is store in requireCount
+ */
+ private ByteVector requires;
+
+ /**
+ * number of exports items
+ */
+ private int exportCount;
+
+ /**
+ * The exports items in bytecode form. This byte vector only contains
+ * the items themselves, the number of items is store in exportCount
+ */
+ private ByteVector exports;
+
+ /**
+ * number of opens items
+ */
+ private int openCount;
+
+ /**
+ * The opens items in bytecode form. This byte vector only contains
+ * the items themselves, the number of items is store in openCount
+ */
+ private ByteVector opens;
+
+ /**
+ * number of uses items
+ */
+ private int useCount;
+
+ /**
+ * The uses items in bytecode form. This byte vector only contains
+ * the items themselves, the number of items is store in useCount
+ */
+ private ByteVector uses;
+
+ /**
+ * number of provides items
+ */
+ private int provideCount;
+
+ /**
+ * The uses provides in bytecode form. This byte vector only contains
+ * the items themselves, the number of items is store in provideCount
+ */
+ private ByteVector provides;
+
+ ModuleWriter(final ClassWriter cw, final int name,
+ final int access, final int version) {
+ super(Opcodes.ASM6);
+ this.cw = cw;
+ this.size = 16; // name + access + version + 5 counts
+ this.name = name;
+ this.access = access;
+ this.version = version;
+ }
+
+ @Override
+ public void visitMainClass(String mainClass) {
+ if (this.mainClass == 0) { // protect against several calls to visitMainClass
+ cw.newUTF8("ModuleMainClass");
+ attributeCount++;
+ attributesSize += 8;
+ }
+ this.mainClass = cw.newClass(mainClass);
+ }
+
+ @Override
+ public void visitPackage(String packaze) {
+ if (packages == null) {
+ // protect against several calls to visitPackage
+ cw.newUTF8("ModulePackages");
+ packages = new ByteVector();
+ attributeCount++;
+ attributesSize += 8;
+ }
+ packages.putShort(cw.newPackage(packaze));
+ packageCount++;
+ attributesSize += 2;
+ }
+
+ @Override
+ public void visitRequire(String module, int access, String version) {
+ if (requires == null) {
+ requires = new ByteVector();
+ }
+ requires.putShort(cw.newModule(module))
+ .putShort(access)
+ .putShort(version == null? 0: cw.newUTF8(version));
+ requireCount++;
+ size += 6;
+ }
+
+ @Override
+ public void visitExport(String packaze, int access, String... modules) {
+ if (exports == null) {
+ exports = new ByteVector();
+ }
+ exports.putShort(cw.newPackage(packaze)).putShort(access);
+ if (modules == null) {
+ exports.putShort(0);
+ size += 6;
+ } else {
+ exports.putShort(modules.length);
+ for(String module: modules) {
+ exports.putShort(cw.newModule(module));
+ }
+ size += 6 + 2 * modules.length;
+ }
+ exportCount++;
+ }
+
+ @Override
+ public void visitOpen(String packaze, int access, String... modules) {
+ if (opens == null) {
+ opens = new ByteVector();
+ }
+ opens.putShort(cw.newPackage(packaze)).putShort(access);
+ if (modules == null) {
+ opens.putShort(0);
+ size += 6;
+ } else {
+ opens.putShort(modules.length);
+ for(String module: modules) {
+ opens.putShort(cw.newModule(module));
+ }
+ size += 6 + 2 * modules.length;
+ }
+ openCount++;
+ }
+
+ @Override
+ public void visitUse(String service) {
+ if (uses == null) {
+ uses = new ByteVector();
+ }
+ uses.putShort(cw.newClass(service));
+ useCount++;
+ size += 2;
+ }
+
+ @Override
+ public void visitProvide(String service, String... providers) {
+ if (provides == null) {
+ provides = new ByteVector();
+ }
+ provides.putShort(cw.newClass(service));
+ provides.putShort(providers.length);
+ for(String provider: providers) {
+ provides.putShort(cw.newClass(provider));
+ }
+ provideCount++;
+ size += 4 + 2 * providers.length;
+ }
+
+ @Override
+ public void visitEnd() {
+ // empty
+ }
+
+ void putAttributes(ByteVector out) {
+ if (mainClass != 0) {
+ out.putShort(cw.newUTF8("ModuleMainClass")).putInt(2).putShort(mainClass);
+ }
+ if (packages != null) {
+ out.putShort(cw.newUTF8("ModulePackages"))
+ .putInt(2 + 2 * packageCount)
+ .putShort(packageCount)
+ .putByteArray(packages.data, 0, packages.length);
+ }
+ }
+
+ void put(ByteVector out) {
+ out.putInt(size);
+ out.putShort(name).putShort(access).putShort(version);
+ out.putShort(requireCount);
+ if (requires != null) {
+ out.putByteArray(requires.data, 0, requires.length);
+ }
+ out.putShort(exportCount);
+ if (exports != null) {
+ out.putByteArray(exports.data, 0, exports.length);
+ }
+ out.putShort(openCount);
+ if (opens != null) {
+ out.putByteArray(opens.data, 0, opens.length);
+ }
+ out.putShort(useCount);
+ if (uses != null) {
+ out.putByteArray(uses.data, 0, uses.length);
+ }
+ out.putShort(provideCount);
+ if (provides != null) {
+ out.putByteArray(provides.data, 0, provides.length);
+ }
+ }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java Wed Nov 08 16:03:35 2017 -0500
@@ -70,13 +70,13 @@
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
-@SuppressWarnings("deprecation") // for Integer(int) constructor
public interface Opcodes {
// ASM API versions
int ASM4 = 4 << 16 | 0 << 8 | 0;
int ASM5 = 5 << 16 | 0 << 8 | 0;
+ int ASM6 = 6 << 16 | 0 << 8 | 0;
// versions
@@ -88,7 +88,7 @@
int V1_6 = 0 << 16 | 50;
int V1_7 = 0 << 16 | 51;
int V1_8 = 0 << 16 | 52;
- int V1_9 = 0 << 16 | 53;
+ int V9 = 0 << 16 | 53;
// access flags
@@ -99,18 +99,23 @@
int ACC_FINAL = 0x0010; // class, field, method, parameter
int ACC_SUPER = 0x0020; // class
int ACC_SYNCHRONIZED = 0x0020; // method
+ int ACC_OPEN = 0x0020; // module
+ int ACC_TRANSITIVE = 0x0020; // module requires
int ACC_VOLATILE = 0x0040; // field
int ACC_BRIDGE = 0x0040; // method
+ int ACC_STATIC_PHASE = 0x0040; // module requires
int ACC_VARARGS = 0x0080; // method
int ACC_TRANSIENT = 0x0080; // field
int ACC_NATIVE = 0x0100; // method
int ACC_INTERFACE = 0x0200; // class
int ACC_ABSTRACT = 0x0400; // class, method
int ACC_STRICT = 0x0800; // method
- int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter
+ int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter, module *
int ACC_ANNOTATION = 0x2000; // class
int ACC_ENUM = 0x4000; // class(?) field inner
- int ACC_MANDATED = 0x8000; // parameter
+ int ACC_MANDATED = 0x8000; // parameter, module, module *
+ int ACC_MODULE = 0x8000; // class
+
// ASM specific pseudo access flags
@@ -177,15 +182,17 @@
*/
int F_SAME1 = 4;
- // For reference comparison purposes, construct new instances
- // instead of using valueOf() or autoboxing.
- Integer TOP = new Integer(0);
- Integer INTEGER = new Integer(1);
- Integer FLOAT = new Integer(2);
- Integer DOUBLE = new Integer(3);
- Integer LONG = new Integer(4);
- Integer NULL = new Integer(5);
- Integer UNINITIALIZED_THIS = new Integer(6);
+ // Do not try to change the following code to use auto-boxing,
+ // these values are compared by reference and not by value
+ // The constructor of Integer was deprecated in 9
+ // but we are stuck with it by backward compatibility
+ @SuppressWarnings("deprecation") Integer TOP = new Integer(0);
+ @SuppressWarnings("deprecation") Integer INTEGER = new Integer(1);
+ @SuppressWarnings("deprecation") Integer FLOAT = new Integer(2);
+ @SuppressWarnings("deprecation") Integer DOUBLE = new Integer(3);
+ @SuppressWarnings("deprecation") Integer LONG = new Integer(4);
+ @SuppressWarnings("deprecation") Integer NULL = new Integer(5);
+ @SuppressWarnings("deprecation") Integer UNINITIALIZED_THIS = new Integer(6);
// opcodes // visit method (- = idem)
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Type.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Type.java Wed Nov 08 16:03:35 2017 -0500
@@ -406,7 +406,16 @@
*/
public static Type getReturnType(final String methodDescriptor) {
char[] buf = methodDescriptor.toCharArray();
- return getType(buf, methodDescriptor.indexOf(')') + 1);
+ int off = 1;
+ while (true) {
+ char car = buf[off++];
+ if (car == ')') {
+ return getType(buf, off);
+ } else if (car == 'L') {
+ while (buf[off++] != ';') {
+ }
+ }
+ }
}
/**
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AdviceAdapter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AdviceAdapter.java Wed Nov 08 16:03:35 2017 -0500
@@ -112,7 +112,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param mv
* the method visitor to which this adapter delegates calls.
* @param access
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java Wed Nov 08 16:03:35 2017 -0500
@@ -170,7 +170,7 @@
*/
public AnalyzerAdapter(final String owner, final int access,
final String name, final String desc, final MethodVisitor mv) {
- this(Opcodes.ASM5, owner, access, name, desc, mv);
+ this(Opcodes.ASM6, owner, access, name, desc, mv);
if (getClass() != AnalyzerAdapter.class) {
throw new IllegalStateException();
}
@@ -181,7 +181,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param owner
* the owner's class name.
* @param access
@@ -690,6 +690,8 @@
t1 = pop();
if (t1 instanceof String) {
pushDesc(((String) t1).substring(1));
+ } else if (t1 == Opcodes.NULL) {
+ push(t1);
} else {
push("java/lang/Object");
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnnotationRemapper.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnnotationRemapper.java Wed Nov 08 16:03:35 2017 -0500
@@ -73,7 +73,7 @@
public AnnotationRemapper(final AnnotationVisitor av,
final Remapper remapper) {
- this(Opcodes.ASM5, av, remapper);
+ this(Opcodes.ASM6, av, remapper);
}
protected AnnotationRemapper(final int api, final AnnotationVisitor av,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ClassRemapper.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ClassRemapper.java Wed Nov 08 16:03:35 2017 -0500
@@ -59,10 +59,14 @@
package jdk.internal.org.objectweb.asm.commons;
+import java.util.List;
+
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
+import jdk.internal.org.objectweb.asm.Attribute;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.FieldVisitor;
import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.TypePath;
@@ -78,7 +82,7 @@
protected String className;
public ClassRemapper(final ClassVisitor cv, final Remapper remapper) {
- this(Opcodes.ASM5, cv, remapper);
+ this(Opcodes.ASM6, cv, remapper);
}
protected ClassRemapper(final int api, final ClassVisitor cv,
@@ -97,6 +101,12 @@
}
@Override
+ public ModuleVisitor visitModule(String name, int flags, String version) {
+ ModuleVisitor mv = super.visitModule(remapper.mapModuleName(name), flags, version);
+ return mv == null ? null : createModuleRemapper(mv);
+ }
+
+ @Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
visible);
@@ -112,6 +122,18 @@
}
@Override
+ public void visitAttribute(Attribute attr) {
+ if (attr instanceof ModuleHashesAttribute) {
+ ModuleHashesAttribute hashesAttr = new ModuleHashesAttribute();
+ List<String> modules = hashesAttr.modules;
+ for(int i = 0; i < modules.size(); i++) {
+ modules.set(i, remapper.mapModuleName(modules.get(i)));
+ }
+ }
+ super.visitAttribute(attr);
+ }
+
+ @Override
public FieldVisitor visitField(int access, String name, String desc,
String signature, Object value) {
FieldVisitor fv = super.visitField(access,
@@ -158,4 +180,8 @@
protected AnnotationVisitor createAnnotationRemapper(AnnotationVisitor av) {
return new AnnotationRemapper(av, remapper);
}
+
+ protected ModuleVisitor createModuleRemapper(ModuleVisitor mv) {
+ return new ModuleRemapper(mv, remapper);
+ }
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java Wed Nov 08 16:03:35 2017 -0500
@@ -75,7 +75,7 @@
private int maxSize;
public CodeSizeEvaluator(final MethodVisitor mv) {
- this(Opcodes.ASM5, mv);
+ this(Opcodes.ASM6, mv);
}
protected CodeSizeEvaluator(final int api, final MethodVisitor mv) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/FieldRemapper.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/FieldRemapper.java Wed Nov 08 16:03:35 2017 -0500
@@ -74,7 +74,7 @@
private final Remapper remapper;
public FieldRemapper(final FieldVisitor fv, final Remapper remapper) {
- this(Opcodes.ASM5, fv, remapper);
+ this(Opcodes.ASM6, fv, remapper);
}
protected FieldRemapper(final int api, final FieldVisitor fv,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java Wed Nov 08 16:03:35 2017 -0500
@@ -289,7 +289,7 @@
*/
public GeneratorAdapter(final MethodVisitor mv, final int access,
final String name, final String desc) {
- this(Opcodes.ASM5, mv, access, name, desc);
+ this(Opcodes.ASM6, mv, access, name, desc);
if (getClass() != GeneratorAdapter.class) {
throw new IllegalStateException();
}
@@ -300,7 +300,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param mv
* the method visitor to which this adapter delegates calls.
* @param access
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java Wed Nov 08 16:03:35 2017 -0500
@@ -86,7 +86,7 @@
* If a subclass calls this constructor.
*/
public InstructionAdapter(final MethodVisitor mv) {
- this(Opcodes.ASM5, mv);
+ this(Opcodes.ASM6, mv);
if (getClass() != InstructionAdapter.class) {
throw new IllegalStateException();
}
@@ -97,7 +97,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param mv
* the method visitor to which this adapter delegates calls.
*/
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter.java Wed Nov 08 16:03:35 2017 -0500
@@ -142,7 +142,7 @@
public JSRInlinerAdapter(final MethodVisitor mv, final int access,
final String name, final String desc, final String signature,
final String[] exceptions) {
- this(Opcodes.ASM5, mv, access, name, desc, signature, exceptions);
+ this(Opcodes.ASM6, mv, access, name, desc, signature, exceptions);
if (getClass() != JSRInlinerAdapter.class) {
throw new IllegalStateException();
}
@@ -153,7 +153,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param mv
* the <code>MethodVisitor</code> to send the resulting inlined
* method code to (use <code>null</code> for none).
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/LocalVariablesSorter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/LocalVariablesSorter.java Wed Nov 08 16:03:35 2017 -0500
@@ -120,7 +120,7 @@
*/
public LocalVariablesSorter(final int access, final String desc,
final MethodVisitor mv) {
- this(Opcodes.ASM5, access, desc, mv);
+ this(Opcodes.ASM6, access, desc, mv);
if (getClass() != LocalVariablesSorter.class) {
throw new IllegalStateException();
}
@@ -131,7 +131,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param access
* access flags of the adapted method.
* @param desc
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/MethodRemapper.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/MethodRemapper.java Wed Nov 08 16:03:35 2017 -0500
@@ -76,7 +76,7 @@
protected final Remapper remapper;
public MethodRemapper(final MethodVisitor mv, final Remapper remapper) {
- this(Opcodes.ASM5, mv, remapper);
+ this(Opcodes.ASM6, mv, remapper);
}
protected MethodRemapper(final int api, final MethodVisitor mv,
@@ -122,18 +122,20 @@
}
private Object[] remapEntries(int n, Object[] entries) {
- for (int i = 0; i < n; i++) {
- if (entries[i] instanceof String) {
- Object[] newEntries = new Object[n];
- if (i > 0) {
- System.arraycopy(entries, 0, newEntries, 0, i);
+ if (entries != null) {
+ for (int i = 0; i < n; i++) {
+ if (entries[i] instanceof String) {
+ Object[] newEntries = new Object[n];
+ if (i > 0) {
+ System.arraycopy(entries, 0, newEntries, 0, i);
+ }
+ do {
+ Object t = entries[i];
+ newEntries[i++] = t instanceof String ? remapper
+ .mapType((String) t) : t;
+ } while (i < n);
+ return newEntries;
}
- do {
- Object t = entries[i];
- newEntries[i++] = t instanceof String ? remapper
- .mapType((String) t) : t;
- } while (i < n);
- return newEntries;
}
}
return entries;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleHashesAttribute.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,155 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm.commons;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.Attribute;
+import jdk.internal.org.objectweb.asm.ByteVector;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+
+/**
+ * ModuleHashes attribute.
+ * This attribute is specific to the OpenJDK and may change in the future.
+ *
+ * @author Remi Forax
+ */
+public final class ModuleHashesAttribute extends Attribute {
+ public String algorithm;
+ public List<String> modules;
+ public List<byte[]> hashes;
+
+ /**
+ * Creates an attribute with a hashing algorithm, a list of module names,
+ * and a list of the same length of hashes.
+ * @param algorithm the hashing algorithm name.
+ * @param modules a list of module name
+ * @param hashes a list of hash, one for each module name.
+ */
+ public ModuleHashesAttribute(final String algorithm,
+ final List<String> modules, final List<byte[]> hashes) {
+ super("ModuleHashes");
+ this.algorithm = algorithm;
+ this.modules = modules;
+ this.hashes = hashes;
+ }
+
+ /**
+ * Creates an empty attribute that can be used as prototype
+ * to be passed as argument of the method
+ * {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)}.
+ */
+ public ModuleHashesAttribute() {
+ this(null, null, null);
+ }
+
+ @Override
+ protected Attribute read(ClassReader cr, int off, int len, char[] buf,
+ int codeOff, Label[] labels) {
+ String hashAlgorithm = cr.readUTF8(off, buf);
+
+ int count = cr.readUnsignedShort(off + 2);
+ ArrayList<String> modules = new ArrayList<String>(count);
+ ArrayList<byte[]> hashes = new ArrayList<byte[]>(count);
+ off += 4;
+
+ for (int i = 0; i < count; i++) {
+ String module = cr.readModule(off, buf);
+ int hashLength = cr.readUnsignedShort(off + 2);
+ off += 4;
+
+ byte[] hash = new byte[hashLength];
+ for (int j = 0; j < hashLength; j++) {
+ hash[j] = (byte) (cr.readByte(off + j) & 0xff);
+ }
+ off += hashLength;
+
+ modules.add(module);
+ hashes.add(hash);
+ }
+ return new ModuleHashesAttribute(hashAlgorithm, modules, hashes);
+ }
+
+ @Override
+ protected ByteVector write(ClassWriter cw, byte[] code, int len,
+ int maxStack, int maxLocals) {
+ ByteVector v = new ByteVector();
+ int index = cw.newUTF8(algorithm);
+ v.putShort(index);
+
+ int count = (modules == null)? 0: modules.size();
+ v.putShort(count);
+
+ for(int i = 0; i < count; i++) {
+ String module = modules.get(i);
+ v.putShort(cw.newModule(module));
+
+ byte[] hash = hashes.get(i);
+ v.putShort(hash.length);
+ for(byte b: hash) {
+ v.putByte(b);
+ }
+ }
+ return v;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleRemapper.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm.commons;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+/**
+ * A {@link ModuleVisitor} adapter for type remapping.
+ *
+ * @author Remi Forax
+ */
+public class ModuleRemapper extends ModuleVisitor {
+ private final Remapper remapper;
+
+ public ModuleRemapper(final ModuleVisitor mv, final Remapper remapper) {
+ this(Opcodes.ASM6, mv, remapper);
+ }
+
+ protected ModuleRemapper(final int api, final ModuleVisitor mv,
+ final Remapper remapper) {
+ super(api, mv);
+ this.remapper = remapper;
+ }
+
+ @Override
+ public void visitMainClass(String mainClass) {
+ super.visitMainClass(remapper.mapType(mainClass));
+ }
+
+ @Override
+ public void visitPackage(String packaze) {
+ super.visitPackage(remapper.mapPackageName(packaze));
+ }
+
+ @Override
+ public void visitRequire(String module, int access, String version) {
+ super.visitRequire(remapper.mapModuleName(module), access, version);
+ }
+
+ @Override
+ public void visitExport(String packaze, int access, String... modules) {
+ String[] newModules = null;
+ if (modules != null) {
+ newModules = new String[modules.length];
+ for (int i = 0 ; i < modules.length; i++) {
+ newModules[i] = remapper.mapModuleName(modules[i]);
+ }
+ }
+ super.visitExport(remapper.mapPackageName(packaze), access, newModules);
+ }
+
+ @Override
+ public void visitOpen(String packaze, int access, String... modules) {
+ String[] newModules = null;
+ if (modules != null) {
+ newModules = new String[modules.length];
+ for (int i = 0 ; i < modules.length; i++) {
+ newModules[i] = remapper.mapModuleName(modules[i]);
+ }
+ }
+ super.visitOpen(remapper.mapPackageName(packaze), access, newModules);
+ }
+
+ @Override
+ public void visitUse(String service) {
+ super.visitUse(remapper.mapType(service));
+ }
+
+ @Override
+ public void visitProvide(String service, String... providers) {
+ String[] newProviders = new String[providers.length];
+ for (int i = 0 ; i < providers.length; i++) {
+ newProviders[i] = remapper.mapType(providers[i]);
+ }
+ super.visitProvide(remapper.mapType(service), newProviders);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleResolutionAttribute.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm.commons;
+
+import jdk.internal.org.objectweb.asm.Attribute;
+import jdk.internal.org.objectweb.asm.ByteVector;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+
+/**
+ * ModuleResolution_attribute.
+ * This attribute is specific to the OpenJDK and may change in the future.
+ *
+ * @author Remi Forax
+ */
+public final class ModuleResolutionAttribute extends Attribute {
+ /**
+ * Resolution state of a module meaning that the module is not available
+ * from the class-path by default.
+ */
+ public static final int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1;
+
+ /**
+ * Resolution state of a module meaning the module is marked as deprecated.
+ */
+ public static final int RESOLUTION_WARN_DEPRECATED = 2;
+
+ /**
+ * Resolution state of a module meaning the module is marked as deprecated
+ * and will be removed in a future release.
+ */
+ public static final int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4;
+
+ /**
+ * Resolution state of a module meaning the module is not yet standardized,
+ * so in incubating mode.
+ */
+ public static final int RESOLUTION_WARN_INCUBATING = 8;
+
+ public int resolution;
+
+ /**
+ * Creates an attribute with a resolution state value.
+ * @param resolution the resolution state among
+ * {@link #RESOLUTION_WARN_DEPRECATED},
+ * {@link #RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL}, and
+ * {@link #RESOLUTION_WARN_INCUBATING}.
+ */
+ public ModuleResolutionAttribute(final int resolution) {
+ super("ModuleResolution");
+ this.resolution = resolution;
+ }
+
+ /**
+ * Creates an empty attribute that can be used as prototype
+ * to be passed as argument of the method
+ * {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)}.
+ */
+ public ModuleResolutionAttribute() {
+ this(0);
+ }
+
+ @Override
+ protected Attribute read(ClassReader cr, int off, int len, char[] buf,
+ int codeOff, Label[] labels) {
+ int resolution = cr.readUnsignedShort(off);
+ return new ModuleResolutionAttribute(resolution);
+ }
+
+ @Override
+ protected ByteVector write(ClassWriter cw, byte[] code, int len,
+ int maxStack, int maxLocals) {
+ ByteVector v = new ByteVector();
+ v.putShort(resolution);
+ return v;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleTargetAttribute.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm.commons;
+
+import jdk.internal.org.objectweb.asm.Attribute;
+import jdk.internal.org.objectweb.asm.ByteVector;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+
+/**
+ * ModuleTarget attribute.
+ * This attribute is specific to the OpenJDK and may change in the future.
+ *
+ * @author Remi Forax
+ */
+public final class ModuleTargetAttribute extends Attribute {
+ public String platform;
+
+ /**
+ * Creates an attribute with a platform name.
+ * @param platform the platform name on which the module can run.
+ */
+ public ModuleTargetAttribute(final String platform) {
+ super("ModuleTarget");
+ this.platform = platform;
+ }
+
+ /**
+ * Creates an empty attribute that can be used as prototype
+ * to be passed as argument of the method
+ * {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)}.
+ */
+ public ModuleTargetAttribute() {
+ this(null);
+ }
+
+ @Override
+ protected Attribute read(ClassReader cr, int off, int len, char[] buf,
+ int codeOff, Label[] labels) {
+ String platform = cr.readUTF8(off, buf);
+ return new ModuleTargetAttribute(platform);
+ }
+
+ @Override
+ protected ByteVector write(ClassWriter cw, byte[] code, int len,
+ int maxStack, int maxLocals) {
+ ByteVector v = new ByteVector();
+ int index = (platform == null)? 0: cw.newUTF8(platform);
+ v.putShort(index);
+ return v;
+ }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java Wed Nov 08 16:03:35 2017 -0500
@@ -255,6 +255,28 @@
}
/**
+ * Map package name to the new name. Subclasses can override.
+ *
+ * @param name name of the package
+ * @return new name of the package
+ */
+ public String mapPackageName(String name) {
+ String fakeName = map(name + ".FakeClassName");
+ int index;
+ return fakeName == null || (index = fakeName.lastIndexOf('.')) == -1 ? name: fakeName.substring(0, index);
+ }
+
+ /**
+ * Map module name to the new name. Subclasses can override.
+ *
+ * @param name name of the module
+ * @return new name of the module
+ */
+ public String mapModuleName(String name) {
+ return name;
+ }
+
+ /**
* Map type name to the new name. Subclasses can override.
*
* @param typeName
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingAnnotationAdapter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingAnnotationAdapter.java Wed Nov 08 16:03:35 2017 -0500
@@ -75,7 +75,7 @@
public RemappingAnnotationAdapter(final AnnotationVisitor av,
final Remapper remapper) {
- this(Opcodes.ASM5, av, remapper);
+ this(Opcodes.ASM6, av, remapper);
}
protected RemappingAnnotationAdapter(final int api,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingClassAdapter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingClassAdapter.java Wed Nov 08 16:03:35 2017 -0500
@@ -63,6 +63,7 @@
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.FieldVisitor;
import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.TypePath;
@@ -80,7 +81,7 @@
protected String className;
public RemappingClassAdapter(final ClassVisitor cv, final Remapper remapper) {
- this(Opcodes.ASM5, cv, remapper);
+ this(Opcodes.ASM6, cv, remapper);
}
protected RemappingClassAdapter(final int api, final ClassVisitor cv,
@@ -99,6 +100,11 @@
}
@Override
+ public ModuleVisitor visitModule(String name, int flags, String version) {
+ throw new RuntimeException("RemappingClassAdapter is deprecated, use ClassRemapper instead");
+ }
+
+ @Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
visible);
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingFieldAdapter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingFieldAdapter.java Wed Nov 08 16:03:35 2017 -0500
@@ -76,7 +76,7 @@
private final Remapper remapper;
public RemappingFieldAdapter(final FieldVisitor fv, final Remapper remapper) {
- this(Opcodes.ASM5, fv, remapper);
+ this(Opcodes.ASM6, fv, remapper);
}
protected RemappingFieldAdapter(final int api, final FieldVisitor fv,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java Wed Nov 08 16:03:35 2017 -0500
@@ -79,7 +79,7 @@
public RemappingMethodAdapter(final int access, final String desc,
final MethodVisitor mv, final Remapper remapper) {
- this(Opcodes.ASM5, access, desc, mv, remapper);
+ this(Opcodes.ASM6, access, desc, mv, remapper);
}
protected RemappingMethodAdapter(final int api, final int access,
@@ -125,18 +125,20 @@
}
private Object[] remapEntries(int n, Object[] entries) {
- for (int i = 0; i < n; i++) {
- if (entries[i] instanceof String) {
- Object[] newEntries = new Object[n];
- if (i > 0) {
- System.arraycopy(entries, 0, newEntries, 0, i);
+ if (entries != null) {
+ for (int i = 0; i < n; i++) {
+ if (entries[i] instanceof String) {
+ Object[] newEntries = new Object[n];
+ if (i > 0) {
+ System.arraycopy(entries, 0, newEntries, 0, i);
+ }
+ do {
+ Object t = entries[i];
+ newEntries[i++] = t instanceof String ? remapper
+ .mapType((String) t) : t;
+ } while (i < n);
+ return newEntries;
}
- do {
- Object t = entries[i];
- newEntries[i++] = t instanceof String ? remapper
- .mapType((String) t) : t;
- } while (i < n);
- return newEntries;
}
}
return entries;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingSignatureAdapter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingSignatureAdapter.java Wed Nov 08 16:03:35 2017 -0500
@@ -79,7 +79,7 @@
public RemappingSignatureAdapter(final SignatureVisitor v,
final Remapper remapper) {
- this(Opcodes.ASM5, v, remapper);
+ this(Opcodes.ASM6, v, remapper);
}
protected RemappingSignatureAdapter(final int api,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java Wed Nov 08 16:03:35 2017 -0500
@@ -80,7 +80,7 @@
* ClassWriter cw = new ClassWriter(...);
* ClassVisitor sv = new SerialVersionUIDAdder(cw);
* ClassVisitor ca = new MyClassAdapter(sv);
- * new ClassReader(originalClass).accept(ca, false);
+ * new ClassReader(orginalClass).accept(ca, false);
* </pre>
*
* The SVUID algorithm can be found <a href=
@@ -199,7 +199,7 @@
* If a subclass calls this constructor.
*/
public SerialVersionUIDAdder(final ClassVisitor cv) {
- this(Opcodes.ASM5, cv);
+ this(Opcodes.ASM6, cv);
if (getClass() != SerialVersionUIDAdder.class) {
throw new IllegalStateException();
}
@@ -210,7 +210,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param cv
* a {@link ClassVisitor} to which this visitor will delegate
* calls.
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SignatureRemapper.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SignatureRemapper.java Wed Nov 08 16:03:35 2017 -0500
@@ -78,7 +78,7 @@
private Stack<String> classNames = new Stack<String>();
public SignatureRemapper(final SignatureVisitor v, final Remapper remapper) {
- this(Opcodes.ASM5, v, remapper);
+ this(Opcodes.ASM6, v, remapper);
}
protected SignatureRemapper(final int api, final SignatureVisitor v,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/StaticInitMerger.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/StaticInitMerger.java Wed Nov 08 16:03:35 2017 -0500
@@ -78,7 +78,7 @@
private int counter;
public StaticInitMerger(final String prefix, final ClassVisitor cv) {
- this(Opcodes.ASM5, prefix, cv);
+ this(Opcodes.ASM6, prefix, cv);
}
protected StaticInitMerger(final int api, final String prefix,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/TryCatchBlockSorter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/TryCatchBlockSorter.java Wed Nov 08 16:03:35 2017 -0500
@@ -86,7 +86,7 @@
public TryCatchBlockSorter(final MethodVisitor mv, final int access,
final String name, final String desc, final String signature,
final String[] exceptions) {
- this(Opcodes.ASM5, mv, access, name, desc, signature, exceptions);
+ this(Opcodes.ASM6, mv, access, name, desc, signature, exceptions);
}
protected TryCatchBlockSorter(final int api, final MethodVisitor mv,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureVisitor.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureVisitor.java Wed Nov 08 16:03:35 2017 -0500
@@ -102,7 +102,7 @@
/**
* The ASM API version implemented by this visitor. The value of this field
- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected final int api;
@@ -111,10 +111,10 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public SignatureVisitor(final int api) {
- if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+ if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
throw new IllegalArgumentException();
}
this.api = api;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureWriter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureWriter.java Wed Nov 08 16:03:35 2017 -0500
@@ -95,7 +95,7 @@
* Constructs a new {@link SignatureWriter} object.
*/
public SignatureWriter() {
- super(Opcodes.ASM5);
+ super(Opcodes.ASM6);
}
// ------------------------------------------------------------------------
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -65,7 +65,7 @@
import jdk.internal.org.objectweb.asm.Opcodes;
/**
- * A node that represents an annotationn.
+ * A node that represents an annotation.
*
* @author Eric Bruneton
*/
@@ -81,8 +81,8 @@
* as two consecutive elements in the list. The name is a {@link String},
* and the value may be a {@link Byte}, {@link Boolean}, {@link Character},
* {@link Short}, {@link Integer}, {@link Long}, {@link Float},
- * {@link Double}, {@link String} or {@link jdk.internal.org.objectweb.asm.Type}, or an
- * two elements String array (for enumeration values), a
+ * {@link Double}, {@link String} or {@link jdk.internal.org.objectweb.asm.Type}, or a
+ * two elements String array (for enumeration values), an
* {@link AnnotationNode}, or a {@link List} of values of one of the
* preceding types. The list may be <tt>null</tt> if there is no name value
* pair.
@@ -100,7 +100,7 @@
* If a subclass calls this constructor.
*/
public AnnotationNode(final String desc) {
- this(Opcodes.ASM5, desc);
+ this(Opcodes.ASM6, desc);
if (getClass() != AnnotationNode.class) {
throw new IllegalStateException();
}
@@ -111,7 +111,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param desc
* the class descriptor of the annotation class.
*/
@@ -127,7 +127,7 @@
* where the visited values must be stored.
*/
AnnotationNode(final List<Object> values) {
- super(Opcodes.ASM5);
+ super(Opcodes.ASM6);
this.values = values;
}
@@ -143,7 +143,65 @@
if (this.desc != null) {
values.add(name);
}
- values.add(value);
+ if (value instanceof byte[]) {
+ byte[] v = (byte[]) value;
+ ArrayList<Byte> l = new ArrayList<Byte>(v.length);
+ for (byte b : v) {
+ l.add(b);
+ }
+ values.add(l);
+ } else if (value instanceof boolean[]) {
+ boolean[] v = (boolean[]) value;
+ ArrayList<Boolean> l = new ArrayList<Boolean>(v.length);
+ for (boolean b : v) {
+ l.add(b);
+ }
+ values.add(l);
+ } else if (value instanceof short[]) {
+ short[] v = (short[]) value;
+ ArrayList<Short> l = new ArrayList<Short>(v.length);
+ for (short s : v) {
+ l.add(s);
+ }
+ values.add(l);
+ } else if (value instanceof char[]) {
+ char[] v = (char[]) value;
+ ArrayList<Character> l = new ArrayList<Character>(v.length);
+ for (char c : v) {
+ l.add(c);
+ }
+ values.add(l);
+ } else if (value instanceof int[]) {
+ int[] v = (int[]) value;
+ ArrayList<Integer> l = new ArrayList<Integer>(v.length);
+ for (int i : v) {
+ l.add(i);
+ }
+ values.add(l);
+ } else if (value instanceof long[]) {
+ long[] v = (long[]) value;
+ ArrayList<Long> l = new ArrayList<Long>(v.length);
+ for (long lng : v) {
+ l.add(lng);
+ }
+ values.add(l);
+ } else if (value instanceof float[]) {
+ float[] v = (float[]) value;
+ ArrayList<Float> l = new ArrayList<Float>(v.length);
+ for (float f : v) {
+ l.add(f);
+ }
+ values.add(l);
+ } else if (value instanceof double[]) {
+ double[] v = (double[]) value;
+ ArrayList<Double> l = new ArrayList<Double>(v.length);
+ for (double d : v) {
+ l.add(d);
+ }
+ values.add(l);
+ } else {
+ values.add(value);
+ }
}
@Override
@@ -200,8 +258,8 @@
* versions of the ASM API than the given version.
*
* @param api
- * an ASM API version. Must be one of {@link Opcodes#ASM4} or
- * {@link Opcodes#ASM5}.
+ * an ASM API version. Must be one of {@link Opcodes#ASM4},
+ * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public void check(final int api) {
// nothing to do
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ClassNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ClassNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -67,6 +67,7 @@
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.FieldVisitor;
import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.TypePath;
@@ -127,6 +128,11 @@
public String sourceDebug;
/**
+ * Module information. May be <tt>null</tt>.
+ */
+ public ModuleNode module;
+
+ /**
* The internal name of the enclosing class of the class. May be
* <tt>null</tt>.
*/
@@ -221,7 +227,7 @@
* If a subclass calls this constructor.
*/
public ClassNode() {
- this(Opcodes.ASM5);
+ this(Opcodes.ASM6);
if (getClass() != ClassNode.class) {
throw new IllegalStateException();
}
@@ -232,7 +238,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public ClassNode(final int api) {
super(api);
@@ -267,6 +273,12 @@
}
@Override
+ public ModuleVisitor visitModule(final String name, final int access,
+ final String version) {
+ return module = new ModuleNode(name, access, version);
+ }
+
+ @Override
public void visitOuterClass(final String owner, final String name,
final String desc) {
outerClass = owner;
@@ -358,11 +370,16 @@
* API than the given version.
*
* @param api
- * an ASM API version. Must be one of {@link Opcodes#ASM4} or
- * {@link Opcodes#ASM5}.
+ * an ASM API version. Must be one of {@link Opcodes#ASM4},
+ * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public void check(final int api) {
- if (api == Opcodes.ASM4) {
+ if (api < Opcodes.ASM6) {
+ if (module != null) {
+ throw new RuntimeException();
+ }
+ }
+ if (api < Opcodes.ASM5) {
if (visibleTypeAnnotations != null
&& visibleTypeAnnotations.size() > 0) {
throw new RuntimeException();
@@ -371,12 +388,31 @@
&& invisibleTypeAnnotations.size() > 0) {
throw new RuntimeException();
}
- for (FieldNode f : fields) {
- f.check(api);
- }
- for (MethodNode m : methods) {
- m.check(api);
- }
+ }
+ // checks attributes
+ int i, n;
+ n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
+ for (i = 0; i < n; ++i) {
+ visibleAnnotations.get(i).check(api);
+ }
+ n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size();
+ for (i = 0; i < n; ++i) {
+ invisibleAnnotations.get(i).check(api);
+ }
+ n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size();
+ for (i = 0; i < n; ++i) {
+ visibleTypeAnnotations.get(i).check(api);
+ }
+ n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
+ .size();
+ for (i = 0; i < n; ++i) {
+ invisibleTypeAnnotations.get(i).check(api);
+ }
+ for (FieldNode f : fields) {
+ f.check(api);
+ }
+ for (MethodNode m : methods) {
+ m.check(api);
}
}
@@ -395,6 +431,10 @@
if (sourceFile != null || sourceDebug != null) {
cv.visitSource(sourceFile, sourceDebug);
}
+ // visits module
+ if (module != null) {
+ module.accept(cv);
+ }
// visits outer class
if (outerClass != null) {
cv.visitOuterClass(outerClass, outerMethod, outerMethodDesc);
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FieldNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FieldNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -173,7 +173,7 @@
*/
public FieldNode(final int access, final String name, final String desc,
final String signature, final Object value) {
- this(Opcodes.ASM5, access, name, desc, signature, value);
+ this(Opcodes.ASM6, access, name, desc, signature, value);
if (getClass() != FieldNode.class) {
throw new IllegalStateException();
}
@@ -276,8 +276,8 @@
* API than the given version.
*
* @param api
- * an ASM API version. Must be one of {@link Opcodes#ASM4} or
- * {@link Opcodes#ASM5}.
+ * an ASM API version. Must be one of {@link Opcodes#ASM4},
+ * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public void check(final int api) {
if (api == Opcodes.ASM4) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java Wed Nov 08 16:03:35 2017 -0500
@@ -634,14 +634,28 @@
}
public void add(Object o) {
- InsnList.this.insertBefore(next, (AbstractInsnNode) o);
+ if (next != null) {
+ InsnList.this.insertBefore(next, (AbstractInsnNode) o);
+ } else if (prev != null) {
+ InsnList.this.insert(prev, (AbstractInsnNode) o);
+ } else {
+ InsnList.this.add((AbstractInsnNode) o);
+ }
prev = (AbstractInsnNode) o;
remove = null;
}
public void set(Object o) {
- InsnList.this.set(next.prev, (AbstractInsnNode) o);
- prev = (AbstractInsnNode) o;
+ if (remove != null) {
+ InsnList.this.set(remove, (AbstractInsnNode) o);
+ if (remove == prev) {
+ prev = (AbstractInsnNode) o;
+ } else {
+ next = (AbstractInsnNode) o;
+ }
+ } else {
+ throw new IllegalStateException();
+ }
}
}
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableAnnotationNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableAnnotationNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -122,7 +122,7 @@
*/
public LocalVariableAnnotationNode(int typeRef, TypePath typePath,
LabelNode[] start, LabelNode[] end, int[] index, String desc) {
- this(Opcodes.ASM5, typeRef, typePath, start, end, index, desc);
+ this(Opcodes.ASM6, typeRef, typePath, start, end, index, desc);
}
/**
@@ -130,7 +130,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param typeRef
* a reference to the annotated type. See {@link TypeReference}.
* @param start
@@ -181,6 +181,6 @@
index[i] = this.index.get(i);
}
accept(mv.visitLocalVariableAnnotation(typeRef, typePath, start, end,
- index, desc, true));
+ index, desc, visible));
}
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -249,7 +249,7 @@
* If a subclass calls this constructor.
*/
public MethodNode() {
- this(Opcodes.ASM5);
+ this(Opcodes.ASM6);
if (getClass() != MethodNode.class) {
throw new IllegalStateException();
}
@@ -260,7 +260,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public MethodNode(final int api) {
super(api);
@@ -291,7 +291,7 @@
*/
public MethodNode(final int access, final String name, final String desc,
final String signature, final String[] exceptions) {
- this(Opcodes.ASM5, access, name, desc, signature, exceptions);
+ this(Opcodes.ASM6, access, name, desc, signature, exceptions);
if (getClass() != MethodNode.class) {
throw new IllegalStateException();
}
@@ -302,7 +302,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param access
* the method's access flags (see {@link Opcodes}). This
* parameter also indicates if the method is synthetic and/or
@@ -688,8 +688,8 @@
* versions of the ASM API than the given version.
*
* @param api
- * an ASM API version. Must be one of {@link Opcodes#ASM4} or
- * {@link Opcodes#ASM5}.
+ * an ASM API version. Must be one of {@link Opcodes#ASM4},
+ * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public void check(final int api) {
if (api == Opcodes.ASM4) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleExportNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents an exported package with its name and the module that can access to it.
+ *
+ * @author Remi Forax
+ */
+public class ModuleExportNode {
+ /**
+ * The package name.
+ */
+ public String packaze;
+
+ /**
+ * The access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
+ * Valid values are {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+ */
+ public int access;
+
+ /**
+ * A list of modules that can access to this exported package.
+ * May be <tt>null</tt>.
+ */
+ public List<String> modules;
+
+ /**
+ * Constructs a new {@link ModuleExportNode}.
+ *
+ * @param packaze
+ * the parameter's name.
+ * @param modules
+ * a list of modules that can access to this exported package.
+ */
+ public ModuleExportNode(final String packaze, final int access, final List<String> modules) {
+ this.packaze = packaze;
+ this.access = access;
+ this.modules = modules;
+ }
+
+ /**
+ * Makes the given module visitor visit this export declaration.
+ *
+ * @param mv
+ * a module visitor.
+ */
+ public void accept(final ModuleVisitor mv) {
+ mv.visitExport(packaze, access, (modules == null) ? null : modules.toArray(new String[0]));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,280 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.ClassVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+/**
+ * A node that represents a module declaration.
+ *
+ * @author Remi Forax
+ */
+public class ModuleNode extends ModuleVisitor {
+ /**
+ * Module name
+ */
+ public String name;
+
+ /**
+ * Module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC}
+ * and {@code ACC_MANDATED}.
+ */
+ public int access;
+
+ /**
+ * Version of the module.
+ * May be <tt>null</tt>.
+ */
+ public String version;
+
+ /**
+ * Name of the main class in internal form
+ * May be <tt>null</tt>.
+ */
+ public String mainClass;
+
+ /**
+ * A list of packages that are declared by the current module.
+ * May be <tt>null</tt>.
+ */
+ public List<String> packages;
+
+ /**
+ * A list of modules can are required by the current module.
+ * May be <tt>null</tt>.
+ */
+ public List<ModuleRequireNode> requires;
+
+ /**
+ * A list of packages that are exported by the current module.
+ * May be <tt>null</tt>.
+ */
+ public List<ModuleExportNode> exports;
+
+ /**
+ * A list of packages that are opened by the current module.
+ * May be <tt>null</tt>.
+ */
+ public List<ModuleOpenNode> opens;
+
+ /**
+ * A list of classes in their internal forms that are used
+ * as a service by the current module. May be <tt>null</tt>.
+ */
+ public List<String> uses;
+
+ /**
+ * A list of services along with their implementations provided
+ * by the current module. May be <tt>null</tt>.
+ */
+ public List<ModuleProvideNode> provides;
+
+ public ModuleNode(final String name, final int access,
+ final String version) {
+ super(Opcodes.ASM6);
+ this.name = name;
+ this.access = access;
+ this.version = version;
+ }
+
+ public ModuleNode(final int api,
+ final String name,
+ final int access,
+ final String version,
+ final List<ModuleRequireNode> requires,
+ final List<ModuleExportNode> exports,
+ final List<ModuleOpenNode> opens,
+ final List<String> uses,
+ final List<ModuleProvideNode> provides) {
+ super(api);
+ this.name = name;
+ this.access = access;
+ this.version = version;
+ this.requires = requires;
+ this.exports = exports;
+ this.opens = opens;
+ this.uses = uses;
+ this.provides = provides;
+ if (getClass() != ModuleNode.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ @Override
+ public void visitMainClass(String mainClass) {
+ this.mainClass = mainClass;
+ }
+
+ @Override
+ public void visitPackage(String packaze) {
+ if (packages == null) {
+ packages = new ArrayList<String>(5);
+ }
+ packages.add(packaze);
+ }
+
+ @Override
+ public void visitRequire(String module, int access, String version) {
+ if (requires == null) {
+ requires = new ArrayList<ModuleRequireNode>(5);
+ }
+ requires.add(new ModuleRequireNode(module, access, version));
+ }
+
+ @Override
+ public void visitExport(String packaze, int access, String... modules) {
+ if (exports == null) {
+ exports = new ArrayList<ModuleExportNode>(5);
+ }
+ List<String> moduleList = null;
+ if (modules != null) {
+ moduleList = new ArrayList<String>(modules.length);
+ for (int i = 0; i < modules.length; i++) {
+ moduleList.add(modules[i]);
+ }
+ }
+ exports.add(new ModuleExportNode(packaze, access, moduleList));
+ }
+
+ @Override
+ public void visitOpen(String packaze, int access, String... modules) {
+ if (opens == null) {
+ opens = new ArrayList<ModuleOpenNode>(5);
+ }
+ List<String> moduleList = null;
+ if (modules != null) {
+ moduleList = new ArrayList<String>(modules.length);
+ for (int i = 0; i < modules.length; i++) {
+ moduleList.add(modules[i]);
+ }
+ }
+ opens.add(new ModuleOpenNode(packaze, access, moduleList));
+ }
+
+ @Override
+ public void visitUse(String service) {
+ if (uses == null) {
+ uses = new ArrayList<String>(5);
+ }
+ uses.add(service);
+ }
+
+ @Override
+ public void visitProvide(String service, String... providers) {
+ if (provides == null) {
+ provides = new ArrayList<ModuleProvideNode>(5);
+ }
+ ArrayList<String> providerList =
+ new ArrayList<String>(providers.length);
+ for (int i = 0; i < providers.length; i++) {
+ providerList.add(providers[i]);
+ }
+ provides.add(new ModuleProvideNode(service, providerList));
+ }
+
+ @Override
+ public void visitEnd() {
+ }
+
+ public void accept(final ClassVisitor cv) {
+ ModuleVisitor mv = cv.visitModule(name, access, version);
+ if (mv == null) {
+ return;
+ }
+ if (mainClass != null) {
+ mv.visitMainClass(mainClass);
+ }
+ if (packages != null) {
+ for (int i = 0; i < packages.size(); i++) {
+ mv.visitPackage(packages.get(i));
+ }
+ }
+
+ if (requires != null) {
+ for (int i = 0; i < requires.size(); i++) {
+ requires.get(i).accept(mv);
+ }
+ }
+ if (exports != null) {
+ for (int i = 0; i < exports.size(); i++) {
+ exports.get(i).accept(mv);
+ }
+ }
+ if (opens != null) {
+ for (int i = 0; i < opens.size(); i++) {
+ opens.get(i).accept(mv);
+ }
+ }
+ if (uses != null) {
+ for (int i = 0; i < uses.size(); i++) {
+ mv.visitUse(uses.get(i));
+ }
+ }
+ if (provides != null) {
+ for (int i = 0; i < provides.size(); i++) {
+ provides.get(i).accept(mv);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleOpenNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents an opened package with its name and the module that can access to it.
+ *
+ * @author Remi Forax
+ */
+public class ModuleOpenNode {
+ /**
+ * The package name.
+ */
+ public String packaze;
+
+ /**
+ * The access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
+ * Valid values are {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+ */
+ public int access;
+
+ /**
+ * A list of modules that can access to this exported package.
+ * May be <tt>null</tt>.
+ */
+ public List<String> modules;
+
+ /**
+ * Constructs a new {@link ModuleOpenNode}.
+ *
+ * @param packaze
+ * the parameter's name.
+ * @param modules
+ * a list of modules that can access to this open package.
+ */
+ public ModuleOpenNode(final String packaze, final int access, final List<String> modules) {
+ this.packaze = packaze;
+ this.access = access;
+ this.modules = modules;
+ }
+
+ /**
+ * Makes the given module visitor visit this open declaration.
+ *
+ * @param mv
+ * a module visitor.
+ */
+ public void accept(final ModuleVisitor mv) {
+ mv.visitExport(packaze, access, (modules == null) ? null : modules.toArray(new String[0]));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleProvideNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents a service and its implementation provided by the current module.
+ *
+ * @author Remi Forax
+ */
+public class ModuleProvideNode {
+ /**
+ * The service name (in its internal form).
+ */
+ public String service;
+
+ /**
+ * The service provider names (in their internal form).
+ */
+ public List<String> providers;
+
+ /**
+ * Constructs a new {@link ModuleProvideNode}.
+ *
+ * @param service
+ * the service name (in its internal form).
+ * @param providers
+ * the service provider names (in their internal form).
+ */
+ public ModuleProvideNode(final String service, final List<String> providers) {
+ this.service = service;
+ this.providers = providers;
+ }
+
+ /**
+ * Makes the given module visitor visit this require declaration.
+ *
+ * @param mv
+ * a module visitor.
+ */
+ public void accept(final ModuleVisitor mv) {
+ mv.visitProvide(service, providers.toArray(new String[0]));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleRequireNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents a required module with its name and access of a module descriptor.
+ *
+ * @author Remi Forax
+ */
+public class ModuleRequireNode {
+ /**
+ * The name of the required module.
+ */
+ public String module;
+
+ /**
+ * The access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
+ * Valid values are <tt>ACC_TRANSITIVE</tt>, <tt>ACC_STATIC_PHASE</tt>,
+ * <tt>ACC_SYNTHETIC</tt> and <tt>ACC_MANDATED</tt>.
+ */
+ public int access;
+
+ /**
+ * Version at compile time of the required module or null.
+ */
+ public String version;
+
+ /**
+ * Constructs a new {@link ModuleRequireNode}.
+ *
+ * @param module
+ * the name of the required module.
+ * @param access
+ * The access flags. Valid values are
+ * <tt>ACC_TRANSITIVE</tt>, <tt>ACC_STATIC_PHASE</tt>,
+ * <tt>ACC_SYNTHETIC</tt> and <tt>ACC_MANDATED</tt>
+ * (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
+ * @param version
+ * Version of the required module at compile time,
+ * null if not defined.
+ */
+ public ModuleRequireNode(final String module, final int access,
+ final String version) {
+ this.module = module;
+ this.access = access;
+ this.version = version;
+ }
+
+ /**
+ * Makes the given module visitor visit this require directive.
+ *
+ * @param mv
+ * a module visitor.
+ */
+ public void accept(final ModuleVisitor mv) {
+ mv.visitRequire(module, access, version);
+ }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TypeAnnotationNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TypeAnnotationNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -99,7 +99,7 @@
*/
public TypeAnnotationNode(final int typeRef, final TypePath typePath,
final String desc) {
- this(Opcodes.ASM5, typeRef, typePath, desc);
+ this(Opcodes.ASM6, typeRef, typePath, desc);
if (getClass() != TypeAnnotationNode.class) {
throw new IllegalStateException();
}
@@ -110,7 +110,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param typeRef
* a reference to the annotated type. See {@link TypeReference}.
* @param typePath
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicInterpreter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicInterpreter.java Wed Nov 08 16:03:35 2017 -0500
@@ -82,7 +82,7 @@
Opcodes {
public BasicInterpreter() {
- super(ASM5);
+ super(ASM6);
}
protected BasicInterpreter(final int api) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicVerifier.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicVerifier.java Wed Nov 08 16:03:35 2017 -0500
@@ -76,7 +76,7 @@
public class BasicVerifier extends BasicInterpreter {
public BasicVerifier() {
- super(ASM5);
+ super(ASM6);
}
protected BasicVerifier(final int api) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SimpleVerifier.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SimpleVerifier.java Wed Nov 08 16:03:35 2017 -0500
@@ -136,7 +136,7 @@
public SimpleVerifier(final Type currentClass,
final Type currentSuperClass,
final List<Type> currentClassInterfaces, final boolean isInterface) {
- this(ASM5, currentClass, currentSuperClass, currentClassInterfaces,
+ this(ASM6, currentClass, currentSuperClass, currentClassInterfaces,
isInterface);
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceInterpreter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceInterpreter.java Wed Nov 08 16:03:35 2017 -0500
@@ -79,7 +79,7 @@
Opcodes {
public SourceInterpreter() {
- super(ASM5);
+ super(ASM6);
}
protected SourceInterpreter(final int api) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java Wed Nov 08 16:03:35 2017 -0500
@@ -110,6 +110,11 @@
private static final int ACCESS_INNER = 1048576;
/**
+ * Pseudo access flag used to distinguish module requires/exports flags.
+ */
+ private static final int ACCESS_MODULE = 2097152;
+
+ /**
* Constructs a new {@link ASMifier}. <i>Subclasses must not use this
* constructor</i>. Instead, they must use the
* {@link #ASMifier(int, String, int)} version.
@@ -118,7 +123,7 @@
* If a subclass calls this constructor.
*/
public ASMifier() {
- this(Opcodes.ASM5, "cw", 0);
+ this(Opcodes.ASM6, "cw", 0);
if (getClass() != ASMifier.class) {
throw new IllegalStateException();
}
@@ -129,7 +134,7 @@
*
* @param api
* the ASM API version implemented by this class. Must be one of
- * {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param name
* the name of the visitor variable in the produced code.
* @param id
@@ -196,13 +201,17 @@
final String signature, final String superName,
final String[] interfaces) {
String simpleName;
- int n = name.lastIndexOf('/');
- if (n == -1) {
- simpleName = name;
+ if (name == null) {
+ simpleName = "module-info";
} else {
- text.add("package asm." + name.substring(0, n).replace('/', '.')
- + ";\n");
- simpleName = name.substring(n + 1);
+ int n = name.lastIndexOf('/');
+ if (n == -1) {
+ simpleName = name;
+ } else {
+ text.add("package asm." + name.substring(0, n).replace('/', '.')
+ + ";\n");
+ simpleName = name.substring(n + 1).replace('-', '_');
+ }
}
text.add("import java.util.*;\n");
text.add("import jdk.internal.org.objectweb.asm.*;\n");
@@ -237,6 +246,12 @@
case Opcodes.V1_7:
buf.append("V1_7");
break;
+ case Opcodes.V1_8:
+ buf.append("V1_8");
+ break;
+ case Opcodes.V9:
+ buf.append("V9");
+ break;
default:
buf.append(version);
break;
@@ -276,6 +291,24 @@
}
@Override
+ public Printer visitModule(final String name, final int flags,
+ final String version) {
+ buf.setLength(0);
+ buf.append("ModuleVisitor mdv = cw.visitModule(");
+ appendConstant(name);
+ buf.append(", ");
+ appendAccess(flags | ACCESS_MODULE);
+ buf.append(", ");
+ appendConstant(version);
+ buf.append(");\n\n");
+ text.add(buf.toString());
+ ASMifier a = createASMifier("mdv", 0);
+ text.add(a.getText());
+ text.add("}\n");
+ return a;
+ }
+
+ @Override
public void visitOuterClass(final String owner, final String name,
final String desc) {
buf.setLength(0);
@@ -386,6 +419,108 @@
}
// ------------------------------------------------------------------------
+ // Module
+ // ------------------------------------------------------------------------
+
+ @Override
+ public void visitMainClass(String mainClass) {
+ buf.setLength(0);
+ buf.append("mdv.visitMainClass(");
+ appendConstant(buf, mainClass);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitPackage(String packaze) {
+ buf.setLength(0);
+ buf.append("mdv.visitPackage(");
+ appendConstant(buf, packaze);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitRequire(String module, int access, String version) {
+ buf.setLength(0);
+ buf.append("mdv.visitRequire(");
+ appendConstant(buf, module);
+ buf.append(", ");
+ appendAccess(access | ACCESS_MODULE);
+ buf.append(", ");
+ appendConstant(buf, version);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitExport(String packaze, int access, String... modules) {
+ buf.setLength(0);
+ buf.append("mdv.visitExport(");
+ appendConstant(buf, packaze);
+ buf.append(", ");
+ appendAccess(access | ACCESS_MODULE);
+ if (modules != null && modules.length > 0) {
+ buf.append(", new String[] {");
+ for (int i = 0; i < modules.length; ++i) {
+ buf.append(i == 0 ? " " : ", ");
+ appendConstant(modules[i]);
+ }
+ buf.append(" }");
+ }
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitOpen(String packaze, int access, String... modules) {
+ buf.setLength(0);
+ buf.append("mdv.visitOpen(");
+ appendConstant(buf, packaze);
+ buf.append(", ");
+ appendAccess(access | ACCESS_MODULE);
+ if (modules != null && modules.length > 0) {
+ buf.append(", new String[] {");
+ for (int i = 0; i < modules.length; ++i) {
+ buf.append(i == 0 ? " " : ", ");
+ appendConstant(modules[i]);
+ }
+ buf.append(" }");
+ }
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitUse(String service) {
+ buf.setLength(0);
+ buf.append("mdv.visitUse(");
+ appendConstant(buf, service);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitProvide(String service, String... providers) {
+ buf.setLength(0);
+ buf.append("mdv.visitProvide(");
+ appendConstant(buf, service);
+ buf.append(", new String[] {");
+ for (int i = 0; i < providers.length; ++i) {
+ buf.append(i == 0 ? " " : ", ");
+ appendConstant(providers[i]);
+ }
+ buf.append(" });\n");
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitModuleEnd() {
+ text.add("mdv.visitEnd();\n");
+ }
+
+
+ // ------------------------------------------------------------------------
// Annotations
// ------------------------------------------------------------------------
@@ -972,7 +1107,7 @@
// ------------------------------------------------------------------------
protected ASMifier createASMifier(final String name, final int id) {
- return new ASMifier(Opcodes.ASM5, name, id);
+ return new ASMifier(Opcodes.ASM6, name, id);
}
/**
@@ -1000,7 +1135,11 @@
if (!first) {
buf.append(" + ");
}
- buf.append("ACC_FINAL");
+ if ((access & ACCESS_MODULE) == 0) {
+ buf.append("ACC_FINAL");
+ } else {
+ buf.append("ACC_TRANSITIVE");
+ }
first = false;
}
if ((access & Opcodes.ACC_STATIC) != 0) {
@@ -1010,31 +1149,35 @@
buf.append("ACC_STATIC");
first = false;
}
- if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) {
+ if ((access & (Opcodes.ACC_SYNCHRONIZED | Opcodes.ACC_SUPER | Opcodes.ACC_TRANSITIVE)) != 0) {
if (!first) {
buf.append(" + ");
}
if ((access & ACCESS_CLASS) == 0) {
- buf.append("ACC_SYNCHRONIZED");
+ if ((access & ACCESS_MODULE) == 0) {
+ buf.append("ACC_SYNCHRONIZED");
+ } else {
+ buf.append("ACC_TRANSITIVE");
+ }
} else {
buf.append("ACC_SUPER");
}
first = false;
}
- if ((access & Opcodes.ACC_VOLATILE) != 0
- && (access & ACCESS_FIELD) != 0) {
+ if ((access & (Opcodes.ACC_VOLATILE | Opcodes.ACC_BRIDGE | Opcodes.ACC_STATIC_PHASE)) != 0) {
if (!first) {
buf.append(" + ");
}
- buf.append("ACC_VOLATILE");
- first = false;
- }
- if ((access & Opcodes.ACC_BRIDGE) != 0 && (access & ACCESS_CLASS) == 0
- && (access & ACCESS_FIELD) == 0) {
- if (!first) {
- buf.append(" + ");
+ if ((access & ACCESS_FIELD) == 0) {
+ if ((access & ACCESS_MODULE) == 0) {
+ buf.append("ACC_BRIDGE");
+ } else {
+ buf.append("ACC_STATIC_PHASE");
+ }
+ } else {
+ buf.append("ACC_VOLATILE");
}
- buf.append("ACC_BRIDGE");
+
first = false;
}
if ((access & Opcodes.ACC_VARARGS) != 0 && (access & ACCESS_CLASS) == 0
@@ -1113,11 +1256,15 @@
buf.append("ACC_DEPRECATED");
first = false;
}
- if ((access & Opcodes.ACC_MANDATED) != 0) {
+ if ((access & (Opcodes.ACC_MANDATED | Opcodes.ACC_MODULE)) != 0) {
if (!first) {
buf.append(" + ");
}
- buf.append("ACC_MANDATED");
+ if ((access & ACCESS_CLASS) == 0) {
+ buf.append("ACC_MANDATED");
+ } else {
+ buf.append("ACC_MODULE");
+ }
first = false;
}
if (first) {
@@ -1163,7 +1310,8 @@
.append(", \"");
buf.append(h.getOwner()).append("\", \"");
buf.append(h.getName()).append("\", \"");
- buf.append(h.getDesc()).append("\")");
+ buf.append(h.getDesc()).append("\", ");
+ buf.append(h.isInterface()).append(")");
} else if (cst instanceof Byte) {
buf.append("new Byte((byte)").append(cst).append(')');
} else if (cst instanceof Boolean) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckAnnotationAdapter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckAnnotationAdapter.java Wed Nov 08 16:03:35 2017 -0500
@@ -78,7 +78,7 @@
}
CheckAnnotationAdapter(final AnnotationVisitor av, final boolean named) {
- super(Opcodes.ASM5, av);
+ super(Opcodes.ASM6, av);
this.named = named;
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java Wed Nov 08 16:03:35 2017 -0500
@@ -73,6 +73,7 @@
import jdk.internal.org.objectweb.asm.FieldVisitor;
import jdk.internal.org.objectweb.asm.Label;
import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type;
import jdk.internal.org.objectweb.asm.TypePath;
@@ -181,6 +182,11 @@
private boolean end;
/**
+ * <tt>true</tt> if the visitModule method has been called.
+ */
+ private boolean module;
+
+ /**
* The already visited labels. This map associate Integer values to Label
* keys.
*/
@@ -363,7 +369,7 @@
* If a subclass calls this constructor.
*/
public CheckClassAdapter(final ClassVisitor cv, final boolean checkDataFlow) {
- this(Opcodes.ASM5, cv, checkDataFlow);
+ this(Opcodes.ASM6, cv, checkDataFlow);
if (getClass() != CheckClassAdapter.class) {
throw new IllegalStateException();
}
@@ -374,7 +380,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param cv
* the class visitor to which this adapter must delegate calls.
* @param checkDataFlow
@@ -407,8 +413,12 @@
+ Opcodes.ACC_SUPER + Opcodes.ACC_INTERFACE
+ Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC
+ Opcodes.ACC_ANNOTATION + Opcodes.ACC_ENUM
- + Opcodes.ACC_DEPRECATED + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
- if (name == null || !name.endsWith("package-info")) {
+ + Opcodes.ACC_DEPRECATED + Opcodes.ACC_MODULE
+ + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
+ if (name == null) {
+ throw new IllegalArgumentException("Illegal class name (null)");
+ }
+ if (!name.endsWith("package-info")) {
CheckMethodAdapter.checkInternalName(name, "class name");
}
if ("java/lang/Object".equals(name)) {
@@ -450,6 +460,22 @@
}
@Override
+ public ModuleVisitor visitModule(String name, int access, String version) {
+ checkState();
+ if (module) {
+ throw new IllegalStateException(
+ "visitModule can be called only once.");
+ }
+ module = true;
+ if (name == null) {
+ throw new IllegalArgumentException("Illegal module name (null)");
+ }
+ checkAccess(access, Opcodes.ACC_OPEN | Opcodes.ACC_SYNTHETIC);
+ return new CheckModuleAdapter(super.visitModule(name, access, version),
+ (access & Opcodes.ACC_OPEN) != 0);
+ }
+
+ @Override
public void visitOuterClass(final String owner, final String name,
final String desc) {
checkState();
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckFieldAdapter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckFieldAdapter.java Wed Nov 08 16:03:35 2017 -0500
@@ -83,7 +83,7 @@
* If a subclass calls this constructor.
*/
public CheckFieldAdapter(final FieldVisitor fv) {
- this(Opcodes.ASM5, fv);
+ this(Opcodes.ASM6, fv);
if (getClass() != CheckFieldAdapter.class) {
throw new IllegalStateException();
}
@@ -94,7 +94,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param fv
* the field visitor to which this adapter must delegate calls.
*/
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java Wed Nov 08 16:03:35 2017 -0500
@@ -426,7 +426,7 @@
*/
public CheckMethodAdapter(final MethodVisitor mv,
final Map<Label, Integer> labels) {
- this(Opcodes.ASM5, mv, labels);
+ this(Opcodes.ASM6, mv, labels);
if (getClass() != CheckMethodAdapter.class) {
throw new IllegalStateException();
}
@@ -439,7 +439,8 @@
*
* @param api
* the ASM API version implemented by this CheckMethodAdapter.
- * Must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * Must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5}
+ * or {@link Opcodes#ASM6}.
* @param mv
* the method visitor to which this adapter must delegate calls.
* @param labels
@@ -756,6 +757,12 @@
throw new IllegalArgumentException(
"INVOKEINTERFACE can't be used with classes");
}
+ if (opcode == Opcodes.INVOKESPECIAL && itf
+ && (version & 0xFFFF) < Opcodes.V1_8) {
+ throw new IllegalArgumentException(
+ "INVOKESPECIAL can't be used with interfaces prior to Java 8");
+ }
+
// Calling super.visitMethodInsn requires to call the correct version
// depending on this.api (otherwise infinite loops can occur). To
// simplify and to make it easier to automatically remove the backward
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckModuleAdapter.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,180 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.util;
+
+import java.util.HashSet;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+/**
+ * @author Remi Forax
+ */
+public final class CheckModuleAdapter extends ModuleVisitor {
+ private boolean end;
+ private final boolean isOpen;
+
+ private final HashSet<String> requireNames = new HashSet<String>();
+ private final HashSet<String> exportNames = new HashSet<String>();
+ private final HashSet<String> openNames = new HashSet<String>();
+ private final HashSet<String> useNames = new HashSet<String>();
+ private final HashSet<String> provideNames = new HashSet<String>();
+
+ public CheckModuleAdapter(final ModuleVisitor mv, final boolean isOpen) {
+ super(Opcodes.ASM6, mv);
+ this.isOpen = isOpen;
+ }
+
+ @Override
+ public void visitRequire(String module, int access, String version) {
+ checkEnd();
+ if (module == null) {
+ throw new IllegalArgumentException("require cannot be null");
+ }
+ checkDeclared("requires", requireNames, module);
+ CheckClassAdapter.checkAccess(access, Opcodes.ACC_STATIC_PHASE
+ + Opcodes.ACC_TRANSITIVE + Opcodes.ACC_SYNTHETIC + Opcodes.ACC_MANDATED);
+ super.visitRequire(module, access, version);
+ }
+
+ @Override
+ public void visitExport(String packaze, int access, String... modules) {
+ checkEnd();
+ if (packaze == null) {
+ throw new IllegalArgumentException("packaze cannot be null");
+ }
+ CheckMethodAdapter.checkInternalName(packaze, "package name");
+ checkDeclared("exports", exportNames, packaze);
+ CheckClassAdapter.checkAccess(access, Opcodes.ACC_SYNTHETIC
+ + Opcodes.ACC_MANDATED);
+ if (modules != null) {
+ for (int i = 0; i < modules.length; i++) {
+ if (modules[i] == null) {
+ throw new IllegalArgumentException("module at index " + i + " cannot be null");
+ }
+ }
+ }
+ super.visitExport(packaze, access, modules);
+ }
+
+ @Override
+ public void visitOpen(String packaze, int access, String... modules) {
+ checkEnd();
+ if (isOpen) {
+ throw new IllegalArgumentException("an open module can not use open directive");
+ }
+ if (packaze == null) {
+ throw new IllegalArgumentException("packaze cannot be null");
+ }
+ CheckMethodAdapter.checkInternalName(packaze, "package name");
+ checkDeclared("opens", openNames, packaze);
+ CheckClassAdapter.checkAccess(access, Opcodes.ACC_SYNTHETIC
+ + Opcodes.ACC_MANDATED);
+ if (modules != null) {
+ for (int i = 0; i < modules.length; i++) {
+ if (modules[i] == null) {
+ throw new IllegalArgumentException("module at index " + i + " cannot be null");
+ }
+ }
+ }
+ super.visitOpen(packaze, access, modules);
+ }
+
+ @Override
+ public void visitUse(String service) {
+ checkEnd();
+ CheckMethodAdapter.checkInternalName(service, "service");
+ checkDeclared("uses", useNames, service);
+ super.visitUse(service);
+ }
+
+ @Override
+ public void visitProvide(String service, String... providers) {
+ checkEnd();
+ CheckMethodAdapter.checkInternalName(service, "service");
+ checkDeclared("provides", provideNames, service);
+ if (providers == null || providers.length == 0) {
+ throw new IllegalArgumentException("providers cannot be null or empty");
+ }
+ for (int i = 0; i < providers.length; i++) {
+ CheckMethodAdapter.checkInternalName(providers[i], "provider");
+ }
+ super.visitProvide(service, providers);
+ }
+
+ @Override
+ public void visitEnd() {
+ checkEnd();
+ end = true;
+ super.visitEnd();
+ }
+
+ private void checkEnd() {
+ if (end) {
+ throw new IllegalStateException(
+ "Cannot call a visit method after visitEnd has been called");
+ }
+ }
+
+ private static void checkDeclared(String directive, HashSet<String> names, String name) {
+ if (!names.add(name)) {
+ throw new IllegalArgumentException(directive + " " + name + " already declared");
+ }
+ }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckSignatureAdapter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckSignatureAdapter.java Wed Nov 08 16:03:35 2017 -0500
@@ -142,7 +142,7 @@
* <tt>null</tt>.
*/
public CheckSignatureAdapter(final int type, final SignatureVisitor sv) {
- this(Opcodes.ASM5, type, sv);
+ this(Opcodes.ASM6, type, sv);
}
/**
@@ -150,7 +150,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param type
* the type of signature to be checked. See
* {@link #CLASS_SIGNATURE}, {@link #METHOD_SIGNATURE} and
@@ -175,7 +175,7 @@
|| (state != EMPTY && state != FORMAL && state != BOUND)) {
throw new IllegalStateException();
}
- CheckMethodAdapter.checkIdentifier(name, "formal type parameter");
+ checkIdentifier(name, "formal type parameter");
state = FORMAL;
if (sv != null) {
sv.visitFormalTypeParameter(name);
@@ -284,7 +284,7 @@
if (type != TYPE_SIGNATURE || state != EMPTY) {
throw new IllegalStateException();
}
- CheckMethodAdapter.checkIdentifier(name, "type variable");
+ checkIdentifier(name, "type variable");
state = SIMPLE_TYPE;
if (sv != null) {
sv.visitTypeVariable(name);
@@ -306,7 +306,7 @@
if (type != TYPE_SIGNATURE || state != EMPTY) {
throw new IllegalStateException();
}
- CheckMethodAdapter.checkInternalName(name, "class name");
+ checkClassName(name, "class name");
state = CLASS_TYPE;
if (sv != null) {
sv.visitClassType(name);
@@ -318,7 +318,7 @@
if (state != CLASS_TYPE) {
throw new IllegalStateException();
}
- CheckMethodAdapter.checkIdentifier(name, "inner class name");
+ checkIdentifier(name, "inner class name");
if (sv != null) {
sv.visitInnerClassType(name);
}
@@ -356,4 +356,30 @@
sv.visitEnd();
}
}
+
+ private void checkClassName(final String name, final String msg) {
+ if (name == null || name.length() == 0) {
+ throw new IllegalArgumentException("Invalid " + msg
+ + " (must not be null or empty)");
+ }
+ for (int i = 0; i < name.length(); ++i) {
+ if (".;[<>:".indexOf(name.charAt(i)) != -1) {
+ throw new IllegalArgumentException("Invalid " + msg
+ + " (must not contain . ; [ < > or :): " + name);
+ }
+ }
+ }
+
+ private void checkIdentifier(final String name, final String msg) {
+ if (name == null || name.length() == 0) {
+ throw new IllegalArgumentException("Invalid " + msg
+ + " (must not be null or empty)");
+ }
+ for (int i = 0; i < name.length(); ++i) {
+ if (".;[/<>:".indexOf(name.charAt(i)) != -1) {
+ throw new IllegalArgumentException("Invalid " + msg
+ + " (must not contain . ; [ / < > or :): " + name);
+ }
+ }
+ }
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java Wed Nov 08 16:03:35 2017 -0500
@@ -146,7 +146,7 @@
/**
* The ASM API version implemented by this class. The value of this field
- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected final int api;
@@ -174,7 +174,7 @@
*
* @param api
* the ASM API version implemented by this printer. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected Printer(final int api) {
this.api = api;
@@ -226,6 +226,24 @@
*/
public abstract void visitSource(final String source, final String debug);
+
+ /**
+ * Module.
+ * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitModule(String, int)}.
+ *
+ * @param name
+ * module name.
+ * @param access
+ * module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC}
+ * and {@code ACC_MANDATED}.
+ * @param version
+ * module version or null.
+ * @return
+ */
+ public Printer visitModule(String name, int access, String version) {
+ throw new RuntimeException("Must be overriden");
+ }
+
/**
* Class outer class.
* See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitOuterClass}.
@@ -376,6 +394,45 @@
public abstract void visitClassEnd();
// ------------------------------------------------------------------------
+ // Module
+ // ------------------------------------------------------------------------
+
+ public void visitMainClass(String mainClass) {
+ throw new RuntimeException("Must be overriden");
+ }
+
+ public void visitPackage(String packaze) {
+ throw new RuntimeException("Must be overriden");
+ }
+
+ public void visitRequire(String module, int access, String version) {
+ throw new RuntimeException("Must be overriden");
+ }
+
+ public void visitExport(String packaze, int access, String... modules) {
+ throw new RuntimeException("Must be overriden");
+ }
+
+ public void visitOpen(String packaze, int access, String... modules) {
+ throw new RuntimeException("Must be overriden");
+ }
+
+ public void visitUse(String service) {
+ throw new RuntimeException("Must be overriden");
+ }
+
+ public void visitProvide(String service, String... providers) {
+ throw new RuntimeException("Must be overriden");
+ }
+
+ /**
+ * Module end. See {@link jdk.internal.org.objectweb.asm.ModuleVisitor#visitEnd}.
+ */
+ public void visitModuleEnd() {
+ throw new RuntimeException("Must be overriden");
+ }
+
+ // ------------------------------------------------------------------------
// Annotations
// ------------------------------------------------------------------------
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java Wed Nov 08 16:03:35 2017 -0500
@@ -182,7 +182,7 @@
* If a subclass calls this constructor.
*/
public Textifier() {
- this(Opcodes.ASM5);
+ this(Opcodes.ASM6);
if (getClass() != Textifier.class) {
throw new IllegalStateException();
}
@@ -193,7 +193,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected Textifier(final int api) {
super(api);
@@ -250,6 +250,10 @@
public void visit(final int version, final int access, final String name,
final String signature, final String superName,
final String[] interfaces) {
+ if ((access & Opcodes.ACC_MODULE) != 0) {
+ // visitModule will print the module
+ return;
+ }
this.access = access;
int major = version & 0xFFFF;
int minor = version >>> 16;
@@ -271,7 +275,7 @@
.append(sv.getDeclaration()).append('\n');
}
- appendAccess(access & ~Opcodes.ACC_SUPER);
+ appendAccess(access & ~(Opcodes.ACC_SUPER | Opcodes.ACC_MODULE));
if ((access & Opcodes.ACC_ANNOTATION) != 0) {
buf.append("@interface ");
} else if ((access & Opcodes.ACC_INTERFACE) != 0) {
@@ -315,6 +319,24 @@
}
@Override
+ public Printer visitModule(final String name, final int access,
+ final String version) {
+ buf.setLength(0);
+ if ((access & Opcodes.ACC_OPEN) != 0) {
+ buf.append("open ");
+ }
+ buf.append("module ")
+ .append(name)
+ .append(" { ")
+ .append(version == null ? "" : "// " + version)
+ .append("\n\n");
+ text.add(buf.toString());
+ Textifier t = createTextifier();
+ text.add(t.getText());
+ return t;
+ }
+
+ @Override
public void visitOuterClass(final String owner, final String name,
final String desc) {
buf.setLength(0);
@@ -443,7 +465,7 @@
}
buf.append(tab);
- appendAccess(access & ~Opcodes.ACC_VOLATILE);
+ appendAccess(access & ~(Opcodes.ACC_VOLATILE | Opcodes.ACC_TRANSIENT));
if ((access & Opcodes.ACC_NATIVE) != 0) {
buf.append("native ");
}
@@ -483,6 +505,118 @@
}
// ------------------------------------------------------------------------
+ // Module
+ // ------------------------------------------------------------------------
+
+ @Override
+ public void visitMainClass(String mainClass) {
+ buf.setLength(0);
+ buf.append(" // main class ").append(mainClass).append('\n');
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitPackage(String packaze) {
+ buf.setLength(0);
+ buf.append(" // package ").append(packaze).append('\n');
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitRequire(String require, int access, String version) {
+ buf.setLength(0);
+ buf.append(tab).append("requires ");
+ if ((access & Opcodes.ACC_TRANSITIVE) != 0) {
+ buf.append("transitive ");
+ }
+ if ((access & Opcodes.ACC_STATIC_PHASE) != 0) {
+ buf.append("static ");
+ }
+ buf.append(require)
+ .append("; // access flags 0x")
+ .append(Integer.toHexString(access).toUpperCase())
+ .append('\n');
+ if (version != null) {
+ buf.append(" // version ")
+ .append(version)
+ .append('\n');
+ }
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitExport(String export, int access, String... modules) {
+ buf.setLength(0);
+ buf.append(tab).append("exports ");
+ buf.append(export);
+ if (modules != null && modules.length > 0) {
+ buf.append(" to");
+ } else {
+ buf.append(';');
+ }
+ buf.append(" // access flags 0x")
+ .append(Integer.toHexString(access).toUpperCase())
+ .append('\n');
+ if (modules != null && modules.length > 0) {
+ for (int i = 0; i < modules.length; ++i) {
+ buf.append(tab2).append(modules[i]);
+ buf.append(i != modules.length - 1 ? ",\n": ";\n");
+ }
+ }
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitOpen(String export, int access, String... modules) {
+ buf.setLength(0);
+ buf.append(tab).append("opens ");
+ buf.append(export);
+ if (modules != null && modules.length > 0) {
+ buf.append(" to");
+ } else {
+ buf.append(';');
+ }
+ buf.append(" // access flags 0x")
+ .append(Integer.toHexString(access).toUpperCase())
+ .append('\n');
+ if (modules != null && modules.length > 0) {
+ for (int i = 0; i < modules.length; ++i) {
+ buf.append(tab2).append(modules[i]);
+ buf.append(i != modules.length - 1 ? ",\n": ";\n");
+ }
+ }
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitUse(String use) {
+ buf.setLength(0);
+ buf.append(tab).append("uses ");
+ appendDescriptor(INTERNAL_NAME, use);
+ buf.append(";\n");
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitProvide(String provide, String... providers) {
+ buf.setLength(0);
+ buf.append(tab).append("provides ");
+ appendDescriptor(INTERNAL_NAME, provide);
+ buf.append(" with\n");
+ for (int i = 0; i < providers.length; ++i) {
+ buf.append(tab2);
+ appendDescriptor(INTERNAL_NAME, providers[i]);
+ buf.append(i != providers.length - 1 ? ",\n": ";\n");
+ }
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitModuleEnd() {
+ // empty
+ }
+
+ // ------------------------------------------------------------------------
// Annotations
// ------------------------------------------------------------------------
@@ -1296,13 +1430,16 @@
appendDescriptor(INTERNAL_NAME, h.getOwner());
buf.append('.');
buf.append(h.getName());
- if(!isMethodHandle){
+ if (!isMethodHandle) {
buf.append('(');
}
appendDescriptor(HANDLE_DESCRIPTOR, h.getDesc());
- if(!isMethodHandle){
+ if (!isMethodHandle) {
buf.append(')');
}
+ if (h.isInterface()) {
+ buf.append(" itf");
+ }
}
/**
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceAnnotationVisitor.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceAnnotationVisitor.java Wed Nov 08 16:03:35 2017 -0500
@@ -76,7 +76,7 @@
}
public TraceAnnotationVisitor(final AnnotationVisitor av, final Printer p) {
- super(Opcodes.ASM5, av);
+ super(Opcodes.ASM6, av);
this.p = p;
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java Wed Nov 08 16:03:35 2017 -0500
@@ -65,6 +65,7 @@
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.FieldVisitor;
import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.TypePath;
@@ -160,7 +161,7 @@
*/
public TraceClassVisitor(final ClassVisitor cv, final Printer p,
final PrintWriter pw) {
- super(Opcodes.ASM5, cv);
+ super(Opcodes.ASM6, cv);
this.pw = pw;
this.p = p;
}
@@ -180,6 +181,14 @@
}
@Override
+ public ModuleVisitor visitModule(String name, int flags,
+ String version) {
+ Printer p = this.p.visitModule(name, flags, version);
+ ModuleVisitor mv = super.visitModule(name, flags, version);
+ return new TraceModuleVisitor(mv, p);
+ }
+
+ @Override
public void visitOuterClass(final String owner, final String name,
final String desc) {
p.visitOuterClass(owner, name, desc);
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceFieldVisitor.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceFieldVisitor.java Wed Nov 08 16:03:35 2017 -0500
@@ -79,7 +79,7 @@
}
public TraceFieldVisitor(final FieldVisitor fv, final Printer p) {
- super(Opcodes.ASM5, fv);
+ super(Opcodes.ASM6, fv);
this.p = p;
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java Wed Nov 08 16:03:35 2017 -0500
@@ -81,7 +81,7 @@
}
public TraceMethodVisitor(final MethodVisitor mv, final Printer p) {
- super(Opcodes.ASM5, mv);
+ super(Opcodes.ASM6, mv);
this.p = p;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceModuleVisitor.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,130 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.util;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+/**
+ * A {@link ModuleVisitor} that prints the fields it visits with a
+ * {@link Printer}.
+ *
+ * @author Remi Forax
+ */
+public final class TraceModuleVisitor extends ModuleVisitor {
+
+ public final Printer p;
+
+ public TraceModuleVisitor(final Printer p) {
+ this(null, p);
+ }
+
+ public TraceModuleVisitor(final ModuleVisitor mv, final Printer p) {
+ super(Opcodes.ASM6, mv);
+ this.p = p;
+ }
+
+ @Override
+ public void visitMainClass(String mainClass) {
+ p.visitMainClass(mainClass);
+ super.visitMainClass(mainClass);
+ }
+
+ @Override
+ public void visitPackage(String packaze) {
+ p.visitPackage(packaze);
+ super.visitPackage(packaze);
+ }
+
+ @Override
+ public void visitRequire(String module, int access, String version) {
+ p.visitRequire(module, access, version);
+ super.visitRequire(module, access, version);
+ }
+
+ @Override
+ public void visitExport(String packaze, int access, String... modules) {
+ p.visitExport(packaze, access, modules);
+ super.visitExport(packaze, access, modules);
+ }
+
+ @Override
+ public void visitOpen(String packaze, int access, String... modules) {
+ p.visitOpen(packaze, access, modules);
+ super.visitOpen(packaze, access, modules);
+ }
+
+ @Override
+ public void visitUse(String use) {
+ p.visitUse(use);
+ super.visitUse(use);
+ }
+
+ @Override
+ public void visitProvide(String service, String... providers) {
+ p.visitProvide(service, providers);
+ super.visitProvide(service, providers);
+ }
+
+ @Override
+ public void visitEnd() {
+ p.visitModuleEnd();
+ super.visitEnd();
+ }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceSignatureVisitor.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceSignatureVisitor.java Wed Nov 08 16:03:35 2017 -0500
@@ -104,13 +104,13 @@
private String separator = "";
public TraceSignatureVisitor(final int access) {
- super(Opcodes.ASM5);
+ super(Opcodes.ASM6);
isInterface = (access & Opcodes.ACC_INTERFACE) != 0;
this.declaration = new StringBuilder();
}
private TraceSignatureVisitor(final StringBuilder buf) {
- super(Opcodes.ASM5);
+ super(Opcodes.ASM6);
this.declaration = buf;
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/version.txt Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/version.txt Wed Nov 08 16:03:35 2017 -0500
@@ -1,12 +1,4 @@
-Path: .
-Working Copy Root Path: /hudson/jobs/objectweb-init/workspace/asm-svn-2016-01-25
-URL: file:///svnroot/asm/trunk/asm
-Repository Root: file:///svnroot/asm
-Repository UUID: 271bd773-ee82-43a6-9b2b-1890ed8ce7f9
-Revision: 1795
-Node Kind: directory
-Schedule: normal
-Last Changed Author: ebruneton
-Last Changed Rev: 1795
-Last Changed Date: 2016-01-24 14:17:10 +0100 (Sun, 24 Jan 2016)
+ASM_6_0-11-gac81f5f
+origin https://gitlab.ow2.org/asm/asm.git (fetch)
+ac81f5f Merge branch 'add-class-dump-tool-for-unit-tests' into 'master'
--- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Wed Nov 08 16:03:35 2017 -0500
@@ -2888,7 +2888,7 @@
/*
* If we have an input stream this means we received a response
* from the server. That stream may have been read to EOF and
- * dependening on the stream type may already be closed or the
+ * depending on the stream type may already be closed or
* the http client may be returned to the keep-alive cache.
* If the http client has been returned to the keep-alive cache
* it may be closed (idle timeout) or may be allocated to
--- a/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java Wed Nov 08 16:03:35 2017 -0500
@@ -66,7 +66,7 @@
/**
* Static factory. Given a (generic) class, actual type arguments
* and an owner type, creates a parameterized type.
- * This class can be instantiated with a a raw type that does not
+ * This class can be instantiated with a raw type that does not
* represent a generic type, provided the list of actual type
* arguments is empty.
* If the ownerType argument is null, the declaring class of the
--- a/src/java.base/share/classes/sun/security/provider/AuthPolicyFile.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/sun/security/provider/AuthPolicyFile.java Wed Nov 08 16:03:35 2017 -0500
@@ -411,7 +411,7 @@
certs = null;
}
- // only add if we had no signer or we had a
+ // only add if we had no signer or we had
// a signer and found the keys for it.
if (certs != null || pe.signedBy == null) {
Permission perm = new UnresolvedPermission(
--- a/src/java.base/share/classes/sun/security/provider/PolicyFile.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/sun/security/provider/PolicyFile.java Wed Nov 08 16:03:35 2017 -0500
@@ -789,7 +789,7 @@
certs = null;
}
- // only add if we had no signer or we had a
+ // only add if we had no signer or we had
// a signer and found the keys for it.
if (certs != null || pe.signedBy == null) {
Permission perm = new UnresolvedPermission(
--- a/src/java.base/share/classes/sun/security/provider/SubjectCodeSource.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/sun/security/provider/SubjectCodeSource.java Wed Nov 08 16:03:35 2017 -0500
@@ -154,7 +154,7 @@
*
* @param codesource the <code>CodeSource</code> to compare against.
*
- * @return true if this <code>SubjectCodeSource</code> implies the
+ * @return true if this <code>SubjectCodeSource</code> implies
* the specified <code>CodeSource</code>.
*/
public boolean implies(CodeSource codesource) {
--- a/src/java.base/share/classes/sun/security/ssl/DTLSInputRecord.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/sun/security/ssl/DTLSInputRecord.java Wed Nov 08 16:03:35 2017 -0500
@@ -539,7 +539,7 @@
// Should be repacked for suitable fragment length.
//
- // Note that the acquiring processes will reassemble the
+ // Note that the acquiring processes will reassemble
// the fragments later.
return compareToSequence(o.recordEpoch, o.recordSeq);
}
--- a/src/java.base/share/classes/sun/security/x509/X509CertImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/sun/security/x509/X509CertImpl.java Wed Nov 08 16:03:35 2017 -0500
@@ -1485,7 +1485,7 @@
}
/**
- * Get the certificate constraints path length from the
+ * Get the certificate constraints path length from
* the critical BasicConstraints extension, (oid = 2.5.29.19).
* @return the length of the constraint.
*/
--- a/src/java.base/share/classes/sun/util/logging/PlatformLogger.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/sun/util/logging/PlatformLogger.java Wed Nov 08 16:03:35 2017 -0500
@@ -45,7 +45,7 @@
*
* If the logging facility is not enabled, the platform loggers
* will output log messages per the default logging configuration
- * (see below). In this implementation, it does not log the
+ * (see below). In this implementation, it does not log
* the stack frame information issuing the log message.
*
* When the logging facility is enabled (at startup or runtime),
--- a/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java Wed Nov 08 16:03:35 2017 -0500
@@ -183,7 +183,6 @@
case "10":
return RELEASE_10;
case "9":
- case "1.9":
return RELEASE_9;
case "1.8":
return RELEASE_8;
--- a/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenUtilities.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenUtilities.java Wed Nov 08 16:03:35 2017 -0500
@@ -25,19 +25,19 @@
package com.apple.eawt;
-import java.awt.*;
+import java.awt.Component;
+import java.awt.Window;
import javax.swing.RootPaneContainer;
-import sun.lwawt.macosx.*;
-
import com.apple.eawt.event.GestureUtilities;
+import sun.lwawt.macosx.CPlatformWindow;
/**
* Utility class perform animated full screen actions to top-level {@link Window}s.
*
* This class manages the relationship between {@link Window}s and the {@link FullScreenListener}s
- * attached to them. It's design is similar to the Java SE 6u10 {@link com.sun.awt.AWTUtilities}
+ * attached to them. It's design is similar to the Java SE 6u10 {@code com.sun.awt.AWTUtilities}
* class which adds additional functionality to AWT Windows, without adding new API to the
* {@link java.awt.Window} class.
*
@@ -45,7 +45,6 @@
*
* @see FullScreenAdapter
* @see GestureUtilities
- * @see com.sun.awt.AWTUtilities
*
* @since Java for Mac OS X 10.7 Update 1
*/
--- a/src/java.desktop/macosx/classes/com/apple/eawt/event/GestureUtilities.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/macosx/classes/com/apple/eawt/event/GestureUtilities.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -25,13 +25,15 @@
package com.apple.eawt.event;
-import javax.swing.*;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JRootPane;
/**
* Registration utility class to add {@link GestureListener}s to Swing components.
*
* This class manages the relationship between {@link JComponent}s and the {@link GestureListener}s
- * attached to them. It's design is similar to the Java SE 6u10 {@link com.sun.awt.AWTUtilities}
+ * attached to them. It's design is similar to the Java SE 6u10 {@code com.sun.awt.AWTUtilities}
* class which adds additional functionality to AWT Windows, without adding new API to the
* {@link java.awt.Window} class.
*
@@ -40,7 +42,6 @@
*
* @see GestureAdapter
* @see JFrame#getRootPane()
- * @see com.sun.awt.AWTUtilities
*
* @since Java for Mac OS X 10.5 Update 7, Java for Mac OS X 10.6 Update 2
*/
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Wed Nov 08 16:03:35 2017 -0500
@@ -25,35 +25,50 @@
package sun.lwawt.macosx;
-import com.apple.eawt.FullScreenAdapter;
-import com.apple.eawt.FullScreenUtilities;
-import com.apple.eawt.event.FullScreenEvent;
-import java.awt.*;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.DefaultKeyboardFocusManager;
+import java.awt.Dialog;
import java.awt.Dialog.ModalityType;
-import java.awt.event.*;
-import java.beans.*;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Frame;
+import java.awt.GraphicsDevice;
+import java.awt.Insets;
+import java.awt.MenuBar;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.Window;
+import java.awt.event.FocusEvent;
+import java.awt.event.WindowEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Comparator;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
-import javax.swing.*;
+import javax.swing.JRootPane;
+import javax.swing.RootPaneContainer;
+import javax.swing.SwingUtilities;
-import sun.awt.*;
+import com.apple.laf.ClientPropertyApplicator;
+import com.apple.laf.ClientPropertyApplicator.Property;
+import sun.awt.AWTAccessor;
import sun.awt.AWTAccessor.ComponentAccessor;
import sun.awt.AWTAccessor.WindowAccessor;
import sun.java2d.SurfaceData;
import sun.java2d.opengl.CGLSurfaceData;
-import sun.lwawt.*;
+import sun.lwawt.LWToolkit;
+import sun.lwawt.LWWindowPeer;
+import sun.lwawt.LWWindowPeer.PeerType;
+import sun.lwawt.PlatformWindow;
import sun.util.logging.PlatformLogger;
-import com.apple.laf.*;
-import com.apple.laf.ClientPropertyApplicator.Property;
-import com.sun.awt.AWTUtilities;
-import sun.lwawt.LWWindowPeer.PeerType;
-
public class CPlatformWindow extends CFRetainedResource implements PlatformWindow {
private native long nativeCreateNSWindow(long nsViewPtr,long ownerPtr, long styleBits, double x, double y, double w, double h);
private static native void nativeSetNSWindowStyleBits(long nsWindowPtr, int mask, int data);
@@ -172,7 +187,7 @@
c.setStyleBits(TEXTURED, Boolean.parseBoolean(value.toString()));
}},
new Property<CPlatformWindow>(WINDOW_ALPHA) { public void applyProperty(final CPlatformWindow c, final Object value) {
- AWTUtilities.setWindowOpacity(c.target, value == null ? 1.0f : Float.parseFloat(value.toString()));
+ c.target.setOpacity(value == null ? 1.0f : Float.parseFloat(value.toString()));
}},
new Property<CPlatformWindow>(WINDOW_SHADOW) { public void applyProperty(final CPlatformWindow c, final Object value) {
c.setStyleBits(HAS_SHADOW, value == null ? true : Boolean.parseBoolean(value.toString()));
@@ -224,6 +239,20 @@
return (CPlatformWindow)((LWWindowPeer)acc.getPeer(root)).getPlatformWindow();
}
};
+ private final Comparator<Window> siblingsComparator = (w1, w2) -> {
+ if (w1 == w2) {
+ return 0;
+ }
+ ComponentAccessor componentAccessor = AWTAccessor.getComponentAccessor();
+ Object p1 = componentAccessor.getPeer(w1);
+ Object p2 = componentAccessor.getPeer(w2);
+ if (p1 instanceof LWWindowPeer && p2 instanceof LWWindowPeer) {
+ return Long.compare(
+ ((CPlatformWindow) (((LWWindowPeer) p1).getPlatformWindow())).lastBecomeMainTime,
+ ((CPlatformWindow) (((LWWindowPeer) p2).getPlatformWindow())).lastBecomeMainTime);
+ }
+ return 0;
+ };
// Bounds of the native widget but in the Java coordinate system.
// In order to keep it up-to-date we will update them on
@@ -245,6 +274,7 @@
private boolean undecorated; // initialized in getInitialStyleBits()
private Rectangle normalBounds = null; // not-null only for undecorated maximized windows
private CPlatformResponder responder;
+ private long lastBecomeMainTime; // this is necessary to preserve right siblings order
public CPlatformWindow() {
super(0, true);
@@ -1172,8 +1202,9 @@
final ComponentAccessor componentAccessor = AWTAccessor.getComponentAccessor();
final WindowAccessor windowAccessor = AWTAccessor.getWindowAccessor();
-
+ Arrays.sort(windows, siblingsComparator);
// Go through the list of windows and perform ordering.
+ CPlatformWindow pwUnder = null;
for (Window w : windows) {
boolean iconified = false;
final Object p = componentAccessor.getPeer(w);
@@ -1187,11 +1218,15 @@
if (pw.isOneOfOwnersOrSelf(this)) {
pw.execute(CWrapper.NSWindow::orderFront);
} else {
- pw.owner.execute(ownerPtr -> {
+ if (pwUnder == null) {
+ pwUnder = pw.owner;
+ }
+ pwUnder.execute(underPtr -> {
pw.execute(ptr -> {
- CWrapper.NSWindow.orderWindow(ptr, CWrapper.NSWindow.NSWindowAbove, ownerPtr);
+ CWrapper.NSWindow.orderWindow(ptr, CWrapper.NSWindow.NSWindowAbove, underPtr);
});
});
+ pwUnder = pw;
}
pw.applyWindowLevel(w);
}
@@ -1228,6 +1263,7 @@
}
private void windowDidBecomeMain() {
+ lastBecomeMainTime = System.currentTimeMillis();
if (checkBlockingAndOrder()) return;
// If it's not blocked, make sure it's above its siblings
orderAboveSiblings();
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -25,26 +25,37 @@
package sun.lwawt.macosx;
-import sun.awt.AWTAccessor;
-import sun.awt.SunToolkit;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.*;
+import java.awt.AWTEvent;
+import java.awt.Button;
+import java.awt.Frame;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.MediaTracker;
+import java.awt.PopupMenu;
+import java.awt.RenderingHints;
+import java.awt.Toolkit;
+import java.awt.Transparency;
+import java.awt.TrayIcon;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.awt.peer.TrayIconPeer;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.concurrent.atomic.AtomicReference;
+
+import javax.swing.Icon;
+import javax.swing.UIManager;
-import static sun.awt.AWTAccessor.*;
+import sun.awt.SunToolkit;
+
+import static sun.awt.AWTAccessor.MenuComponentAccessor;
+import static sun.awt.AWTAccessor.getMenuComponentAccessor;
public class CTrayIcon extends CFRetainedResource implements TrayIconPeer {
private TrayIcon target;
private PopupMenu popup;
- private JDialog messageDialog;
- private DialogEventHandler handler;
// In order to construct MouseEvent object, we need to specify a
// Component target. Because TrayIcon isn't Component's subclass,
@@ -59,8 +70,6 @@
CTrayIcon(TrayIcon target) {
super(0, true);
- this.messageDialog = null;
- this.handler = null;
this.target = target;
this.popup = target.getPopupMenu();
this.dummyFrame = new Frame();
@@ -129,28 +138,25 @@
*/
public void displayMessage(final String caption, final String text,
final String messageType) {
-
- if (SwingUtilities.isEventDispatchThread()) {
- displayMessageOnEDT(caption, text, messageType);
+ // obtain icon to show along the message
+ Icon icon = getIconForMessageType(messageType);
+ CImage cimage = null;
+ if (icon != null) {
+ BufferedImage image = scaleIcon(icon, 0.75);
+ cimage = CImage.getCreator().createFromImage(image);
+ }
+ if (cimage != null) {
+ cimage.execute(imagePtr -> {
+ execute(ptr -> nativeShowNotification(ptr, caption, text,
+ imagePtr));
+ });
} else {
- try {
- SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- displayMessageOnEDT(caption, text, messageType);
- }
- });
- } catch (Exception e) {
- throw new AssertionError(e);
- }
+ execute(ptr -> nativeShowNotification(ptr, caption, text, 0));
}
}
@Override
public void dispose() {
- if (messageDialog != null) {
- disposeMessageDialog();
- }
-
dummyFrame.dispose();
if (popup != null) {
@@ -276,154 +282,14 @@
}
}
- private native Point2D nativeGetIconLocation(long trayIconModel);
-
- public void displayMessageOnEDT(String caption, String text,
- String messageType) {
- if (messageDialog != null) {
- disposeMessageDialog();
- }
-
- // obtain icon to show along the message
- Icon icon = getIconForMessageType(messageType);
- if (icon != null) {
- icon = new ImageIcon(scaleIcon(icon, 0.75));
- }
-
- // We want the message dialog text area to be about 1/8 of the screen
- // size. There is nothing special about this value, it's just makes the
- // message dialog to look nice
- Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
- int textWidth = screenSize.width / 8;
-
- // create dialog to show
- messageDialog = createMessageDialog(caption, text, textWidth, icon);
-
- // finally, show the dialog to user
- showMessageDialog();
- }
+ private native void nativeShowNotification(long trayIconModel,
+ String caption, String text,
+ long nsimage);
/**
- * Creates dialog window used to display the message
+ * Used by the automated tests.
*/
- private JDialog createMessageDialog(String caption, String text,
- int textWidth, Icon icon) {
- JDialog dialog;
- handler = new DialogEventHandler();
-
- JTextArea captionArea = null;
- if (caption != null) {
- captionArea = createTextArea(caption, textWidth, false, true);
- }
-
- JTextArea textArea = null;
- if (text != null){
- textArea = createTextArea(text, textWidth, true, false);
- }
-
- Object[] panels = null;
- if (captionArea != null) {
- if (textArea != null) {
- panels = new Object[] {captionArea, new JLabel(), textArea};
- } else {
- panels = new Object[] {captionArea};
- }
- } else {
- if (textArea != null) {
- panels = new Object[] {textArea};
- }
- }
-
- // We want message dialog with small title bar. There is a client
- // property property that does it, however, it must be set before
- // dialog's native window is created. This is why we create option
- // pane and dialog separately
- final JOptionPane op = new JOptionPane(panels);
- op.setIcon(icon);
- op.addPropertyChangeListener(handler);
-
- // Make Ok button small. Most likely won't work for L&F other then Aqua
- try {
- JPanel buttonPanel = (JPanel)op.getComponent(1);
- JButton ok = (JButton)buttonPanel.getComponent(0);
- ok.putClientProperty("JComponent.sizeVariant", "small");
- } catch (Throwable t) {
- // do nothing, we tried and failed, no big deal
- }
-
- dialog = new JDialog((Dialog) null);
- JRootPane rp = dialog.getRootPane();
-
- // gives us dialog window with small title bar and not zoomable
- rp.putClientProperty(CPlatformWindow.WINDOW_STYLE, "small");
- rp.putClientProperty(CPlatformWindow.WINDOW_ZOOMABLE, "false");
-
- dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
- dialog.setModal(false);
- dialog.setModalExclusionType(Dialog.ModalExclusionType.TOOLKIT_EXCLUDE);
- dialog.setAlwaysOnTop(true);
- dialog.setAutoRequestFocus(false);
- dialog.setResizable(false);
- dialog.setContentPane(op);
-
- dialog.addWindowListener(handler);
-
- // suppress security warning for untrusted windows
- AWTAccessor.getWindowAccessor().setTrayIconWindow(dialog, true);
-
- dialog.pack();
-
- return dialog;
- }
-
- private void showMessageDialog() {
-
- Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
- AtomicReference<Point2D> ref = new AtomicReference<>();
- execute(ptr -> {
- ref.set(nativeGetIconLocation(ptr));
- });
- Point2D iconLoc = ref.get();
- if (iconLoc == null) {
- return;
- }
-
- int dialogY = (int)iconLoc.getY();
- int dialogX = (int)iconLoc.getX();
- if (dialogX + messageDialog.getWidth() > screenSize.width) {
- dialogX = screenSize.width - messageDialog.getWidth();
- }
-
- messageDialog.setLocation(dialogX, dialogY);
- messageDialog.setVisible(true);
- }
-
- private void disposeMessageDialog() {
- if (SwingUtilities.isEventDispatchThread()) {
- disposeMessageDialogOnEDT();
- } else {
- try {
- SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- disposeMessageDialogOnEDT();
- }
- });
- } catch (Exception e) {
- throw new AssertionError(e);
- }
- }
- }
-
- private void disposeMessageDialogOnEDT() {
- if (messageDialog != null) {
- messageDialog.removeWindowListener(handler);
- messageDialog.removePropertyChangeListener(handler);
- messageDialog.dispose();
-
- messageDialog = null;
- handler = null;
- }
- }
+ private native Point2D nativeGetIconLocation(long trayIconModel);
/**
* Scales an icon using specified scale factor
@@ -480,56 +346,5 @@
return UIManager.getIcon("OptionPane.informationIcon");
}
}
-
- private static JTextArea createTextArea(String text, int width,
- boolean isSmall, boolean isBold) {
- JTextArea textArea = new JTextArea(text);
-
- textArea.setLineWrap(true);
- textArea.setWrapStyleWord(true);
- textArea.setEditable(false);
- textArea.setFocusable(false);
- textArea.setBorder(null);
- textArea.setBackground(new JLabel().getBackground());
-
- if (isSmall) {
- textArea.putClientProperty("JComponent.sizeVariant", "small");
- }
-
- if (isBold) {
- Font font = textArea.getFont();
- Font boldFont = new Font(font.getName(), Font.BOLD, font.getSize());
- textArea.setFont(boldFont);
- }
-
- textArea.setSize(width, 1);
-
- return textArea;
- }
-
- /**
- * Implements all the Listeners needed by message dialog
- */
- private final class DialogEventHandler extends WindowAdapter
- implements PropertyChangeListener {
-
- public void windowClosing(WindowEvent we) {
- disposeMessageDialog();
- }
-
- public void propertyChange(PropertyChangeEvent e) {
- if (messageDialog == null) {
- return;
- }
-
- String prop = e.getPropertyName();
- Container cp = messageDialog.getContentPane();
-
- if (messageDialog.isVisible() && e.getSource() == cp &&
- (prop.equals(JOptionPane.VALUE_PROPERTY))) {
- disposeMessageDialog();
- }
- }
- }
}
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m Wed Nov 08 16:03:35 2017 -0500
@@ -74,20 +74,20 @@
// Initialize ourselves
self = [super initWithFrame: rect];
if (self == nil) return self;
-
+
m_cPlatformView = cPlatformView;
fInputMethodLOCKABLE = NULL;
fKeyEventsNeeded = NO;
fProcessingKeystroke = NO;
-
+
fEnablePressAndHold = shouldUsePressAndHold();
fInPressAndHold = NO;
fPAHNeedsToSelect = NO;
-
+
mouseIsOver = NO;
[self resetTrackingArea];
[self setAutoresizesSubviews:NO];
-
+
if (windowLayer != nil) {
self.cglLayer = windowLayer;
//Layer hosting view
@@ -98,7 +98,7 @@
//[self setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawDuringViewResize];
//[self setLayerContentsPlacement: NSViewLayerContentsPlacementTopLeft];
//[self setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
-
+
#ifdef REMOTELAYER
CGLLayer *parentLayer = (CGLLayer*)self.cglLayer;
parentLayer.parentLayer = NULL;
@@ -120,36 +120,36 @@
}
#endif /* REMOTELAYER */
}
-
+
return self;
}
- (void) dealloc {
AWT_ASSERT_APPKIT_THREAD;
-
+
self.cglLayer = nil;
-
+
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
(*env)->DeleteWeakGlobalRef(env, m_cPlatformView);
m_cPlatformView = NULL;
-
+
if (fInputMethodLOCKABLE != NULL)
{
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
-
+
JNFDeleteGlobalRef(env, fInputMethodLOCKABLE);
fInputMethodLOCKABLE = NULL;
}
-
-
+
+
[super dealloc];
}
- (void) viewDidMoveToWindow {
AWT_ASSERT_APPKIT_THREAD;
-
+
[AWTToolkit eventCountPlusPlus];
-
+
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^() {
[[self window] makeFirstResponder: self];
}];
@@ -230,10 +230,10 @@
- (void) mouseMoved: (NSEvent *)event {
// TODO: better way to redirect move events to the "under" view
-
+
NSPoint eventLocation = [event locationInWindow];
NSPoint localPoint = [self convertPoint: eventLocation fromView: nil];
-
+
if ([self mouse: localPoint inRect: [self bounds]]) {
[self deliverJavaMouseEvent: event];
} else {
@@ -277,10 +277,10 @@
- (void) keyDown: (NSEvent *)event {
fProcessingKeystroke = YES;
fKeyEventsNeeded = YES;
-
+
// Allow TSM to look at the event and potentially send back NSTextInputClient messages.
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
-
+
if (fEnablePressAndHold && [event willBeHandledByComplexInputMethod] && fInputMethodLOCKABLE) {
fProcessingKeystroke = NO;
if (!fInPressAndHold) {
@@ -289,14 +289,14 @@
}
return;
}
-
+
NSString *eventCharacters = [event characters];
BOOL isDeadKey = (eventCharacters != nil && [eventCharacters length] == 0);
-
+
if ((![self hasMarkedText] && fKeyEventsNeeded) || isDeadKey) {
[self deliverJavaKeyEventHelper: event];
}
-
+
fProcessingKeystroke = NO;
}
@@ -313,7 +313,7 @@
if (![self hasMarkedText] && !fInPressAndHold) {
[self deliverJavaKeyEventHelper: event];
}
-
+
// Workaround for 8020209: special case for "Cmd =" and "Cmd ."
// because Cocoa calls performKeyEquivalent twice for these keystrokes
NSUInteger modFlags = [event modifierFlags] &
@@ -327,9 +327,9 @@
return YES;
}
}
-
+
}
-
+
return NO;
}
@@ -343,36 +343,36 @@
if ([window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]]) {
isEnabled = [(AWTWindow*)[window delegate] isEnabled];
}
-
+
if (!isEnabled) {
return;
}
-
+
NSEventType type = [event type];
-
+
// check synthesized mouse entered/exited events
if ((type == NSMouseEntered && mouseIsOver) || (type == NSMouseExited && !mouseIsOver)) {
return;
}else if ((type == NSMouseEntered && !mouseIsOver) || (type == NSMouseExited && mouseIsOver)) {
mouseIsOver = !mouseIsOver;
}
-
+
[AWTToolkit eventCountPlusPlus];
-
+
JNIEnv *env = [ThreadUtilities getJNIEnv];
-
+
NSPoint eventLocation = [event locationInWindow];
NSPoint localPoint = [self convertPoint: eventLocation fromView: nil];
NSPoint absP = [NSEvent mouseLocation];
-
+
// Convert global numbers between Cocoa's coordinate system and Java.
// TODO: need consitent way for doing that both with global as well as with local coordinates.
// The reason to do it here is one more native method for getting screen dimension otherwise.
-
+
NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame];
absP.y = screenRect.size.height - absP.y;
jint clickCount;
-
+
if (type == NSMouseEntered ||
type == NSMouseExited ||
type == NSScrollWheel ||
@@ -388,7 +388,7 @@
deltaX = [event scrollingDeltaX] * 0.1;
deltaY = [event scrollingDeltaY] * 0.1;
}
-
+
static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/NSEvent");
static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDDI)V");
jobject jEvent = JNFNewObject(env, jctor_NSEvent,
@@ -402,7 +402,7 @@
deltaX,
[AWTToolkit scrollStateWithEvent: event]);
CHECK_NULL(jEvent);
-
+
static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
static JNF_MEMBER_CACHE(jm_deliverMouseEvent, jc_PlatformView, "deliverMouseEvent", "(Lsun/lwawt/macosx/NSEvent;)V");
jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView);
@@ -418,10 +418,10 @@
[self removeTrackingArea:rolloverTrackingArea];
[rolloverTrackingArea release];
}
-
+
int options = (NSTrackingActiveAlways | NSTrackingMouseEnteredAndExited |
NSTrackingMouseMoved | NSTrackingEnabledDuringMouseDrag);
-
+
rolloverTrackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect]
options: options
owner:self
@@ -448,17 +448,17 @@
}
[sLastKeyEvent release];
sLastKeyEvent = [event retain];
-
+
[AWTToolkit eventCountPlusPlus];
JNIEnv *env = [ThreadUtilities getJNIEnv];
-
+
jstring characters = NULL;
jstring charactersIgnoringModifiers = NULL;
if ([event type] != NSFlagsChanged) {
characters = JNFNSToJavaString(env, [event characters]);
charactersIgnoringModifiers = JNFNSToJavaString(env, [event charactersIgnoringModifiers]);
}
-
+
static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/NSEvent");
static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IISLjava/lang/String;Ljava/lang/String;)V");
jobject jEvent = JNFNewObject(env, jctor_NSEvent,
@@ -468,7 +468,7 @@
characters,
charactersIgnoringModifiers);
CHECK_NULL(jEvent);
-
+
static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
static JNF_MEMBER_CACHE(jm_deliverKeyEvent, jc_PlatformView,
"deliverKeyEvent", "(Lsun/lwawt/macosx/NSEvent;)V");
@@ -502,7 +502,7 @@
- (void) drawRect:(NSRect)dirtyRect {
AWT_ASSERT_APPKIT_THREAD;
-
+
[super drawRect:dirtyRect];
JNIEnv *env = [ThreadUtilities getJNIEnv];
if (env != NULL) {
@@ -615,17 +615,17 @@
- (id)accessibilityAttributeValue:(NSString *)attribute
{
AWT_ASSERT_APPKIT_THREAD;
-
+
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
-
+
(*env)->PushLocalFrame(env, 4);
-
+
id result = NSAccessibilityUnignoredChildrenForOnlyChild([self getAxData:env]);
-
+
(*env)->PopLocalFrame(env, NULL);
-
+
return result;
}
else
@@ -642,28 +642,28 @@
{
AWT_ASSERT_APPKIT_THREAD;
JNIEnv *env = [ThreadUtilities getJNIEnv];
-
+
(*env)->PushLocalFrame(env, 4);
-
+
id result = [[self getAxData:env] accessibilityHitTest:point withEnv:env];
-
+
(*env)->PopLocalFrame(env, NULL);
-
+
return result;
}
- (id)accessibilityFocusedUIElement
{
AWT_ASSERT_APPKIT_THREAD;
-
+
JNIEnv *env = [ThreadUtilities getJNIEnv];
-
+
(*env)->PushLocalFrame(env, 4);
-
+
id result = [[self getAxData:env] accessibilityFocusedUIElement];
-
+
(*env)->PopLocalFrame(env, NULL);
-
+
return result;
}
@@ -702,12 +702,12 @@
- (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType
{
if ([[self window] firstResponder] != self) return nil; // let AWT components handle themselves
-
+
if ([sendType isEqual:NSStringPboardType] || [returnType isEqual:NSStringPboardType]) {
NSString *selectedText = [self accessibleSelectedText];
if (selectedText) return self;
}
-
+
return nil;
}
@@ -719,13 +719,13 @@
[pboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
return [pboard setString:[self accessibleSelectedText] forType:NSStringPboardType];
}
-
+
if ([types containsObject:NSRTFDPboardType])
{
[pboard declareTypes:[NSArray arrayWithObject:NSRTFDPboardType] owner:nil];
return [pboard setData:[self accessibleSelectedTextAsRTFD] forType:NSRTFDPboardType];
}
-
+
return NO;
}
@@ -737,17 +737,17 @@
NSString *text = [pboard stringForType:NSStringPboardType];
return [self replaceAccessibleTextSelection:text];
}
-
+
if ([[pboard types] containsObject:NSRTFDPboardType])
{
NSData *rtfdData = [pboard dataForType:NSRTFDPboardType];
NSAttributedString *styledText = [[NSAttributedString alloc] initWithRTFD:rtfdData documentAttributes:NULL];
NSString *text = [styledText string];
[styledText release];
-
+
return [self replaceAccessibleTextSelection:text];
}
-
+
return NO;
}
@@ -769,7 +769,7 @@
// If draggingSource is nil route the message to the superclass (if responding to the selector):
CDragSource *dragSource = self._dragSource;
NSDragOperation dragOp = NSDragOperationNone;
-
+
if (dragSource != nil) {
dragOp = [dragSource draggingSourceOperationMaskForLocal:flag];
}
@@ -781,7 +781,7 @@
// If draggingSource is nil route the message to the superclass (if responding to the selector):
CDragSource *dragSource = self._dragSource;
NSArray* array = nil;
-
+
if (dragSource != nil) {
array = [dragSource namesOfPromisedFilesDroppedAtDestination:dropDestination];
}
@@ -792,7 +792,7 @@
{
// If draggingSource is nil route the message to the superclass (if responding to the selector):
CDragSource *dragSource = self._dragSource;
-
+
if (dragSource != nil) {
[dragSource draggedImage:image beganAt:screenPoint];
}
@@ -802,7 +802,7 @@
{
// If draggingSource is nil route the message to the superclass (if responding to the selector):
CDragSource *dragSource = self._dragSource;
-
+
if (dragSource != nil) {
[dragSource draggedImage:image endedAt:screenPoint operation:operation];
}
@@ -812,7 +812,7 @@
{
// If draggingSource is nil route the message to the superclass (if responding to the selector):
CDragSource *dragSource = self._dragSource;
-
+
if (dragSource != nil) {
[dragSource draggedImage:image movedTo:screenPoint];
}
@@ -823,7 +823,7 @@
// If draggingSource is nil route the message to the superclass (if responding to the selector):
CDragSource *dragSource = self._dragSource;
BOOL result = FALSE;
-
+
if (dragSource != nil) {
result = [dragSource ignoreModifierKeysWhileDragging];
}
@@ -839,7 +839,7 @@
// If draggingDestination is nil route the message to the superclass:
CDropTarget *dropTarget = self._dropTarget;
NSDragOperation dragOp = NSDragOperationNone;
-
+
if (dropTarget != nil) {
dragOp = [dropTarget draggingEntered:sender];
}
@@ -851,7 +851,7 @@
// If draggingDestination is nil route the message to the superclass:
CDropTarget *dropTarget = self._dropTarget;
NSDragOperation dragOp = NSDragOperationNone;
-
+
if (dropTarget != nil) {
dragOp = [dropTarget draggingUpdated:sender];
}
@@ -862,7 +862,7 @@
{
// If draggingDestination is nil route the message to the superclass:
CDropTarget *dropTarget = self._dropTarget;
-
+
if (dropTarget != nil) {
[dropTarget draggingExited:sender];
}
@@ -873,7 +873,7 @@
// If draggingDestination is nil route the message to the superclass:
CDropTarget *dropTarget = self._dropTarget;
BOOL result = FALSE;
-
+
if (dropTarget != nil) {
result = [dropTarget prepareForDragOperation:sender];
}
@@ -885,7 +885,7 @@
// If draggingDestination is nil route the message to the superclass:
CDropTarget *dropTarget = self._dropTarget;
BOOL result = FALSE;
-
+
if (dropTarget != nil) {
result = [dropTarget performDragOperation:sender];
}
@@ -896,7 +896,7 @@
{
// If draggingDestination is nil route the message to the superclass:
CDropTarget *dropTarget = self._dropTarget;
-
+
if (dropTarget != nil) {
[dropTarget concludeDragOperation:sender];
}
@@ -906,7 +906,7 @@
{
// If draggingDestination is nil route the message to the superclass:
CDropTarget *dropTarget = self._dropTarget;
-
+
if (dropTarget != nil) {
[dropTarget draggingEnded:sender];
}
@@ -924,20 +924,20 @@
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [insertText]: %s\n", [aString UTF8String]);
#endif // IM_DEBUG
-
+
if (fInputMethodLOCKABLE == NULL) {
return;
}
-
+
// Insert happens at the end of PAH
fInPressAndHold = NO;
-
+
// insertText gets called when the user commits text generated from an input method. It also gets
// called during ordinary input as well. We only need to send an input method event when we have marked
// text, or 'text in progress'. We also need to send the event if we get an insert text out of the blue!
// (i.e., when the user uses the Character palette or Inkwell), or when the string to insert is a complex
// Unicode value.
-
+
NSMutableString * useString = [self parseString:aString];
NSUInteger utf16Length = [useString lengthOfBytesUsingEncoding:NSUTF16StringEncoding];
NSUInteger utf8Length = [useString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
@@ -946,22 +946,22 @@
((utf8Length > 1) && [self isCodePointInUnicodeBlockNeedingIMEvent:[useString characterAtIndex:0]])) {
aStringIsComplex = YES;
}
-
+
if ([self hasMarkedText] || !fProcessingKeystroke || aStringIsComplex) {
JNIEnv *env = [ThreadUtilities getJNIEnv];
-
+
static JNF_MEMBER_CACHE(jm_selectPreviousGlyph, jc_CInputMethod, "selectPreviousGlyph", "()V");
// We need to select the previous glyph so that it is overwritten.
if (fPAHNeedsToSelect) {
JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_selectPreviousGlyph);
fPAHNeedsToSelect = NO;
}
-
+
static JNF_MEMBER_CACHE(jm_insertText, jc_CInputMethod, "insertText", "(Ljava/lang/String;)V");
jstring insertedText = JNFNSToJavaString(env, useString);
JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_insertText, insertedText); // AWT_THREADING Safe (AWTRunLoopMode)
(*env)->DeleteLocalRef(env, insertedText);
-
+
// The input method event will create psuedo-key events for each character in the committed string.
// We also don't want to send the character that triggered the insertText, usually a return. [3337563]
fKeyEventsNeeded = NO;
@@ -993,7 +993,7 @@
{
if (!fInputMethodLOCKABLE)
return;
-
+
BOOL isAttributedString = [aString isKindOfClass:[NSAttributedString class]];
NSAttributedString *attrString = (isAttributedString ? (NSAttributedString *)aString : nil);
NSString *incomingString = (isAttributedString ? [aString string] : aString);
@@ -1004,14 +1004,14 @@
static JNF_MEMBER_CACHE(jm_addAttribute, jc_CInputMethod, "addAttribute", "(ZZII)V");
static JNF_MEMBER_CACHE(jm_dispatchText, jc_CInputMethod, "dispatchText", "(IIZ)V");
JNIEnv *env = [ThreadUtilities getJNIEnv];
-
+
// NSInputContext already did the analysis of the TSM event and created attributes indicating
// the underlining and color that should be done to the string. We need to look at the underline
// style and color to determine what kind of Java hilighting needs to be done.
jstring inProcessText = JNFNSToJavaString(env, incomingString);
JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_startIMUpdate, inProcessText); // AWT_THREADING Safe (AWTRunLoopMode)
(*env)->DeleteLocalRef(env, inProcessText);
-
+
if (isAttributedString) {
NSUInteger length;
NSRange effectiveRange;
@@ -1027,25 +1027,25 @@
(NSNumber *)[attributes objectForKey:NSUnderlineStyleAttributeName];
NSInteger underlineSize = [underlineSizeObj integerValue];
isThickUnderline = (underlineSize > 1);
-
+
NSColor *underlineColorObj =
(NSColor *)[attributes objectForKey:NSUnderlineColorAttributeName];
isGray = !([underlineColorObj isEqual:[NSColor blackColor]]);
-
+
JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_addAttribute, isThickUnderline, isGray, effectiveRange.location, effectiveRange.length); // AWT_THREADING Safe (AWTRunLoopMode)
}
}
}
-
+
static JNF_MEMBER_CACHE(jm_selectPreviousGlyph, jc_CInputMethod, "selectPreviousGlyph", "()V");
// We need to select the previous glyph so that it is overwritten.
if (fPAHNeedsToSelect) {
JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_selectPreviousGlyph);
fPAHNeedsToSelect = NO;
}
-
+
JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_dispatchText, selectionRange.location, selectionRange.length, JNI_FALSE); // AWT_THREADING Safe (AWTRunLoopMode)
-
+
// If the marked text is being cleared (zero-length string) don't handle the key event.
if ([incomingString length] == 0) {
fKeyEventsNeeded = NO;
@@ -1057,16 +1057,16 @@
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [unmarkText]\n");
#endif // IM_DEBUG
-
+
if (!fInputMethodLOCKABLE) {
return;
}
-
+
// unmarkText cancels any input in progress and commits it to the text field.
static JNF_MEMBER_CACHE(jm_unmarkText, jc_CInputMethod, "unmarkText", "()V");
JNIEnv *env = [ThreadUtilities getJNIEnv];
JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_unmarkText); // AWT_THREADING Safe (AWTRunLoopMode)
-
+
}
- (BOOL) hasMarkedText
@@ -1074,24 +1074,24 @@
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [hasMarkedText]\n");
#endif // IM_DEBUG
-
+
if (!fInputMethodLOCKABLE) {
return NO;
}
-
+
static JNF_MEMBER_CACHE(jf_fCurrentText, jc_CInputMethod, "fCurrentText", "Ljava/text/AttributedString;");
static JNF_MEMBER_CACHE(jf_fCurrentTextLength, jc_CInputMethod, "fCurrentTextLength", "I");
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject currentText = JNFGetObjectField(env, fInputMethodLOCKABLE, jf_fCurrentText);
-
+
jint currentTextLength = JNFGetIntField(env, fInputMethodLOCKABLE, jf_fCurrentTextLength);
-
+
BOOL hasMarkedText = (currentText != NULL && currentTextLength > 0);
-
+
if (currentText != NULL) {
(*env)->DeleteLocalRef(env, currentText);
}
-
+
return hasMarkedText;
}
@@ -1100,7 +1100,7 @@
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [conversationIdentifier]\n");
#endif // IM_DEBUG
-
+
return (NSInteger) self;
}
@@ -1112,16 +1112,16 @@
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [attributedSubstringFromRange] location=%lu, length=%lu\n", (unsigned long)theRange.location, (unsigned long)theRange.length);
#endif // IM_DEBUG
-
+
static JNF_MEMBER_CACHE(jm_substringFromRange, jc_CInputMethod, "attributedSubstringFromRange", "(II)Ljava/lang/String;");
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject theString = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_substringFromRange, theRange.location, theRange.length); // AWT_THREADING Safe (AWTRunLoopMode)
-
+
id result = [[[NSAttributedString alloc] initWithString:JNFJavaToNSString(env, theString)] autorelease];
#ifdef IM_DEBUG
NSLog(@"attributedSubstringFromRange returning \"%@\"", result);
#endif // IM_DEBUG
-
+
(*env)->DeleteLocalRef(env, theString);
return result;
}
@@ -1131,24 +1131,24 @@
*/
- (NSRange) markedRange
{
-
+
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [markedRange]\n");
#endif // IM_DEBUG
-
+
if (!fInputMethodLOCKABLE) {
return NSMakeRange(NSNotFound, 0);
}
-
+
static JNF_MEMBER_CACHE(jm_markedRange, jc_CInputMethod, "markedRange", "()[I");
JNIEnv *env = [ThreadUtilities getJNIEnv];
jarray array;
jboolean isCopy;
jint *_array;
NSRange range = NSMakeRange(NSNotFound, 0);
-
+
array = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_markedRange); // AWT_THREADING Safe (AWTRunLoopMode)
-
+
if (array) {
_array = (*env)->GetIntArrayElements(env, array, &isCopy);
if (_array != NULL) {
@@ -1162,7 +1162,7 @@
}
(*env)->DeleteLocalRef(env, array);
}
-
+
return range;
}
@@ -1174,18 +1174,18 @@
if (!fInputMethodLOCKABLE) {
return NSMakeRange(NSNotFound, 0);
}
-
+
static JNF_MEMBER_CACHE(jm_selectedRange, jc_CInputMethod, "selectedRange", "()[I");
JNIEnv *env = [ThreadUtilities getJNIEnv];
jarray array;
jboolean isCopy;
jint *_array;
NSRange range = NSMakeRange(NSNotFound, 0);
-
+
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [selectedRange]\n");
#endif // IM_DEBUG
-
+
array = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_selectedRange); // AWT_THREADING Safe (AWTRunLoopMode)
if (array) {
_array = (*env)->GetIntArrayElements(env, array, &isCopy);
@@ -1196,7 +1196,7 @@
}
(*env)->DeleteLocalRef(env, array);
}
-
+
return range;
}
@@ -1207,7 +1207,7 @@
if (!fInputMethodLOCKABLE) {
return NSZeroRect;
}
-
+
static JNF_MEMBER_CACHE(jm_firstRectForCharacterRange, jc_CInputMethod,
"firstRectForCharacterRange", "(I)[I");
JNIEnv *env = [ThreadUtilities getJNIEnv];
@@ -1215,16 +1215,16 @@
jboolean isCopy;
jint *_array;
NSRect rect;
-
+
#ifdef IM_DEBUG
fprintf(stderr,
"AWTView InputMethod Selector Called : [firstRectForCharacterRange:] location=%lu, length=%lu\n",
(unsigned long)theRange.location, (unsigned long)theRange.length);
#endif // IM_DEBUG
-
+
array = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_firstRectForCharacterRange,
theRange.location); // AWT_THREADING Safe (AWTRunLoopMode)
-
+
_array = (*env)->GetIntArrayElements(env, array, &isCopy);
if (_array) {
rect = ConvertNSScreenRect(env, NSMakeRect(_array[0], _array[1], _array[2], _array[3]));
@@ -1233,7 +1233,7 @@
rect = NSZeroRect;
}
(*env)->DeleteLocalRef(env, array);
-
+
#ifdef IM_DEBUG
fprintf(stderr,
"firstRectForCharacterRange returning x=%f, y=%f, width=%f, height=%f\n",
@@ -1250,23 +1250,23 @@
if (!fInputMethodLOCKABLE) {
return NSNotFound;
}
-
+
static JNF_MEMBER_CACHE(jm_characterIndexForPoint, jc_CInputMethod,
"characterIndexForPoint", "(II)I");
JNIEnv *env = [ThreadUtilities getJNIEnv];
-
+
NSPoint flippedLocation = ConvertNSScreenPoint(env, thePoint);
-
+
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [characterIndexForPoint:(NSPoint)thePoint] x=%f, y=%f\n", flippedLocation.x, flippedLocation.y);
#endif // IM_DEBUG
-
+
jint index = JNFCallIntMethod(env, fInputMethodLOCKABLE, jm_characterIndexForPoint, (jint)flippedLocation.x, (jint)flippedLocation.y); // AWT_THREADING Safe (AWTRunLoopMode)
-
+
#ifdef IM_DEBUG
fprintf(stderr, "characterIndexForPoint returning %ld\n", index);
#endif // IM_DEBUG
-
+
if (index == -1) {
return NSNotFound;
} else {
@@ -1279,7 +1279,7 @@
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [validAttributesForMarkedText]\n");
#endif // IM_DEBUG
-
+
return [NSArray array];
}
@@ -1288,14 +1288,14 @@
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [setInputMethod]\n");
#endif // IM_DEBUG
-
+
JNIEnv *env = [ThreadUtilities getJNIEnv];
-
+
// Get rid of the old one
if (fInputMethodLOCKABLE) {
JNFDeleteGlobalRef(env, fInputMethodLOCKABLE);
}
-
+
// Save a global ref to the new input method.
if (inputMethod != NULL)
fInputMethodLOCKABLE = JNFNewGlobalRef(env, inputMethod);
@@ -1308,7 +1308,7 @@
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [abandonInput]\n");
#endif // IM_DEBUG
-
+
[ThreadUtilities performOnMainThread:@selector(markedTextAbandoned:) on:[NSInputManager currentInputManager] withObject:self waitUntilDone:YES];
[self unmarkText];
}
@@ -1330,22 +1330,22 @@
(JNIEnv *env, jobject obj, jint originX, jint originY, jint width, jint height, jlong windowLayerPtr)
{
__block AWTView *newView = nil;
-
+
JNF_COCOA_ENTER(env);
-
+
NSRect rect = NSMakeRect(originX, originY, width, height);
jobject cPlatformView = (*env)->NewWeakGlobalRef(env, obj);
-
+
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
-
+
CALayer *windowLayer = jlong_to_ptr(windowLayerPtr);
newView = [[AWTView alloc] initWithRect:rect
platformView:cPlatformView
windowLayer:windowLayer];
}];
-
+
JNF_COCOA_EXIT(env);
-
+
return ptr_to_jlong(newView);
}
@@ -1360,21 +1360,21 @@
(JNIEnv *env, jclass cls, jlong viewPtr, jboolean toResize)
{
JNF_COCOA_ENTER(env);
-
+
NSView *view = (NSView *)jlong_to_ptr(viewPtr);
-
+
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
-
+
if (toResize) {
[view setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
} else {
[view setAutoresizingMask: NSViewMinYMargin | NSViewMaxXMargin];
}
-
+
if ([view superview] != nil) {
[[view superview] setAutoresizesSubviews:(BOOL)toResize];
}
-
+
}];
JNF_COCOA_EXIT(env);
}
@@ -1390,19 +1390,19 @@
(JNIEnv *env, jclass cls, jlong viewPtr)
{
__block jint ret; //CGDirectDisplayID
-
+
JNF_COCOA_ENTER(env);
-
+
NSView *view = (NSView *)jlong_to_ptr(viewPtr);
NSWindow *window = [view window];
-
+
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
-
+
ret = (jint)[[AWTWindow getNSWindowDisplayID_AppKitThread: window] intValue];
}];
-
+
JNF_COCOA_EXIT(env);
-
+
return ret;
}
@@ -1417,25 +1417,25 @@
(JNIEnv *env, jclass cls, jlong viewPtr)
{
jobject jRect = NULL;
-
+
JNF_COCOA_ENTER(env);
-
+
__block NSRect rect = NSZeroRect;
-
+
NSView *view = (NSView *)jlong_to_ptr(viewPtr);
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
-
+
NSRect viewBounds = [view bounds];
NSRect frameInWindow = [view convertRect:viewBounds toView:nil];
rect = [[view window] convertRectToScreen:frameInWindow];
- NSRect screenRect = [[NSScreen mainScreen] frame];
//Convert coordinates to top-left corner origin
- rect.origin.y = screenRect.size.height - rect.origin.y - viewBounds.size.height;
+ rect = ConvertNSScreenRect(NULL, rect);
+
}];
jRect = NSToJavaRect(env, rect);
-
+
JNF_COCOA_EXIT(env);
-
+
return jRect;
}
@@ -1449,17 +1449,17 @@
(JNIEnv *env, jclass clazz, jlong viewPtr)
{
__block jboolean underMouse = JNI_FALSE;
-
+
JNF_COCOA_ENTER(env);
-
+
NSView *nsView = OBJC(viewPtr);
- [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
+ [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
NSPoint ptWindowCoords = [[nsView window] mouseLocationOutsideOfEventStream];
NSPoint ptViewCoords = [nsView convertPoint:ptWindowCoords fromView:nil];
underMouse = [nsView hitTest:ptViewCoords] != nil;
}];
-
+
JNF_COCOA_EXIT(env);
-
+
return underMouse;
}
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/CTrayIcon.m Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/CTrayIcon.m Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -134,8 +134,7 @@
NSPoint absP = [NSEvent mouseLocation];
NSEventType type = [event type];
- NSRect screenRect = [[NSScreen mainScreen] frame];
- absP.y = screenRect.size.height - absP.y;
+ absP = ConvertNSScreenPoint(NULL, absP);
jint clickCount;
clickCount = [event clickCount];
@@ -179,15 +178,15 @@
isHighlighted = NO;
image = nil;
trackingArea = nil;
-
+
[self addTrackingArea];
-
+
return self;
}
- (void)addTrackingArea {
- NSTrackingAreaOptions options = NSTrackingMouseMoved |
- NSTrackingInVisibleRect |
+ NSTrackingAreaOptions options = NSTrackingMouseMoved |
+ NSTrackingInVisibleRect |
NSTrackingActiveAlways;
trackingArea = [[NSTrackingArea alloc] initWithRect: CGRectZero
options: options
@@ -410,3 +409,28 @@
return jpt;
}
+
+JNIEXPORT void JNICALL
+Java_sun_lwawt_macosx_CTrayIcon_nativeShowNotification
+(JNIEnv *env, jobject self, jlong model, jobject jcaption, jobject jtext,
+ long nsimage) {
+JNF_COCOA_ENTER(env);
+
+ AWTTrayIcon *icon = jlong_to_ptr(model);
+ NSString *caption = JNFJavaToNSString(env, jcaption);
+ NSString *text = JNFJavaToNSString(env, jtext);
+ NSImage * contentImage = jlong_to_ptr(nsimage);
+
+ [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
+ NSUserNotification *notification = [[NSUserNotification alloc] init];
+ notification.title = caption;
+ notification.informativeText = text;
+ notification.contentImage = contentImage;
+ notification.soundName = NSUserNotificationDefaultSoundName;
+
+ [[NSUserNotificationCenter defaultUserNotificationCenter]
+ deliverNotification:notification];
+ }];
+
+JNF_COCOA_EXIT(env);
+}
--- a/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.h Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.h Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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,7 +32,7 @@
#import <Cocoa/Cocoa.h>
#import <JavaNativeFoundation/JavaNativeFoundation.h>
-@interface NSApplicationAWT : NSApplication {
+@interface NSApplicationAWT : NSApplication <NSUserNotificationCenterDelegate> {
NSString *fApplicationName;
NSWindow *eventTransparentWindow;
NSTimeInterval dummyEventTimestamp;
--- a/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m Wed Nov 08 16:03:35 2017 -0500
@@ -77,6 +77,8 @@
- (void)dealloc
{
+ [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:nil];
+
[fApplicationName release];
fApplicationName = nil;
@@ -138,10 +140,18 @@
[super finishLaunching];
+ [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
+
// inform any interested parties that the AWT has arrived and is pumping
[[NSNotificationCenter defaultCenter] postNotificationName:JNFRunLoopDidStartNotification object:self];
}
+- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center
+ shouldPresentNotification:(NSUserNotification *)notification
+{
+ return YES; // We always show notifications to the user
+}
+
- (void) registerWithProcessManager
{
// Headless: NO
--- a/src/java.desktop/share/classes/com/sun/awt/AWTUtilities.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/com/sun/awt/AWTUtilities.java Wed Nov 08 16:03:35 2017 -0500
@@ -25,7 +25,16 @@
package com.sun.awt;
-import java.awt.*;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dialog;
+import java.awt.Frame;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Shape;
+import java.awt.Toolkit;
+import java.awt.Window;
import javax.swing.JRootPane;
@@ -64,6 +73,7 @@
* drastically between update release, and it may even be
* removed or be moved in some other package(s)/class(es).
*/
+@Deprecated(forRemoval = true, since = "10")
public final class AWTUtilities {
/**
@@ -114,7 +124,10 @@
* (either PERPIXEL_TRANSPARENT,
* TRANSLUCENT, or PERPIXEL_TRANSLUCENT)
* @return whether the given translucency kind is supported
+ * @deprecated use {@link GraphicsDevice#isWindowTranslucencySupported}
+ * instead
*/
+ @Deprecated(forRemoval = true, since = "10")
public static boolean isTranslucencySupported(Translucency translucencyKind) {
switch (translucencyKind) {
case PERPIXEL_TRANSPARENT:
@@ -166,14 +179,15 @@
* and the opacity is less than 1.0f
* @throws UnsupportedOperationException if the TRANSLUCENT translucency
* kind is not supported
+ * @deprecated use {@link Window#setOpacity} instead
*/
+ @Deprecated(forRemoval = true, since = "10")
public static void setWindowOpacity(Window window, float opacity) {
if (window == null) {
throw new NullPointerException(
"The window argument should not be null.");
}
-
- AWTAccessor.getWindowAccessor().setOpacity(window, opacity);
+ window.setOpacity(opacity);
}
/**
@@ -182,14 +196,16 @@
*
* @param window the window to get the opacity level from
* @throws NullPointerException if the window argument is null
+ * @deprecated use {@link Window#getOpacity} instead
*/
+ @Deprecated(forRemoval = true, since = "10")
public static float getWindowOpacity(Window window) {
if (window == null) {
throw new NullPointerException(
"The window argument should not be null.");
}
- return AWTAccessor.getWindowAccessor().getOpacity(window);
+ return window.getOpacity();
}
/**
@@ -198,7 +214,10 @@
* Note that this method may sometimes return true, but the native
* windowing system may still not support the concept of
* shaping (due to the bugs in the windowing system).
+ * @deprecated use {@link GraphicsDevice#isWindowTranslucencySupported}
+ * instead
*/
+ @Deprecated(forRemoval = true, since = "10")
public static boolean isWindowShapingSupported() {
Toolkit curToolkit = Toolkit.getDefaultToolkit();
if (!(curToolkit instanceof SunToolkit)) {
@@ -216,13 +235,15 @@
* @param window the window to get the shape from
* @return the current shape of the window
* @throws NullPointerException if the window argument is null
+ * @deprecated use {@link Window#getShape} instead
*/
+ @Deprecated(forRemoval = true, since = "10")
public static Shape getWindowShape(Window window) {
if (window == null) {
throw new NullPointerException(
"The window argument should not be null.");
}
- return AWTAccessor.getWindowAccessor().getShape(window);
+ return window.getShape();
}
/**
@@ -247,13 +268,15 @@
* and the shape is not null
* @throws UnsupportedOperationException if the PERPIXEL_TRANSPARENT
* translucency kind is not supported
+ * @deprecated use {@link Window#setShape} instead
*/
+ @Deprecated(forRemoval = true, since = "10")
public static void setWindowShape(Window window, Shape shape) {
if (window == null) {
throw new NullPointerException(
"The window argument should not be null.");
}
- AWTAccessor.getWindowAccessor().setShape(window, shape);
+ window.setShape(shape);
}
private static boolean isWindowTranslucencySupported() {
@@ -349,7 +372,9 @@
* isOpaque argument is {@code false}.
* @throws UnsupportedOperationException if the PERPIXEL_TRANSLUCENT
* translucency kind is not supported
+ * @deprecated use {@link Window#setBackground} instead
*/
+ @Deprecated(forRemoval = true, since = "10")
public static void setWindowOpaque(Window window, boolean isOpaque) {
if (window == null) {
throw new NullPointerException(
@@ -359,7 +384,12 @@
throw new UnsupportedOperationException(
"The PERPIXEL_TRANSLUCENT translucency kind is not supported");
}
- AWTAccessor.getWindowAccessor().setOpaque(window, isOpaque);
+ Color bg = window.getBackground();
+ if (bg == null) {
+ bg = new Color(0, 0, 0, 0);
+ }
+ window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(),
+ isOpaque ? 255 : 0));
}
/**
@@ -369,7 +399,9 @@
* @return whether the window is currently opaque (true)
* or translucent (false)
* @throws NullPointerException if the window argument is null
+ * @deprecated use {@link Window#isOpaque} instead
*/
+ @Deprecated(forRemoval = true, since = "10")
public static boolean isWindowOpaque(Window window) {
if (window == null) {
throw new NullPointerException(
@@ -395,7 +427,10 @@
* @throws NullPointerException if the gc argument is null
* @return whether the given GraphicsConfiguration supports
* the translucency effects.
+ * @deprecated use {@link GraphicsConfiguration#isTranslucencyCapable}
+ * instead
*/
+ @Deprecated(forRemoval = true, since = "10")
public static boolean isTranslucencyCapable(GraphicsConfiguration gc) {
if (gc == null) {
throw new NullPointerException("The gc argument should not be null");
@@ -448,8 +483,9 @@
* 'mixing-cutout' shape
* @param shape the new 'mixing-cutout' shape
* @throws NullPointerException if the component argument is {@code null}
+ * @deprecated use {@link Component#setMixingCutoutShape} instead
*/
- @Deprecated(since = "9")
+ @Deprecated(forRemoval = true, since = "9")
public static void setComponentMixingCutoutShape(Component component,
Shape shape)
{
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFCompressor.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFCompressor.java Wed Nov 08 16:03:35 2017 -0500
@@ -68,12 +68,7 @@
protected ImageOutputStream stream;
/**
- * Creates a compressor object for use in compressing TIFF data. This
- * object may be passed to the
- * {@link TIFFImageWriteParam#setTIFFCompressor(TIFFCompressor)}
- * method to override the compressor of a supported compression type or
- * to provide the implementation of the compression algorithm of an
- * unsupported compression type.
+ * Creates a compressor object for use in compressing TIFF data.
*
* <p>The parameters {@code compressionTagValue} and
* {@code isCompressionLossless} are provided to accomodate
--- a/src/java.desktop/share/classes/java/applet/AppletContext.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/applet/AppletContext.java Wed Nov 08 16:03:35 2017 -0500
@@ -117,24 +117,30 @@
* <table class="striped">
* <caption>Target arguments and their descriptions</caption>
* <thead>
- * <tr><th>Target Argument</th>
- * <th>Description</th></tr>
+ * <tr>
+ * <th scope="col">Target Argument
+ * <th scope="col">Description
* </thead>
* <tbody>
- * <tr><td>{@code "_self"} <td>Show in the window and frame that
- * contain the applet.</tr>
- * <tr><td>{@code "_parent"}<td>Show in the applet's parent frame. If
- * the applet's frame has no parent frame,
- * acts the same as "_self".</tr>
- * <tr><td>{@code "_top"} <td>Show in the top-level frame of the applet's
- * window. If the applet's frame is the
- * top-level frame, acts the same as "_self".</tr>
- * <tr><td>{@code "_blank"} <td>Show in a new, unnamed
- * top-level window.</tr>
- * <tr><td><i>name</i><td>Show in the frame or window named <i>name</i>. If
- * a target named <i>name</i> does not already exist, a
- * new top-level window with the specified name is created,
- * and the document is shown there.</tr>
+ * <tr>
+ * <th scope="row">{@code "_self"}
+ * <td>Show in the window and frame that contain the applet.
+ * <tr>
+ * <th scope="row">{@code "_parent"}
+ * <td>Show in the applet's parent frame. If the applet's frame has no
+ * parent frame, acts the same as "_self".
+ * <tr>
+ * <th scope="row">{@code "_top"}
+ * <td>Show in the top-level frame of the applet's window. If the
+ * applet's frame is the top-level frame, acts the same as "_self".
+ * <tr>
+ * <th scope="row">{@code "_blank"}
+ * <td>Show in a new, unnamed top-level window.
+ * <tr>
+ * <th scope="row"><i>name</i>
+ * <td>Show in the frame or window named <i>name</i>. If a target named
+ * <i>name</i> does not already exist, a new top-level window with the
+ * specified name is created, and the document is shown there.
* </tbody>
* </table>
* <p>
--- a/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java Wed Nov 08 16:03:35 2017 -0500
@@ -94,25 +94,23 @@
* <table class="striped">
* <caption>AWTKeyStroke default values</caption>
* <thead>
- * <tr><th>Property</th><th>Default Value</th></tr>
+ * <tr>
+ * <th scope="col">Property
+ * <th scope="col">Default Value
* </thead>
* <tbody>
- * <tr>
- * <td>Key Char</td>
- * <td>{@code KeyEvent.CHAR_UNDEFINED}</td>
- * </tr>
- * <tr>
- * <td>Key Code</td>
- * <td>{@code KeyEvent.VK_UNDEFINED}</td>
- * </tr>
- * <tr>
- * <td>Modifiers</td>
- * <td>none</td>
- * </tr>
- * <tr>
- * <td>On key release?</td>
- * <td>{@code false}</td>
- * </tr>
+ * <tr>
+ * <th scope="row">Key Char
+ * <td>{@code KeyEvent.CHAR_UNDEFINED}
+ * <tr>
+ * <th scope="row">Key Code
+ * <td>{@code KeyEvent.VK_UNDEFINED}
+ * <tr>
+ * <th scope="row">Modifiers
+ * <td>none
+ * <tr>
+ * <th scope="row">On key release?
+ * <td>{@code false}
* </tbody>
* </table>
*
--- a/src/java.desktop/share/classes/java/awt/AWTPermission.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/AWTPermission.java Wed Nov 08 16:03:35 2017 -0500
@@ -48,144 +48,116 @@
* <caption>AWTPermission target names, descriptions, and associated risks
* </caption>
* <thead>
- * <tr>
- * <th>Permission Target Name</th>
- * <th>What the Permission Allows</th>
- * <th>Risks of Allowing this Permission</th>
- * </tr>
+ * <tr>
+ * <th scope="col">Permission Target Name
+ * <th scope="col">What the Permission Allows
+ * <th scope="col">Risks of Allowing this Permission
* </thead>
* <tbody>
- * <tr>
- * <td>accessClipboard</td>
- * <td>Posting and retrieval of information to and from the AWT clipboard</td>
- * <td>This would allow malfeasant code to share
- * potentially sensitive or confidential information.</td>
- * </tr>
- *
- * <tr>
- * <td>accessEventQueue</td>
- * <td>Access to the AWT event queue</td>
- * <td>After retrieving the AWT event queue,
- * malicious code may peek at and even remove existing events
- * from its event queue, as well as post bogus events which may purposefully
- * cause the application or applet to misbehave in an insecure manner.</td>
- * </tr>
- *
- * <tr>
- * <td>accessSystemTray</td>
- * <td>Access to the AWT SystemTray instance</td>
- * <td>This would allow malicious code to add tray icons to the system tray.
- * First, such an icon may look like the icon of some known application
- * (such as a firewall or anti-virus) and order a user to do something unsafe
- * (with help of balloon messages). Second, the system tray may be glutted with
- * tray icons so that no one could add a tray icon anymore.</td>
- * </tr>
- *
- * <tr>
- * <td>createRobot</td>
- * <td>Create java.awt.Robot objects</td>
- * <td>The java.awt.Robot object allows code to generate native-level
- * mouse and keyboard events as well as read the screen. It could allow
- * malicious code to control the system, run other programs, read the
- * display, and deny mouse and keyboard access to the user.</td>
- * </tr>
- *
- * <tr>
- * <td>fullScreenExclusive</td>
- * <td>Enter full-screen exclusive mode</td>
- * <td>Entering full-screen exclusive mode allows direct access to
- * low-level graphics card memory. This could be used to spoof the
- * system, since the program is in direct control of rendering. Depending on
- * the implementation, the security warning may not be shown for the windows
- * used to enter the full-screen exclusive mode (assuming that the {@code
- * fullScreenExclusive} permission has been granted to this application). Note
- * that this behavior does not mean that the {@code
- * showWindowWithoutWarningBanner} permission will be automatically granted to
- * the application which has the {@code fullScreenExclusive} permission:
- * non-full-screen windows will continue to be shown with the security
- * warning.</td>
- * </tr>
- *
- * <tr>
- * <td>listenToAllAWTEvents</td>
- * <td>Listen to all AWT events, system-wide</td>
- * <td>After adding an AWT event listener,
- * malicious code may scan all AWT events dispatched in the system,
- * allowing it to read all user input (such as passwords). Each
- * AWT event listener is called from within the context of that
- * event queue's EventDispatchThread, so if the accessEventQueue
- * permission is also enabled, malicious code could modify the
- * contents of AWT event queues system-wide, causing the application
- * or applet to misbehave in an insecure manner.</td>
- * </tr>
- *
- * <tr>
- * <td>readDisplayPixels</td>
- * <td>Readback of pixels from the display screen</td>
- * <td>Interfaces such as the java.awt.Composite interface or the
- * java.awt.Robot class allow arbitrary code to examine pixels on the
- * display enable malicious code to snoop on the activities of the user.</td>
- * </tr>
- *
- * <tr>
- * <td>replaceKeyboardFocusManager</td>
- * <td>Sets the {@code KeyboardFocusManager} for
- * a particular thread.
- * <td>When {@code SecurityManager} is installed, the invoking
- * thread must be granted this permission in order to replace
- * the current {@code KeyboardFocusManager}. If permission
- * is not granted, a {@code SecurityException} will be thrown.
- * </tr>
- *
- * <tr>
- * <td>setAppletStub</td>
- * <td>Setting the stub which implements Applet container services</td>
- * <td>Malicious code could set an applet's stub and result in unexpected
- * behavior or denial of service to an applet.</td>
- * </tr>
- *
- * <tr>
- * <td>setWindowAlwaysOnTop</td>
- * <td>Setting always-on-top property of the window: {@link Window#setAlwaysOnTop}</td>
- * <td>The malicious window might make itself look and behave like a real full desktop, so that
- * information entered by the unsuspecting user is captured and subsequently misused </td>
- * </tr>
- *
- * <tr>
- * <td>showWindowWithoutWarningBanner</td>
- * <td>Display of a window without also displaying a banner warning
- * that the window was created by an applet</td>
- * <td>Without this warning,
- * an applet may pop up windows without the user knowing that they
- * belong to an applet. Since users may make security-sensitive
- * decisions based on whether or not the window belongs to an applet
- * (entering a username and password into a dialog box, for example),
- * disabling this warning banner may allow applets to trick the user
- * into entering such information.</td>
- * </tr>
- *
- * <tr>
- * <td>toolkitModality</td>
- * <td>Creating {@link Dialog.ModalityType#TOOLKIT_MODAL TOOLKIT_MODAL} dialogs
- * and setting the {@link Dialog.ModalExclusionType#TOOLKIT_EXCLUDE
- * TOOLKIT_EXCLUDE} window property.</td>
- * <td>When a toolkit-modal dialog is shown from an applet, it blocks all other
- * applets in the browser. When launching applications from Java Web Start,
- * its windows (such as the security dialog) may also be blocked by toolkit-modal
- * dialogs, shown from these applications.</td>
- * </tr>
- *
- * <tr>
- * <td>watchMousePointer</td>
- * <td>Getting the information about the mouse pointer position at any
- * time</td>
- * <td>Constantly watching the mouse pointer,
- * an applet can make guesses about what the user is doing, i.e. moving
- * the mouse to the lower left corner of the screen most likely means that
- * the user is about to launch an application. If a virtual keypad is used
- * so that keyboard is emulated using the mouse, an applet may guess what
- * is being typed.</td>
- * </tr>
+ * <tr>
+ * <th scope="row">accessClipboard
+ * <td>Posting and retrieval of information to and from the AWT clipboard
+ * <td>This would allow malfeasant code to share potentially sensitive or
+ * confidential information.
+ * <tr>
+ * <th scope="row">accessEventQueue
+ * <td>Access to the AWT event queue
+ * <td>After retrieving the AWT event queue, malicious code may peek at and
+ * even remove existing events from its event queue, as well as post bogus
+ * events which may purposefully cause the application or applet to
+ * misbehave in an insecure manner.
+ * <tr>
+ * <th scope="row">accessSystemTray
+ * <td>Access to the AWT SystemTray instance
+ * <td>This would allow malicious code to add tray icons to the system tray.
+ * First, such an icon may look like the icon of some known application
+ * (such as a firewall or anti-virus) and order a user to do something
+ * unsafe (with help of balloon messages). Second, the system tray may be
+ * glutted with tray icons so that no one could add a tray icon anymore.
+ * <tr>
+ * <th scope="row">createRobot
+ * <td>Create java.awt.Robot objects
+ * <td>The java.awt.Robot object allows code to generate native-level mouse
+ * and keyboard events as well as read the screen. It could allow malicious
+ * code to control the system, run other programs, read the display, and
+ * deny mouse and keyboard access to the user.
+ * <tr>
+ * <th scope="row">fullScreenExclusive
+ * <td>Enter full-screen exclusive mode
+ * <td>Entering full-screen exclusive mode allows direct access to low-level
+ * graphics card memory. This could be used to spoof the system, since the
+ * program is in direct control of rendering. Depending on the
+ * implementation, the security warning may not be shown for the windows
+ * used to enter the full-screen exclusive mode (assuming that the
+ * {@code fullScreenExclusive} permission has been granted to this
+ * application). Note that this behavior does not mean that the
+ * {@code showWindowWithoutWarningBanner} permission will be automatically
+ * granted to the application which has the {@code fullScreenExclusive}
+ * permission: non-full-screen windows will continue to be shown with the
+ * security warning.
+ * <tr>
+ * <th scope="row">listenToAllAWTEvents
+ * <td>Listen to all AWT events, system-wide
+ * <td>After adding an AWT event listener, malicious code may scan all AWT
+ * events dispatched in the system, allowing it to read all user input (such
+ * as passwords). Each AWT event listener is called from within the context
+ * of that event queue's EventDispatchThread, so if the accessEventQueue
+ * permission is also enabled, malicious code could modify the contents of
+ * AWT event queues system-wide, causing the application or applet to
+ * misbehave in an insecure manner.
+ * <tr>
+ * <th scope="row">readDisplayPixels
+ * <td>Readback of pixels from the display screen
+ * <td>Interfaces such as the java.awt.Composite interface or the
+ * java.awt.Robot class allow arbitrary code to examine pixels on the
+ * display enable malicious code to snoop on the activities of the user.
+ * <tr>
+ * <th scope="row">replaceKeyboardFocusManager
+ * <td>Sets the {@code KeyboardFocusManager} for a particular thread.
+ * <td>When {@code SecurityManager} is installed, the invoking thread must
+ * be granted this permission in order to replace the current
+ * {@code KeyboardFocusManager}. If permission is not granted, a
+ * {@code SecurityException} will be thrown.
+ * <tr>
+ * <th scope="row">setAppletStub
+ * <td>Setting the stub which implements Applet container services
+ * <td>Malicious code could set an applet's stub and result in unexpected
+ * behavior or denial of service to an applet.
+ * <tr>
+ * <th scope="row">setWindowAlwaysOnTop
+ * <td>Setting always-on-top property of the window:
+ * {@link Window#setAlwaysOnTop}
+ * <td>The malicious window might make itself look and behave like a real
+ * full desktop, so that information entered by the unsuspecting user is
+ * captured and subsequently misused
+ * <tr>
+ * <th scope="row">showWindowWithoutWarningBanner
+ * <td>Display of a window without also displaying a banner warning that the
+ * window was created by an applet
+ * <td>Without this warning, an applet may pop up windows without the user
+ * knowing that they belong to an applet. Since users may make
+ * security-sensitive decisions based on whether or not the window belongs
+ * to an applet (entering a username and password into a dialog box, for
+ * example), disabling this warning banner may allow applets to trick the
+ * user into entering such information.
+ * <tr>
+ * <th scope="row">toolkitModality
+ * <td>Creating {@link Dialog.ModalityType#TOOLKIT_MODAL TOOLKIT_MODAL}
+ * dialogs and setting the
+ * {@link Dialog.ModalExclusionType#TOOLKIT_EXCLUDE TOOLKIT_EXCLUDE} window
+ * property.
+ * <td>When a toolkit-modal dialog is shown from an applet, it blocks all
+ * other applets in the browser. When launching applications from Java Web
+ * Start, its windows (such as the security dialog) may also be blocked by
+ * toolkit-modal dialogs, shown from these applications.
+ * <tr>
+ * <th scope="row">watchMousePointer
+ * <td>Getting the information about the mouse pointer position at any time
+ * <td>Constantly watching the mouse pointer, an applet can make guesses
+ * about what the user is doing, i.e. moving the mouse to the lower left
+ * corner of the screen most likely means that the user is about to launch
+ * an application. If a virtual keypad is used so that keyboard is emulated
+ * using the mouse, an applet may guess what is being typed.
* </tbody>
* </table>
*
@@ -195,11 +167,9 @@
* @see java.security.PermissionCollection
* @see java.lang.SecurityManager
*
- *
* @author Marianne Mueller
* @author Roland Schemers
*/
-
public final class AWTPermission extends BasicPermission {
/** use serialVersionUID from the Java 2 platform for interoperability */
--- a/src/java.desktop/share/classes/java/awt/AlphaComposite.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/AlphaComposite.java Wed Nov 08 16:03:35 2017 -0500
@@ -72,22 +72,40 @@
* The following factors are used in the description of the blending
* equation in the Porter and Duff paper:
*
- * <blockquote>
- * <table class="borderless">
+ * <table class="striped">
* <caption style="display:none">Factors</caption>
- * <tr><th style="text-align:left">Factor <th style="text-align:left">Definition
- * <tr><td><em>A<sub>s</sub></em><td>the alpha component of the source pixel
- * <tr><td><em>C<sub>s</sub></em><td>a color component of the source pixel in premultiplied form
- * <tr><td><em>A<sub>d</sub></em><td>the alpha component of the destination pixel
- * <tr><td><em>C<sub>d</sub></em><td>a color component of the destination pixel in premultiplied form
- * <tr><td><em>F<sub>s</sub></em><td>the fraction of the source pixel that contributes to the output
- * <tr><td><em>F<sub>d</sub></em><td>the fraction of the destination pixel that contributes
- * to the output
- * <tr><td><em>A<sub>r</sub></em><td>the alpha component of the result
- * <tr><td><em>C<sub>r</sub></em><td>a color component of the result in premultiplied form
+ * <thead>
+ * <tr>
+ * <th scope="col">Factor
+ * <th scope="col">Definition
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <th scope="row"><em>A<sub>s</sub></em>
+ * <td>the alpha component of the source pixel
+ * <tr>
+ * <th scope="row"><em>C<sub>s</sub></em>
+ * <td>a color component of the source pixel in premultiplied form
+ * <tr>
+ * <th scope="row"><em>A<sub>d</sub></em>
+ * <td>the alpha component of the destination pixel
+ * <tr>
+ * <th scope="row"><em>C<sub>d</sub></em>
+ * <td>a color component of the destination pixel in premultiplied form
+ * <tr>
+ * <th scope="row"><em>F<sub>s</sub></em>
+ * <td>the fraction of the source pixel that contributes to the output
+ * <tr>
+ * <th scope="row"><em>F<sub>d</sub></em>
+ * <td>the fraction of the destination pixel that contributes to the output
+ * <tr>
+ * <th scope="row"><em>A<sub>r</sub></em>
+ * <td>the alpha component of the result
+ * <tr>
+ * <th scope="row"><em>C<sub>r</sub></em>
+ * <td>a color component of the result in premultiplied form
+ * </tbody>
* </table>
- * </blockquote>
- *
* <p>
* Using these factors, Porter and Duff define 12 ways of choosing
* the blending factors <em>F<sub>s</sub></em> and <em>F<sub>d</sub></em> to
@@ -113,19 +131,37 @@
* The following factors will be used to discuss our extensions to
* the blending equation in the Porter and Duff paper:
*
- * <blockquote>
- * <table class="borderless">
+ * <table class="striped">
* <caption style="display:none">Factors</caption>
- * <tr><th style="text-align:left">Factor <th style="text-align:left">Definition
- * <tr><td><em>C<sub>sr</sub></em> <td>one of the raw color components of the source pixel
- * <tr><td><em>C<sub>dr</sub></em> <td>one of the raw color components of the destination pixel
- * <tr><td><em>A<sub>ac</sub></em> <td>the "extra" alpha component from the AlphaComposite instance
- * <tr><td><em>A<sub>sr</sub></em> <td>the raw alpha component of the source pixel
- * <tr><td><em>A<sub>dr</sub></em><td>the raw alpha component of the destination pixel
- * <tr><td><em>A<sub>df</sub></em> <td>the final alpha component stored in the destination
- * <tr><td><em>C<sub>df</sub></em> <td>the final raw color component stored in the destination
+ * <thead>
+ * <tr>
+ * <th scope="col">Factor
+ * <th scope="col">Definition
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <th scope="row"><em>C<sub>sr</sub></em>
+ * <td>one of the raw color components of the source pixel
+ * <tr>
+ * <th scope="row"><em>C<sub>dr</sub></em>
+ * <td>one of the raw color components of the destination pixel
+ * <tr>
+ * <th scope="row"><em>A<sub>ac</sub></em>
+ * <td>the "extra" alpha component from the AlphaComposite instance
+ * <tr>
+ * <th scope="row"><em>A<sub>sr</sub></em>
+ * <td>the raw alpha component of the source pixel
+ * <tr>
+ * <th scope="row"><em>A<sub>dr</sub></em>
+ * <td>the raw alpha component of the destination pixel
+ * <tr>
+ * <th scope="row"><em>A<sub>df</sub></em>
+ * <td>the final alpha component stored in the destination
+ * <tr>
+ * <th scope="row"><em>C<sub>df</sub></em>
+ * <td>the final raw color component stored in the destination
+ * </tbody>
* </table>
- *</blockquote>
*
* <h3>Preparing Inputs</h3>
*
--- a/src/java.desktop/share/classes/java/awt/Component.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/Component.java Wed Nov 08 16:03:35 2017 -0500
@@ -843,10 +843,6 @@
public Rectangle getBounds(Component comp) {
return new Rectangle(comp.x, comp.y, comp.width, comp.height);
}
- public void setMixingCutoutShape(Component comp, Shape shape) {
- comp.setMixingCutoutShape(shape);
- }
-
public void setGraphicsConfiguration(Component comp,
GraphicsConfiguration gc)
{
@@ -7247,28 +7243,24 @@
* <caption>Recommended default values for a Component's focus traversal
* keys</caption>
* <thead>
- * <tr>
- * <th>Identifier</th>
- * <th>Meaning</th>
- * <th>Default</th>
- * </tr>
+ * <tr>
+ * <th scope="col">Identifier
+ * <th scope="col">Meaning
+ * <th scope="col">Default
* </thead>
* <tbody>
- * <tr>
- * <td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
- * <td>Normal forward keyboard traversal</td>
- * <td>TAB on KEY_PRESSED, CTRL-TAB on KEY_PRESSED</td>
- * </tr>
- * <tr>
- * <td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
- * <td>Normal reverse keyboard traversal</td>
- * <td>SHIFT-TAB on KEY_PRESSED, CTRL-SHIFT-TAB on KEY_PRESSED</td>
- * </tr>
- * <tr>
- * <td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
- * <td>Go up one focus traversal cycle</td>
- * <td>none</td>
- * </tr>
+ * <tr>
+ * <th scope="row">KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS
+ * <td>Normal forward keyboard traversal
+ * <td>TAB on KEY_PRESSED, CTRL-TAB on KEY_PRESSED
+ * <tr>
+ * <th scope="row">KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS
+ * <td>Normal reverse keyboard traversal
+ * <td>SHIFT-TAB on KEY_PRESSED, CTRL-SHIFT-TAB on KEY_PRESSED
+ * <tr>
+ * <th scope="row">KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
+ * <td>Go up one focus traversal cycle
+ * <td>none
* </tbody>
* </table>
*
--- a/src/java.desktop/share/classes/java/awt/Container.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/Container.java Wed Nov 08 16:03:35 2017 -0500
@@ -3069,33 +3069,28 @@
* <caption>Recommended default values for a Container's focus traversal
* keys</caption>
* <thead>
- * <tr>
- * <th>Identifier</th>
- * <th>Meaning</th>
- * <th>Default</th>
- * </tr>
+ * <tr>
+ * <th scope="col">Identifier
+ * <th scope="col">Meaning
+ * <th scope="col">Default
* </thead>
* <tbody>
- * <tr>
- * <td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
- * <td>Normal forward keyboard traversal</td>
- * <td>TAB on KEY_PRESSED, CTRL-TAB on KEY_PRESSED</td>
- * </tr>
- * <tr>
- * <td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
- * <td>Normal reverse keyboard traversal</td>
- * <td>SHIFT-TAB on KEY_PRESSED, CTRL-SHIFT-TAB on KEY_PRESSED</td>
- * </tr>
- * <tr>
- * <td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
- * <td>Go up one focus traversal cycle</td>
- * <td>none</td>
- * </tr>
- * <tr>
- * <td>KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS</td>
- * <td>Go down one focus traversal cycle</td>
- * <td>none</td>
- * </tr>
+ * <tr>
+ * <th scope="row">KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS
+ * <td>Normal forward keyboard traversal
+ * <td>TAB on KEY_PRESSED, CTRL-TAB on KEY_PRESSED
+ * <tr>
+ * <th scope="row">KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS
+ * <td>Normal reverse keyboard traversal
+ * <td>SHIFT-TAB on KEY_PRESSED, CTRL-SHIFT-TAB on KEY_PRESSED
+ * <tr>
+ * <th scope="row">KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
+ * <td>Go up one focus traversal cycle
+ * <td>none
+ * <tr>
+ * <th scope="row">KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
+ * <td>Go down one focus traversal cycle
+ * <td>none
* </tbody>
* </table>
*
--- a/src/java.desktop/share/classes/java/awt/Desktop.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/Desktop.java Wed Nov 08 16:03:35 2017 -0500
@@ -768,13 +768,13 @@
* Installs the handler which is notified when the application is asked to
* open a list of files.
*
- * @implNote Please note that for Mac OS, notifications
+ * @implNote Please note that for macOS, notifications
* are only sent if the Java app is a bundled application,
* with a {@code CFBundleDocumentTypes} array present in its
- * Info.plist. See the
- * <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">
- * Info.plist Key Reference</a> for more information about adding a
- * {@code CFBundleDocumentTypes} key to your app's Info.plist.
+ * {@code Info.plist}. Check the
+ * <a href="https://developer.apple.com/documentation">
+ * Apple Developer Documentation</a> for more information about
+ * {@code Info.plist}.
*
* @param openFileHandler handler
*
@@ -800,13 +800,13 @@
* Installs the handler which is notified when the application is asked to
* print a list of files.
*
- * @implNote Please note that for Mac OS, notifications
+ * @implNote Please note that for macOS, notifications
* are only sent if the Java app is a bundled application,
* with a {@code CFBundleDocumentTypes} array present in its
- * Info.plist. See the
- * <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">
- * Info.plist Key Reference</a> for more information about adding a
- * {@code CFBundleDocumentTypes} key to your app's Info.plist.
+ * {@code Info.plist}. Check the
+ * <a href="https://developer.apple.com/documentation">
+ * Apple Developer Documentation</a> for more information about
+ * {@code Info.plist}.
*
* @param printFileHandler handler
* @throws SecurityException if a security manager exists and its
@@ -835,13 +835,13 @@
* {@link OpenURIHandler#openURI(OpenURIEvent)} requests to be
* enqueued until another handler is set.
*
- * @implNote Please note that for Mac OS, notifications
+ * @implNote Please note that for macOS, notifications
* are only sent if the Java app is a bundled application,
* with a {@code CFBundleDocumentTypes} array present in its
- * Info.plist. See the
- * <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">
- * Info.plist Key Reference</a> for more information about adding a
- * {@code CFBundleDocumentTypes} key to your app's Info.plist.
+ * {@code Info.plist}. Check the
+ * <a href="https://developer.apple.com/documentation">
+ * Apple Developer Documentation</a> for more information about
+ * {@code Info.plist}.
*
* @param openURIHandler handler
*
--- a/src/java.desktop/share/classes/java/awt/EventQueue.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/EventQueue.java Wed Nov 08 16:03:35 2017 -0500
@@ -680,33 +680,28 @@
* <table class="striped">
* <caption>Event types, source types, and dispatch methods</caption>
* <thead>
- * <tr>
- * <th>Event Type</th>
- * <th>Source Type</th>
- * <th>Dispatched To</th>
- * </tr>
+ * <tr>
+ * <th scope="col">Event Type
+ * <th scope="col">Source Type
+ * <th scope="col">Dispatched To
* </thead>
* <tbody>
- * <tr>
- * <td>ActiveEvent</td>
- * <td>Any</td>
- * <td>event.dispatch()</td>
- * </tr>
- * <tr>
- * <td>Other</td>
- * <td>Component</td>
- * <td>source.dispatchEvent(AWTEvent)</td>
- * </tr>
- * <tr>
- * <td>Other</td>
- * <td>MenuComponent</td>
- * <td>source.dispatchEvent(AWTEvent)</td>
- * </tr>
- * <tr>
- * <td>Other</td>
- * <td>Other</td>
- * <td>No action (ignored)</td>
- * </tr>
+ * <tr>
+ * <th scope="row">ActiveEvent
+ * <td>Any
+ * <td>event.dispatch()
+ * <tr>
+ * <th scope="row">Other
+ * <td>Component
+ * <td>source.dispatchEvent(AWTEvent)
+ * <tr>
+ * <th scope="row">Other
+ * <td>MenuComponent
+ * <td>source.dispatchEvent(AWTEvent)
+ * <tr>
+ * <th scope="row">Other
+ * <td>Other
+ * <td>No action (ignored)
* </tbody>
* </table>
*
--- a/src/java.desktop/share/classes/java/awt/GraphicsDevice.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/GraphicsDevice.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, 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
@@ -23,12 +23,10 @@
* questions.
*/
-
package java.awt;
import java.awt.image.ColorModel;
-import sun.awt.AWTAccessor;
import sun.awt.AppContext;
import sun.awt.SunToolkit;
--- a/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java Wed Nov 08 16:03:35 2017 -0500
@@ -1042,35 +1042,30 @@
* <table class="striped">
* <caption>Recommended default values for focus traversal keys</caption>
* <thead>
- * <tr>
- * <th>Identifier</th>
- * <th>Meaning</th>
- * <th>Default</th>
- * </tr>
+ * <tr>
+ * <th scope="col">Identifier
+ * <th scope="col">Meaning
+ * <th scope="col">Default
* </thead>
* <tbody>
- * <tr>
- * <td>{@code KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS}</td>
- * <td>Normal forward keyboard traversal</td>
- * <td>{@code TAB} on {@code KEY_PRESSED},
- * {@code CTRL-TAB} on {@code KEY_PRESSED}</td>
- * </tr>
- * <tr>
- * <td>{@code KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS}</td>
- * <td>Normal reverse keyboard traversal</td>
- * <td>{@code SHIFT-TAB} on {@code KEY_PRESSED},
- * {@code CTRL-SHIFT-TAB} on {@code KEY_PRESSED}</td>
- * </tr>
- * <tr>
- * <td>{@code KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS}</td>
- * <td>Go up one focus traversal cycle</td>
- * <td>none</td>
- * </tr>
- * <tr>
- * <td>{@code KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS}</td>
- * <td>Go down one focus traversal cycle</td>
- * <td>none</td>
- * </tr>
+ * <tr>
+ * <th scope="row">{@code KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS}
+ * <td>Normal forward keyboard traversal
+ * <td>{@code TAB} on {@code KEY_PRESSED}, {@code CTRL-TAB} on
+ * {@code KEY_PRESSED}
+ * <tr>
+ * <th scope="row">{@code KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS}
+ * <td>Normal reverse keyboard traversal
+ * <td>{@code SHIFT-TAB} on {@code KEY_PRESSED}, {@code CTRL-SHIFT-TAB}
+ * on {@code KEY_PRESSED}
+ * <tr>
+ * <th scope="row">{@code KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS}
+ * <td>Go up one focus traversal cycle
+ * <td>none
+ * <tr>
+ * <th scope="row">{@code KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS}
+ * <td>Go down one focus traversal cycle
+ * <td>none
* </tbody>
* </table>
*
--- a/src/java.desktop/share/classes/java/awt/Scrollbar.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/Scrollbar.java Wed Nov 08 16:03:35 2017 -0500
@@ -299,58 +299,44 @@
* <table class="striped">
* <caption>Scrollbar default properties</caption>
* <thead>
- * <tr>
- * <th>Property</th>
- * <th>Description</th>
- * <th>Default Value</th>
- * </tr>
+ * <tr>
+ * <th scope="col">Property
+ * <th scope="col">Description
+ * <th scope="col">Default Value
* </thead>
* <tbody>
- * <tr>
- * <td>orientation</td>
- * <td>indicates whether the scroll bar is vertical
- * <br>or horizontal</td>
- * <td>{@code Scrollbar.VERTICAL}</td>
- * </tr>
- * <tr>
- * <td>value</td>
- * <td>value which controls the location
- * <br>of the scroll bar's bubble</td>
- * <td>0</td>
- * </tr>
- * <tr>
- * <td>visible amount</td>
- * <td>visible amount of the scroll bar's range,
- * <br>typically represented by the size of the
- * <br>scroll bar's bubble</td>
- * <td>10</td>
- * </tr>
- * <tr>
- * <td>minimum</td>
- * <td>minimum value of the scroll bar</td>
- * <td>0</td>
- * </tr>
- * <tr>
- * <td>maximum</td>
- * <td>maximum value of the scroll bar</td>
- * <td>100</td>
- * </tr>
- * <tr>
- * <td>unit increment</td>
- * <td>amount the value changes when the
- * <br>Line Up or Line Down key is pressed,
- * <br>or when the end arrows of the scrollbar
- * <br>are clicked </td>
- * <td>1</td>
- * </tr>
- * <tr>
- * <td>block increment</td>
- * <td>amount the value changes when the
- * <br>Page Up or Page Down key is pressed,
- * <br>or when the scrollbar track is clicked
- * <br>on either side of the bubble </td>
- * <td>10</td>
- * </tr>
+ * <tr>
+ * <th scope="row">orientation
+ * <td>indicates whether the scroll bar is vertical or horizontal
+ * <td>{@code Scrollbar.VERTICAL}
+ * <tr>
+ * <th scope="row">value
+ * <td>value which controls the location of the scroll bar's bubble
+ * <td>0
+ * <tr>
+ * <th scope="row">visible amount
+ * <td>visible amount of the scroll bar's range, typically represented
+ * by the size of the scroll bar's bubble
+ * <td>10
+ * <tr>
+ * <th scope="row">minimum
+ * <td>minimum value of the scroll bar
+ * <td>0
+ * <tr>
+ * <th scope="row">maximum
+ * <td>maximum value of the scroll bar
+ * <td>100
+ * <tr>
+ * <th scope="row">unit increment
+ * <td>amount the value changes when the Line Up or Line Down key is
+ * pressed, or when the end arrows of the scrollbar are clicked
+ * <td>1
+ * <tr>
+ * <th scope="row">block increment
+ * <td>amount the value changes when the Page Up or Page Down key is
+ * pressed, or when the scrollbar track is clicked<br>on either side of
+ * the bubble
+ * <td>10
* </tbody>
* </table>
*
--- a/src/java.desktop/share/classes/java/awt/SystemTray.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/SystemTray.java Wed Nov 08 16:03:35 2017 -0500
@@ -371,28 +371,26 @@
* <table class="striped">
* <caption>SystemTray properties</caption>
* <thead>
- * <tr>
- * <th>Property</th>
- * <th>Description</th>
- * </tr>
+ * <tr>
+ * <th scope="col">Property
+ * <th scope="col">Description
* </thead>
* <tbody>
- * <tr>
- * <td>{@code trayIcons}</td>
- * <td>The {@code SystemTray}'s array of {@code TrayIcon} objects.
- * The array is accessed via the {@link #getTrayIcons} method.<br>
- * This property is changed when a tray icon is added to (or removed
- * from) the system tray.<br> For example, this property is changed
- * when the system tray becomes unavailable on the desktop<br>
- * and the tray icons are automatically removed.</td>
- * </tr>
- * <tr>
- * <td>{@code systemTray}</td>
- * <td>This property contains {@code SystemTray} instance when the system tray
- * is available or {@code null} otherwise.<br> This property is changed
- * when the system tray becomes available or unavailable on the desktop.<br>
- * The property is accessed by the {@link #getSystemTray} method.</td>
- * </tr>
+ * <tr>
+ * <th scope="row">{@code trayIcons}
+ * <td>The {@code SystemTray}'s array of {@code TrayIcon} objects. The
+ * array is accessed via the {@link #getTrayIcons} method. This property
+ * is changed when a tray icon is added to (or removed from) the system
+ * tray. For example, this property is changed when the system tray
+ * becomes unavailable on the desktop and the tray icons are
+ * automatically removed.
+ * <tr>
+ * <th scope="row">{@code systemTray}
+ * <td>This property contains {@code SystemTray} instance when the
+ * system tray is available or {@code null} otherwise. This property is
+ * changed when the system tray becomes available or unavailable on the
+ * desktop. The property is accessed by the {@link #getSystemTray}
+ * method.
* </tbody>
* </table>
* <p>
--- a/src/java.desktop/share/classes/java/awt/Window.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/Window.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -22,9 +22,17 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package java.awt;
-import java.awt.event.*;
+import java.awt.event.ComponentEvent;
+import java.awt.event.FocusEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowFocusListener;
+import java.awt.event.WindowListener;
+import java.awt.event.WindowStateListener;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.awt.im.InputContext;
@@ -48,7 +56,13 @@
import java.util.Set;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicBoolean;
-import javax.accessibility.*;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+
import sun.awt.AWTAccessor;
import sun.awt.AWTPermissions;
import sun.awt.AppContext;
@@ -4050,26 +4064,6 @@
static {
AWTAccessor.setWindowAccessor(new AWTAccessor.WindowAccessor() {
- public float getOpacity(Window window) {
- return window.opacity;
- }
- public void setOpacity(Window window, float opacity) {
- window.setOpacity(opacity);
- }
- public Shape getShape(Window window) {
- return window.getShape();
- }
- public void setShape(Window window, Shape shape) {
- window.setShape(shape);
- }
- public void setOpaque(Window window, boolean opaque) {
- Color bg = window.getBackground();
- if (bg == null) {
- bg = new Color(0, 0, 0, 0);
- }
- window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(),
- opaque ? 255 : 0));
- }
public void updateWindow(Window window) {
window.updateWindow();
}
--- a/src/java.desktop/share/classes/java/awt/event/MouseEvent.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/event/MouseEvent.java Wed Nov 08 16:03:35 2017 -0500
@@ -745,7 +745,6 @@
* @see #getClickCount()
* @see #isPopupTrigger()
* @see #getButton()
- * @see #button
* @see Toolkit#areExtraMouseButtonsEnabled()
* @see java.awt.MouseInfo#getNumberOfButtons()
* @see InputEvent#getMaskForButton(int)
--- a/src/java.desktop/share/classes/java/awt/font/NumericShaper.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/font/NumericShaper.java Wed Nov 08 16:03:35 2017 -0500
@@ -108,39 +108,36 @@
*
* <table class="plain">
* <caption>NumericShaper constants precedence</caption>
- * <thead>
- * <tr>
- * <th class="TableHeadingColor">Unicode Range</th>
- * <th class="TableHeadingColor">{@code NumericShaper} Constants</th>
- * <th class="TableHeadingColor">Precedence</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td rowspan="2">Arabic</td>
- * <td>{@link NumericShaper#ARABIC NumericShaper.ARABIC}<br>
- * {@link NumericShaper#EASTERN_ARABIC NumericShaper.EASTERN_ARABIC}</td>
- * <td>{@link NumericShaper#EASTERN_ARABIC NumericShaper.EASTERN_ARABIC}</td>
- * </tr>
- * <tr>
- * <td>{@link NumericShaper.Range#ARABIC}<br>
- * {@link NumericShaper.Range#EASTERN_ARABIC}</td>
- * <td>{@link NumericShaper.Range#EASTERN_ARABIC}</td>
- * </tr>
- * </tbody>
- * <tbody>
- * <tr>
- * <td>Tai Tham</td>
- * <td>{@link NumericShaper.Range#TAI_THAM_HORA}<br>
- * {@link NumericShaper.Range#TAI_THAM_THAM}</td>
- * <td>{@link NumericShaper.Range#TAI_THAM_THAM}</td>
- * </tr>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th scope="col">Unicode Range
+ * <th scope="col">{@code NumericShaper} Constants
+ * <th scope="col">Precedence
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <th scope="row" rowspan="2">Arabic
+ * <td>{@link NumericShaper#ARABIC NumericShaper.ARABIC}
+ * <br>
+ * {@link NumericShaper#EASTERN_ARABIC NumericShaper.EASTERN_ARABIC}
+ * <td>{@link NumericShaper#EASTERN_ARABIC NumericShaper.EASTERN_ARABIC}
+ * </tr>
+ * <tr>
+ * <th scope="row">{@link NumericShaper.Range#ARABIC}
+ * <br>
+ * {@link NumericShaper.Range#EASTERN_ARABIC}
+ * <td>{@link NumericShaper.Range#EASTERN_ARABIC}
+ * <tr>
+ * <th scope="row">Tai Tham
+ * <td>{@link NumericShaper.Range#TAI_THAM_HORA}
+ * <br>
+ * {@link NumericShaper.Range#TAI_THAM_THAM}
+ * <td>{@link NumericShaper.Range#TAI_THAM_THAM}
+ * </tbody>
* </table>
*
* @since 1.4
*/
-
public final class NumericShaper implements java.io.Serializable {
// For access from java.text.Bidi
--- a/src/java.desktop/share/classes/java/awt/font/TextAttribute.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/font/TextAttribute.java Wed Nov 08 16:03:35 2017 -0500
@@ -96,159 +96,141 @@
* </UL>
*
* <h4>Summary of attributes</h4>
- * <table style="float:center;width:95%" class="striped">
- * <caption>Key, value type, principal constants, and
- * default value behavior of all TextAttributes</caption>
+ *
+ * <table style="width:95%;margin: 0px auto" class="striped">
+ * <caption>Key, value type, principal constants, and default value behavior of
+ * all TextAttributes</caption>
* <thead>
- * <tr>
- * <th valign="TOP" style="text-align:center">Key</th>
- * <th valign="TOP" style="text-align:center">Value Type</th>
- * <th valign="TOP" style="text-align:center">Principal Constants</th>
- * <th valign="TOP" style="text-align:center">Default Value</th>
- * </tr>
+ * <tr>
+ * <th scope="col">Key
+ * <th scope="col">Value Type
+ * <th scope="col">Principal Constants
+ * <th scope="col">Default Value
* </thead>
* <tbody>
- * <tr>
- * <td valign="TOP">{@link #FAMILY}</td>
- * <td valign="TOP">String</td>
- * <td valign="TOP">See Font {@link java.awt.Font#DIALOG DIALOG},
- * {@link java.awt.Font#DIALOG_INPUT DIALOG_INPUT},<br> {@link java.awt.Font#SERIF SERIF},
- * {@link java.awt.Font#SANS_SERIF SANS_SERIF}, and {@link java.awt.Font#MONOSPACED MONOSPACED}.
- * </td>
- * <td valign="TOP">"Default" (use platform default)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #WEIGHT}</td>
- * <td valign="TOP">Number</td>
- * <td valign="TOP">WEIGHT_REGULAR, WEIGHT_BOLD</td>
- * <td valign="TOP">WEIGHT_REGULAR</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #WIDTH}</td>
- * <td valign="TOP">Number</td>
- * <td valign="TOP">WIDTH_CONDENSED, WIDTH_REGULAR,<br>WIDTH_EXTENDED</td>
- * <td valign="TOP">WIDTH_REGULAR</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #POSTURE}</td>
- * <td valign="TOP">Number</td>
- * <td valign="TOP">POSTURE_REGULAR, POSTURE_OBLIQUE</td>
- * <td valign="TOP">POSTURE_REGULAR</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #SIZE}</td>
- * <td valign="TOP">Number</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">12.0</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #TRANSFORM}</td>
- * <td valign="TOP">{@link TransformAttribute}</td>
- * <td valign="TOP">See TransformAttribute {@link TransformAttribute#IDENTITY IDENTITY}</td>
- * <td valign="TOP">TransformAttribute.IDENTITY</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #SUPERSCRIPT}</td>
- * <td valign="TOP">Integer</td>
- * <td valign="TOP">SUPERSCRIPT_SUPER, SUPERSCRIPT_SUB</td>
- * <td valign="TOP">0 (use the standard glyphs and metrics)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #FONT}</td>
- * <td valign="TOP">{@link java.awt.Font}</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">null (do not override font resolution)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #CHAR_REPLACEMENT}</td>
- * <td valign="TOP">{@link GraphicAttribute}</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">null (draw text using font glyphs)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #FOREGROUND}</td>
- * <td valign="TOP">{@link java.awt.Paint}</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">null (use current graphics paint)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #BACKGROUND}</td>
- * <td valign="TOP">{@link java.awt.Paint}</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">null (do not render background)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #UNDERLINE}</td>
- * <td valign="TOP">Integer</td>
- * <td valign="TOP">UNDERLINE_ON</td>
- * <td valign="TOP">-1 (do not render underline)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #STRIKETHROUGH}</td>
- * <td valign="TOP">Boolean</td>
- * <td valign="TOP">STRIKETHROUGH_ON</td>
- * <td valign="TOP">false (do not render strikethrough)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #RUN_DIRECTION}</td>
- * <td valign="TOP">Boolean</td>
- * <td valign="TOP">RUN_DIRECTION_LTR<br>RUN_DIRECTION_RTL</td>
- * <td valign="TOP">null (use {@link java.text.Bidi} standard default)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #BIDI_EMBEDDING}</td>
- * <td valign="TOP">Integer</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">0 (use base line direction)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #JUSTIFICATION}</td>
- * <td valign="TOP">Number</td>
- * <td valign="TOP">JUSTIFICATION_FULL</td>
- * <td valign="TOP">JUSTIFICATION_FULL</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #INPUT_METHOD_HIGHLIGHT}</td>
- * <td valign="TOP">{@link java.awt.im.InputMethodHighlight},<br>{@link java.text.Annotation}</td>
- * <td valign="TOP">(see class)</td>
- * <td valign="TOP">null (do not apply input highlighting)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #INPUT_METHOD_UNDERLINE}</td>
- * <td valign="TOP">Integer</td>
- * <td valign="TOP">UNDERLINE_LOW_ONE_PIXEL,<br>UNDERLINE_LOW_TWO_PIXEL</td>
- * <td valign="TOP">-1 (do not render underline)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #SWAP_COLORS}</td>
- * <td valign="TOP">Boolean</td>
- * <td valign="TOP">SWAP_COLORS_ON</td>
- * <td valign="TOP">false (do not swap colors)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #NUMERIC_SHAPING}</td>
- * <td valign="TOP">{@link java.awt.font.NumericShaper}</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">null (do not shape digits)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #KERNING}</td>
- * <td valign="TOP">Integer</td>
- * <td valign="TOP">KERNING_ON</td>
- * <td valign="TOP">0 (do not request kerning)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #LIGATURES}</td>
- * <td valign="TOP">Integer</td>
- * <td valign="TOP">LIGATURES_ON</td>
- * <td valign="TOP">0 (do not form optional ligatures)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #TRACKING}</td>
- * <td valign="TOP">Number</td>
- * <td valign="TOP">TRACKING_LOOSE, TRACKING_TIGHT</td>
- * <td valign="TOP">0 (do not add tracking)</td>
- * </tr>
+ * <tr>
+ * <th scope="row">{@link #FAMILY}
+ * <td>String
+ * <td>See Font {@link java.awt.Font#DIALOG DIALOG},
+ * {@link java.awt.Font#DIALOG_INPUT DIALOG_INPUT},
+ * <br>
+ * {@link java.awt.Font#SERIF SERIF},
+ * {@link java.awt.Font#SANS_SERIF SANS_SERIF}, and
+ * {@link java.awt.Font#MONOSPACED MONOSPACED}.
+ * <td>"Default" (use platform default)
+ * <tr>
+ * <th scope="row">{@link #WEIGHT}
+ * <td>Number
+ * <td>WEIGHT_REGULAR, WEIGHT_BOLD
+ * <td>WEIGHT_REGULAR
+ * <tr>
+ * <th scope="row">{@link #WIDTH}
+ * <td>Number
+ * <td>WIDTH_CONDENSED, WIDTH_REGULAR,<br>WIDTH_EXTENDED
+ * <td>WIDTH_REGULAR
+ * <tr>
+ * <th scope="row">{@link #POSTURE}
+ * <td>Number
+ * <td>POSTURE_REGULAR, POSTURE_OBLIQUE
+ * <td>POSTURE_REGULAR
+ * <tr>
+ * <th scope="row">{@link #SIZE}
+ * <td>Number
+ * <td>none
+ * <td>12.0
+ * <tr>
+ * <th scope="row">{@link #TRANSFORM}
+ * <td>{@link TransformAttribute}
+ * <td>See TransformAttribute {@link TransformAttribute#IDENTITY IDENTITY}
+ * <td>TransformAttribute.IDENTITY
+ * <tr>
+ * <th scope="row">{@link #SUPERSCRIPT}
+ * <td>Integer
+ * <td>SUPERSCRIPT_SUPER, SUPERSCRIPT_SUB
+ * <td>0 (use the standard glyphs and metrics)
+ * <tr>
+ * <th scope="row">{@link #FONT}
+ * <td>{@link java.awt.Font}
+ * <td>none
+ * <td>null (do not override font resolution)
+ * <tr>
+ * <th scope="row">{@link #CHAR_REPLACEMENT}
+ * <td>{@link GraphicAttribute}
+ * <td>none
+ * <td>null (draw text using font glyphs)
+ * <tr>
+ * <th scope="row">{@link #FOREGROUND}
+ * <td>{@link java.awt.Paint}
+ * <td>none
+ * <td>null (use current graphics paint)
+ * <tr>
+ * <th scope="row">{@link #BACKGROUND}
+ * <td>{@link java.awt.Paint}
+ * <td>none
+ * <td>null (do not render background)
+ * <tr>
+ * <th scope="row">{@link #UNDERLINE}
+ * <td>Integer
+ * <td>UNDERLINE_ON
+ * <td>-1 (do not render underline)
+ * <tr>
+ * <th scope="row">{@link #STRIKETHROUGH}
+ * <td>Boolean
+ * <td>STRIKETHROUGH_ON
+ * <td>false (do not render strikethrough)
+ * <tr>
+ * <th scope="row">{@link #RUN_DIRECTION}
+ * <td>Boolean
+ * <td>RUN_DIRECTION_LTR<br>RUN_DIRECTION_RTL
+ * <td>null (use {@link java.text.Bidi} standard default)
+ * <tr>
+ * <th scope="row">{@link #BIDI_EMBEDDING}
+ * <td>Integer
+ * <td>none
+ * <td>0 (use base line direction)
+ * <tr>
+ * <th scope="row">{@link #JUSTIFICATION}
+ * <td>Number
+ * <td>JUSTIFICATION_FULL
+ * <td>JUSTIFICATION_FULL
+ * <tr>
+ * <th scope="row">{@link #INPUT_METHOD_HIGHLIGHT}
+ * <td>{@link java.awt.im.InputMethodHighlight},
+ * <br>
+ * {@link java.text.Annotation}
+ * <td>(see class)
+ * <td>null (do not apply input highlighting)
+ * <tr>
+ * <th scope="row">{@link #INPUT_METHOD_UNDERLINE}
+ * <td>Integer
+ * <td>UNDERLINE_LOW_ONE_PIXEL,<br>UNDERLINE_LOW_TWO_PIXEL
+ * <td>-1 (do not render underline)
+ * <tr>
+ * <th scope="row">{@link #SWAP_COLORS}
+ * <td>Boolean
+ * <td>SWAP_COLORS_ON
+ * <td>false (do not swap colors)
+ * <tr>
+ * <th scope="row">{@link #NUMERIC_SHAPING}
+ * <td>{@link java.awt.font.NumericShaper}
+ * <td>none
+ * <td>null (do not shape digits)
+ * <tr>
+ * <th scope="row">{@link #KERNING}
+ * <td>Integer
+ * <td>KERNING_ON
+ * <td>0 (do not request kerning)
+ * <tr>
+ * <th scope="row">{@link #LIGATURES}
+ * <td>Integer
+ * <td>LIGATURES_ON
+ * <td>0 (do not form optional ligatures)
+ * <tr>
+ * <th scope="row">{@link #TRACKING}
+ * <td>Number
+ * <td>TRACKING_LOOSE, TRACKING_TIGHT
+ * <td>0 (do not add tracking)
+ * </tr>
* </tbody>
* </table>
*
--- a/src/java.desktop/share/classes/java/awt/image/RescaleOp.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/image/RescaleOp.java Wed Nov 08 16:03:35 2017 -0500
@@ -360,7 +360,8 @@
* of {@code src} is an {@code IndexColorModel},
* or if the number of scaling factors and offsets in this
* {@code RescaleOp} do not meet the requirements
- * stated in the class comments.
+ * stated in the class comments, or if the source and
+ * destination images differ in size.
*/
public final BufferedImage filter (BufferedImage src, BufferedImage dst) {
ColorModel srcCM = src.getColorModel();
@@ -473,7 +474,8 @@
* {@code dst} do not have the same number of bands,
* or if the number of scaling factors and offsets in this
* {@code RescaleOp} do not meet the requirements
- * stated in the class comments.
+ * stated in the class comments, or if the source and
+ * destination rasters differ in size.
*/
public final WritableRaster filter (Raster src, WritableRaster dst) {
return filterRasterImpl(src, dst, length, true);
--- a/src/java.desktop/share/classes/javax/imageio/package-info.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/imageio/package-info.java Wed Nov 08 16:03:35 2017 -0500
@@ -39,84 +39,77 @@
* <p>
* All implementations of javax.imageio provide the following standard image
* format plug-ins:
- * <div>
- * <table border=1 cellpadding=5 style="margin: 0px auto;" summary="Standard
- * image format plug-ins">
- * <tr>
- * <th> </th><th>Reading</th><th>Writing</th><th>Notes</th>
- * <th>Metadata</th>
- * </tr>
*
+ * <table class="striped">
+ * <caption>Standard image format plug-ins</caption>
+ * <thead>
+ * <tr>
+ * <th scope="col">Image format
+ * <th scope="col">Reading
+ * <th scope="col">Writing
+ * <th scope="col">Notes
+ * <th scope="col">Metadata
+ * </thead>
+ * <tbody>
* <!-- BMP plugin -->
- * <tr>
- * <td><a href="https://msdn.microsoft.com/en-us/library/dd183391.aspx">
- * BMP</a></td>
- * <td align='center'>yes</td>
- * <td align='center'>yes</td>
- * <td align='center'>none</td>
- * <td align='center'><a href='metadata/doc-files/bmp_metadata.html'>BMP
- * metadata format</a></td>
- * </tr>
- *
+ * <tr>
+ * <th scope="row">
+ * <a href="https://msdn.microsoft.com/en-us/library/dd183391.aspx">BMP</a>
+ * <td>yes
+ * <td>yes
+ * <td>none
+ * <td><a href='metadata/doc-files/bmp_metadata.html'>BMP
+ * metadata format</a>
* <!-- GIF plugin -->
- * <tr>
- * <td><a href="http://www.w3.org/Graphics/GIF/spec-gif89a.txt">GIF</a>
- * </td>
- * <td align='center'>yes</td>
- * <td align='center'>yes</td>
- * <td align='center'><a href="#gif_plugin_notes">GIF plug-in notes</a>
- * </td>
- * <td align='center'><a href='metadata/doc-files/gif_metadata.html'>GIF
- * metadata format</a></td>
- * </tr>
- *
+ * <tr>
+ * <th scope="row">
+ * <a href="http://www.w3.org/Graphics/GIF/spec-gif89a.txt">GIF</a>
+ * <td>yes
+ * <td>yes
+ * <td><a href="#gif_plugin_notes">GIF plug-in notes</a>
+ * <td><a href='metadata/doc-files/gif_metadata.html'>GIF
+ * metadata format</a>
* <!-- JPEG plugin -->
- * <tr>
- * <td><a href="http://www.jpeg.org">JPEG</a></td>
- * <td align='center'>yes</td>
- * <td align='center'>yes</td>
- * <td align='center'>none</td>
- * <td align='center'><a href='metadata/doc-files/jpeg_metadata.html'>
- * JPEG metadata format</a></td>
- * </tr>
- *
+ * <tr>
+ * <th scope="row"><a href="http://www.jpeg.org">JPEG</a>
+ * <td>yes
+ * <td>yes
+ * <td>none
+ * <td><a href='metadata/doc-files/jpeg_metadata.html'>
+ * JPEG metadata format</a>
* <!-- PNG plugin -->
- * <tr>
- * <td><a href="http://www.libpng.org/pub/png/spec/">PNG</a></td>
- * <td align='center'>yes</td>
- * <td align='center'>yes</td>
- * <td align='center'>none</td>
- * <td align='center'><a href='metadata/doc-files/png_metadata.html'>PNG
- * metadata format</a></td>
- * </tr>
- *
+ * <tr>
+ * <th scope="row"><a href="http://www.libpng.org/pub/png/spec/">PNG</a>
+ * <td>yes
+ * <td>yes
+ * <td>none
+ * <td><a href='metadata/doc-files/png_metadata.html'>PNG
+ * metadata format</a>
* <!-- TIFF plugin -->
- * <tr>
- * <td><a href="https://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf">
- * TIFF</a></td>
- * <td align='center'>yes</td>
- * <td align='center'>yes</td>
- * <td align='center'><a href='metadata/doc-files/tiff_metadata.html#Reading'>
- * TIFF plug-in notes</a></td>
- * <td align='center'><a href='metadata/doc-files/tiff_metadata.html#StreamMetadata'>
- * TIFF metadata format</a></td>
- * </tr>
- *
+ * <tr>
+ * <th scope="row">
+ * <a href="https://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf">
+ * TIFF</a>
+ * <td>yes
+ * <td>yes
+ * <td>
+ * <a href='metadata/doc-files/tiff_metadata.html#Reading'>TIFF plug-in
+ * notes</a>
+ * <td>
+ * <a href='metadata/doc-files/tiff_metadata.html#StreamMetadata'>TIFF
+ * metadata format</a>
* <!-- WBMP plugin -->
- * <tr>
- * <td><a href="http://www.wapforum.org/what/technical/SPEC-WAESpec-19990524.pdf">
- * WBMP</a></td>
- * <td align='center'>yes</td>
- * <td align='center'>yes</td>
- * <td align='center'>none</td>
- * <td align='center'><a href='metadata/doc-files/wbmp_metadata.html'>
- * WBMP metadata format</a></td>
- * </tr>
+ * <tr>
+ * <th scope="row">
+ * <a href="http://www.wapforum.org/what/technical/SPEC-WAESpec-19990524.pdf">
+ * WBMP</a>
+ * <td>yes
+ * <td>yes
+ * <td>none
+ * <td><a href='metadata/doc-files/wbmp_metadata.html'>
+ * WBMP metadata format</a>
+ * </tbody>
* </table>
- * </div>
- * <BR>
- * <BR>
- * <BR>
*
* <h2> Standard Plug-in Notes</h2>
*
--- a/src/java.desktop/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -54,13 +54,32 @@
* listed in the following
* table:
*
- * <table border=1>
- * <caption><b>Compression Types</b></caption>
- * <tr><th>Type String</th> <th>Description</th> <th>Image Types</th></tr>
- * <tr><td>BI_RGB</td> <td>Uncompressed RLE</td> <td>{@literal <= } 8-bits/sample</td></tr>
- * <tr><td>BI_RLE8</td> <td>8-bit Run Length Encoding</td> <td>{@literal <=} 8-bits/sample</td></tr>
- * <tr><td>BI_RLE4</td> <td>4-bit Run Length Encoding</td> <td>{@literal <=} 4-bits/sample</td></tr>
- * <tr><td>BI_BITFIELDS</td> <td>Packed data</td> <td> 16 or 32 bits/sample</td></tr>
+ * <table class="striped">
+ * <caption>Compression Types</caption>
+ * <thead>
+ * <tr>
+ * <th scope="col">Type String
+ * <th scope="col">Description
+ * <th scope="col">Image Types
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <th scope="row">BI_RGB
+ * <td>Uncompressed RLE
+ * <td>{@literal <= } 8-bits/sample
+ * <tr>
+ * <th scope="row">BI_RLE8
+ * <td>8-bit Run Length Encoding
+ * <td>{@literal <=} 8-bits/sample
+ * <tr>
+ * <th scope="row">BI_RLE4
+ * <td>4-bit Run Length Encoding
+ * <td>{@literal <=} 4-bits/sample
+ * <tr>
+ * <th scope="row">BI_BITFIELDS
+ * <td>Packed data
+ * <td>16 or 32 bits/sample
+ * </tbody>
* </table>
*/
public class BMPImageWriteParam extends ImageWriteParam {
--- a/src/java.desktop/share/classes/javax/imageio/plugins/tiff/TIFFField.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/imageio/plugins/tiff/TIFFField.java Wed Nov 08 16:03:35 2017 -0500
@@ -40,221 +40,83 @@
* TIFF data types are referred to by Java constants and mapped internally
* onto Java language data types and type names as follows:
*
- * <br>
- * <br>
- * <table border="1">
+ * <table class="striped">
* <caption>TIFF Data Type to Java Data Type Mapping</caption>
- *
- * <tr>
- * <th>
- * <b>TIFF Data Type</b>
- * </th>
- * <th>
- * <b>Java Constant</b>
- * </th>
- * <th>
- * <b>Java Data Type</b>
- * </th>
- * <th>
- * <b>Java Type Name</b>
- * </th>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code BYTE}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_BYTE}
- * </td>
- * <td>
- * {@code byte}
- * </td>
- * <td>
- * {@code "Byte"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code ASCII}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_ASCII}
- * </td>
- * <td>
- * {@code String}
- * </td>
- * <td>
- * {@code "Ascii"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code SHORT}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_SHORT}
- * </td>
- * <td>
- * {@code char}
- * </td>
- * <td>
- * {@code "Short"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code LONG}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_LONG}
- * </td>
- * <td>
- * {@code long}
- * </td>
- * <td>
- * {@code "Long"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code RATIONAL}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_RATIONAL}
- * </td>
- * <td>
- * {@code long[2]} {numerator, denominator}
- * </td>
- * <td>
- * {@code "Rational"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code SBYTE}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_SBYTE}
- * </td>
- * <td>
- * {@code byte}
- * </td>
- * <td>
- * {@code "SByte"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code UNDEFINED}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_UNDEFINED}
- * </td>
- * <td>
- * {@code byte}
- * </td>
- * <td>
- * {@code "Undefined"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code SSHORT}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_SSHORT}
- * </td>
- * <td>
- * {@code short}
- * </td>
- * <td>
- * {@code "SShort"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code SLONG}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_SLONG}
- * </td>
- * <td>
- * {@code int}
- * </td>
- * <td>
- * {@code "SLong"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code SRATIONAL}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_SRATIONAL}
- * </td>
- * <td>
- * {@code int[2]} {numerator, denominator}
- * </td>
- * <td>
- * {@code "SRational"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code FLOAT}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_FLOAT}
- * </td>
- * <td>
- * {@code float}
- * </td>
- * <td>
- * {@code "Float"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code DOUBLE}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_DOUBLE}
- * </td>
- * <td>
- * {@code double}
- * </td>
- * <td>
- * {@code "Double"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code IFD}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_IFD_POINTER}
- * </td>
- * <td>
- * {@code long}
- * </td>
- * <td>
- * {@code "IFDPointer"}
- * </td>
- * </tr>
- *
+ * <thead>
+ * <tr>
+ * <th scope="col">TIFF Data Type
+ * <th scope="col">Java Constant
+ * <th scope="col">Java Data Type
+ * <th scope="col">Java Type Name
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <th scope="row">{@code BYTE}
+ * <td>{@link TIFFTag#TIFF_BYTE}
+ * <td>{@code byte}
+ * <td>{@code "Byte"}
+ * <tr>
+ * <th scope="row">{@code ASCII}
+ * <td>{@link TIFFTag#TIFF_ASCII}
+ * <td>{@code String}
+ * <td>{@code "Ascii"}
+ * <tr>
+ * <th scope="row">{@code SHORT}
+ * <td>{@link TIFFTag#TIFF_SHORT}
+ * <td>{@code char}
+ * <td>{@code "Short"}
+ * <tr>
+ * <th scope="row">{@code LONG}
+ * <td>{@link TIFFTag#TIFF_LONG}
+ * <td>{@code long}
+ * <td>{@code "Long"}
+ * <tr>
+ * <th scope="row">{@code RATIONAL}
+ * <td>{@link TIFFTag#TIFF_RATIONAL}
+ * <td>{@code long[2]} {numerator, denominator}
+ * <td>{@code "Rational"}
+ * <tr>
+ * <th scope="row">{@code SBYTE}
+ * <td>{@link TIFFTag#TIFF_SBYTE}
+ * <td>{@code byte}
+ * <td>{@code "SByte"}
+ * <tr>
+ * <th scope="row">{@code UNDEFINED}
+ * <td>{@link TIFFTag#TIFF_UNDEFINED}
+ * <td>{@code byte}
+ * <td>{@code "Undefined"}
+ * <tr>
+ * <th scope="row">{@code SSHORT}
+ * <td>{@link TIFFTag#TIFF_SSHORT}
+ * <td>{@code short}
+ * <td>{@code "SShort"}
+ * <tr>
+ * <th scope="row">{@code SLONG}
+ * <td>{@link TIFFTag#TIFF_SLONG}
+ * <td>{@code int}
+ * <td>{@code "SLong"}
+ * <tr>
+ * <th scope="row">{@code SRATIONAL}
+ * <td>{@link TIFFTag#TIFF_SRATIONAL}
+ * <td>{@code int[2]} {numerator, denominator}
+ * <td>{@code "SRational"}
+ * <tr>
+ * <th scope="row">{@code FLOAT}
+ * <td>{@link TIFFTag#TIFF_FLOAT}
+ * <td>{@code float}
+ * <td>{@code "Float"}
+ * <tr>
+ * <th scope="row">{@code DOUBLE}
+ * <td>{@link TIFFTag#TIFF_DOUBLE}
+ * <td>{@code double}
+ * <td>{@code "Double"}
+ * <tr>
+ * <th scope="row">{@code IFD}
+ * <td>{@link TIFFTag#TIFF_IFD_POINTER}
+ * <td>{@code long}
+ * <td>{@code "IFDPointer"}
+ * </tr>
+ * </tbody>
* </table>
*
* @since 9
--- a/src/java.desktop/share/classes/javax/print/DocFlavor.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/print/DocFlavor.java Wed Nov 08 16:03:35 2017 -0500
@@ -175,21 +175,21 @@
* <caption>MIME-Types and their descriptions</caption>
* <thead>
* <tr>
- * <th>MIME-Type
- * <th>Description
+ * <th scope="col">MIME-Type
+ * <th scope="col">Description
* </thead>
* <tbody>
* <tr>
- * <td>{@code "text/plain"}
+ * <th scope="row">{@code "text/plain"}
* <td>Plain text in the default character set (US-ASCII)
* <tr>
- * <td><code> "text/plain; charset=<i>xxx</i>"</code>
+ * <th scope="row"><code> "text/plain; charset=<i>xxx</i>"</code>
* <td>Plain text in character set <i>xxx</i>
* <tr>
- * <td>{@code "text/html"}
+ * <th scope="row">{@code "text/html"}
* <td>HyperText Markup Language in the default character set (US-ASCII)
* <tr>
- * <td><code> "text/html; charset=<i>xxx</i>"</code>
+ * <th scope="row"><code> "text/html; charset=<i>xxx</i>"</code>
* <td>HyperText Markup Language in character set <i>xxx</i>
* </tbody>
* </table>
@@ -201,18 +201,18 @@
* <caption>MIME-Types and their descriptions</caption>
* <thead>
* <tr>
- * <th>MIME-Type
- * <th>Description
+ * <th scope="col">MIME-Type
+ * <th scope="col">Description
* </thead>
* <tbody>
* <tr>
- * <td>{@code "application/pdf"}
+ * <th scope="row">{@code "application/pdf"}
* <td>Portable Document Format document
* <tr>
- * <td>{@code "application/postscript"}
+ * <th scope="row">{@code "application/postscript"}
* <td>PostScript document
* <tr>
- * <td>{@code "application/vnd.hp-PCL"}
+ * <th scope="row">{@code "application/vnd.hp-PCL"}
* <td>Printer Control Language document
* </tbody>
* </table>
@@ -223,18 +223,18 @@
* <caption>MIME-Types and their descriptions</caption>
* <thead>
* <tr>
- * <th>MIME-Type
- * <th>Description
+ * <th scope="col">MIME-Type
+ * <th scope="col">Description
* </thead>
* <tbody>
* <tr>
- * <td>{@code "image/gif"}
+ * <th scope="row">{@code "image/gif"}
* <td>Graphics Interchange Format image
* <tr>
- * <td>{@code "image/jpeg"}
+ * <th scope="row">{@code "image/jpeg"}
* <td>Joint Photographic Experts Group image
* <tr>
- * <td>{@code "image/png"}
+ * <th scope="row">{@code "image/png"}
* <td>Portable Network Graphics image
* </tbody>
* </table>
@@ -245,12 +245,12 @@
* <caption>MIME-Types and their descriptions</caption>
* <thead>
* <tr>
- * <th>MIME-Type
- * <th>Description
+ * <th scope="col">MIME-Type
+ * <th scope="col">Description
* </thead>
* <tbody>
* <tr>
- * <td>{@code "application/octet-stream"}
+ * <th scope="row">{@code "application/octet-stream"}
* <td>The print data format is unspecified (just an octet stream)
* </tbody>
* </table>
--- a/src/java.desktop/share/classes/javax/print/attribute/standard/Chromaticity.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/print/attribute/standard/Chromaticity.java Wed Nov 08 16:03:35 2017 -0500
@@ -42,22 +42,23 @@
* The table below shows the effects of specifying a Chromaticity attribute of
* {@link #MONOCHROME MONOCHROME} or {@link #COLOR COLOR} for a monochrome or
* color document.
+ *
* <table class="striped">
* <caption>Shows effects of specifying {@code MONOCHROME} or {@code COLOR}
* Chromaticity attributes</caption>
* <thead>
* <tr>
- * <th>Chromaticity<br>Attribute
- * <th>Effect on<br>Monochrome Document
- * <th>Effect on<br>Color Document
+ * <th scope="col">Chromaticity<br>Attribute
+ * <th scope="col">Effect on<br>Monochrome Document
+ * <th scope="col">Effect on<br>Color Document
* </thead>
* <tbody>
* <tr>
- * <td>{@link #MONOCHROME MONOCHROME}
+ * <th scope="row">{@link #MONOCHROME MONOCHROME}
* <td>Printed as is, in monochrome
* <td>Printed in monochrome, with colors converted to shades of gray
* <tr>
- * <td>{@link #COLOR COLOR}
+ * <th scope="row">{@link #COLOR COLOR}
* <td>Printed as is, in monochrome
* <td>Printed as is, in color
* </tbody>
--- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobKOctets.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobKOctets.java Wed Nov 08 16:03:35 2017 -0500
@@ -69,40 +69,41 @@
* The size of a doc is computed based on the print data representation class as
* specified by the doc's {@link javax.print.DocFlavor DocFlavor}, as shown in
* the table below.
+ *
* <table class="striped">
* <caption>Table showing computation of doc sizes</caption>
* <thead>
* <tr>
- * <th>Representation Class
- * <th>Document Size
+ * <th scope="col">Representation Class
+ * <th scope="col">Document Size
* </thead>
* <tbody>
* <tr>
- * <td>{@code byte[]}
+ * <th scope="row">{@code byte[]}
* <td>Length of the byte array
* <tr>
- * <td>{@code java.io.InputStream}
+ * <th scope="row">{@code java.io.InputStream}
* <td>Number of bytes read from the stream
* <tr>
- * <td>{@code char[]}
+ * <th scope="row">{@code char[]}
* <td>Length of the character array x 2
* <tr>
- * <td>{@code java.lang.String}
+ * <th scope="row">{@code java.lang.String}
* <td>Length of the string x 2
* <tr>
- * <td>{@code java.io.Reader}
+ * <th scope="row">{@code java.io.Reader}
* <td>Number of characters read from the stream x 2
* <tr>
- * <td>{@code java.net.URL}
+ * <th scope="row">{@code java.net.URL}
* <td>Number of bytes read from the file at the given {@code URL} address
* <tr>
- * <td>{@code java.awt.image.renderable.RenderableImage}
+ * <th scope="row">{@code java.awt.image.renderable.RenderableImage}
* <td>Implementation dependent*
* <tr>
- * <td>{@code java.awt.print.Printable}
+ * <th scope="row">{@code java.awt.print.Printable}
* <td>Implementation dependent*
* <tr>
- * <td>{@code java.awt.print.Pageable}
+ * <th scope="row">{@code java.awt.print.Pageable}
* <td>Implementation dependent*
* </tbody>
* </table>
--- a/src/java.desktop/share/classes/javax/print/attribute/standard/PresentationDirection.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/print/attribute/standard/PresentationDirection.java Wed Nov 08 16:03:35 2017 -0500
@@ -41,10 +41,10 @@
* <p>
* <b>IPP Compatibility:</b> This attribute is not an IPP 1.1 attribute; it is
* an attribute in the Production Printing Extension
- * (<a href="ftp://ftp.pwg.org/pub/pwg/standards/pwg5100.3.pdf">PDF</a>) of IPP
- * 1.1. The category name returned by {@code getName()} is the IPP attribute
- * name. The enumeration's integer value is the IPP enum value. The
- * {@code toString()} method returns the IPP string representation of the
+ * (<a href="ftp://ftp.pwg.org/pub/pwg/standards/temp_archive/pwg5100.3.pdf">
+ * PDF</a>) of IPP 1.1. The category name returned by {@code getName()} is the
+ * IPP attribute name. The enumeration's integer value is the IPP enum value.
+ * The {@code toString()} method returns the IPP string representation of the
* attribute value.
*
* @author Phil Race
--- a/src/java.desktop/share/classes/javax/print/attribute/standard/package-info.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/print/attribute/standard/package-info.java Wed Nov 08 16:03:35 2017 -0500
@@ -150,412 +150,437 @@
* attribute, the column marked "SupportedValuesAttribute" lists the
* supported-values attribute class, if any, with which a print service
* indicates the supported values for that attribute category.
- * <table border=1 cellpadding=2 cellspacing=1 summary="Lists all printing
- * attributes as described in above text">
- * <tr style="background-color:#E5E5E5">
- * <th valign="bottom">Attribute Class
- * <th valign="bottom">Doc<br>Attribute
- * <th valign="bottom">Print<br>Request<br>Attribute
- * <th valign="bottom">Print<br>Job<br>Attribute
- * <th valign="bottom">Print<br>Service<br>Attribute
- * <th valign="bottom">SupportedValuesAttribute
+ *
+ * <table class="striped">
+ * <caption>Lists all printing attributes as described above</caption>
+ * <thead>
* <tr>
- * <td><a href="Compression.html">Compression</a>
+ * <th scope="col">Attribute Class
+ * <th scope="col">Doc<br>Attribute
+ * <th scope="col">Print<br>Request<br>Attribute
+ * <th scope="col">Print<br>Job<br>Attribute
+ * <th scope="col">Print<br>Service<br>Attribute
+ * <th scope="col">SupportedValuesAttribute
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <th scope="row"><a href="Compression.html">Compression</a>
* <td align="center">X
* <td>
* <td>
* <td>
* <td>
* <tr>
- * <td><a href="DocumentName.html">DocumentName</a>
+ * <th scope="row"><a href="DocumentName.html">DocumentName</a>
* <td align="center">X
* <td>
* <td>
* <td>
* <td>
* <tr>
- * <td><a href="Chromaticity.html">Chromaticity</a>
+ * <th scope="row"><a href="Chromaticity.html">Chromaticity</a>
* <td align="center">X
* <td align="center">X
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="Copies.html">Copies</a>
+ * <th scope="row"><a href="Copies.html">Copies</a>
* <td>
* <td align="center">X
* <td align="center">X
* <td>
* <td><a href="CopiesSupported.html">CopiesSupported</a>
* <tr>
- * <td><a href="Finishings.html">Finishings</a>
+ * <th scope="row"><a href="Finishings.html">Finishings</a>
* <td align="center">X
* <td align="center">X
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="JobHoldUntil.html">JobHoldUntil</a>
+ * <th scope="row"><a href="JobHoldUntil.html">JobHoldUntil</a>
* <td>
* <td align="center">X
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="JobImpressions.html">JobImpressions</a>
+ * <th scope="row"><a href="JobImpressions.html">JobImpressions</a>
* <td>
* <td align="center">X
* <td align="center">X
* <td>
* <td><a href="JobImpressionsSupported.html">JobImpressionsSupported</a>
* <tr>
- * <td><a href="JobKOctets.html">JobKOctets</a>
+ * <th scope="row"><a href="JobKOctets.html">JobKOctets</a>
* <td>
* <td align="center">X
* <td align="center">X
* <td>
* <td><a href="JobKOctetsSupported.html">JobKOctetsSupported</a>
* <tr>
- * <td><a href="JobMediaSheets.html">JobMediaSheets</a>
+ * <th scope="row"><a href="JobMediaSheets.html">JobMediaSheets</a>
* <td>
* <td align="center">X
* <td align="center">X
* <td>
* <td><a href="JobMediaSheetsSupported.html">JobMediaSheetsSupported</a>
* <tr>
- * <td><a href="JobName.html">JobName</a>
+ * <th scope="row"><a href="JobName.html">JobName</a>
* <td>
* <td align="center">X
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="JobPriority.html">JobPriority</a>
+ * <th scope="row"><a href="JobPriority.html">JobPriority</a>
* <td>
* <td align="center">X
* <td align="center">X
* <td>
* <td><a href="JobPrioritySupported.html">JobPrioritySupported</a>
* <tr>
- * <td><a href="JobSheets.html">JobSheets</a>
+ * <th scope="row"><a href="JobSheets.html">JobSheets</a>
* <td>
* <td align="center">X
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="Media.html">Media</a>
+ * <th scope="row"><a href="Media.html">Media</a>
* <td align="center">X
* <td align="center">X
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="MediaSize.html">MediaSize</a>
+ * <th scope="row"><a href="MediaSize.html">MediaSize</a>
* <td>
* <td>
* <td>
* <td>
* <td>
* <tr>
- * <td><a href="MultipleDocumentHandling.html">MultipleDocumentHandling</a>
+ * <th scope="row"><a href="MultipleDocumentHandling.html">
+ * MultipleDocumentHandling</a>
* <td>
* <td align="center">X
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="NumberUp.html">NumberUp</a>
+ * <th scope="row"><a href="NumberUp.html">NumberUp</a>
* <td align="center">X
* <td align="center">X
* <td align="center">X
* <td>
* <td><a href="NumberUpSupported.html">NumberUpSupported</a>
* <tr>
- * <td><a href="OrientationRequested.html">OrientationRequested</a>
+ * <th scope="row"><a href="OrientationRequested.html">
+ * OrientationRequested</a>
* <td align="center">X
* <td align="center">X
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="PageRanges.html">PageRanges</a>
+ * <th scope="row"><a href="PageRanges.html">PageRanges</a>
* <td align="center">X
* <td align="center">X
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="PresentationDirection.html">PresentationDirection</a>
+ * <th scope="row"><a href="PresentationDirection.html">
+ * PresentationDirection</a>
* <td align="center">X
* <td align="center">X
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="PrinterResolution.html">PrinterResolution</a>
+ * <th scope="row"><a href="PrinterResolution.html">PrinterResolution</a>
* <td align="center">X
* <td align="center">X
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="PrintQuality.html">PrintQuality</a>
+ * <th scope="row"><a href="PrintQuality.html">PrintQuality</a>
* <td align="center">X
* <td align="center">X
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="RequestingUserName.html">RequestingUserName</a>
+ * <th scope="row"><a href="RequestingUserName.html">RequestingUserName</a>
* <td>
* <td align="center">X
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="SheetCollate.html">SheetCollate</a>
+ * <th scope="row"><a href="SheetCollate.html">SheetCollate</a>
* <td align="center">X
* <td align="center">X
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="Sides.html">Sides</a>
+ * <th scope="row"><a href="Sides.html">Sides</a>
* <td align="center">X
* <td align="center">X
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="DateTimeAtCompleted.html">DateTimeAtCompleted</a>
+ * <th scope="row"><a href="DateTimeAtCompleted.html">
+ * DateTimeAtCompleted</a>
* <td>
* <td>
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="DateTimeAtCreation.html">DateTimeAtCreation</a>
+ * <th scope="row"><a href="DateTimeAtCreation.html">DateTimeAtCreation</a>
* <td>
* <td>
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="DateTimeAtProcessing.html">DateTimeAtProcessing</a>
+ * <th scope="row"><a href="DateTimeAtProcessing.html">
+ * DateTimeAtProcessing</a>
+ * <td>
+ * <td>
+ * <td align="center">X
+ * <td>
+ * <td>
+ * <tr>
+ * <th scope="row"><a href="JobImpressionsCompleted.html">
+ * JobImpressionsCompleted</a>
* <td>
* <td>
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="JobImpressionsCompleted.html">JobImpressionsCompleted</a>
+ * <th scope="row"><a href="JobKOctetsProcessed.html">
+ * JobKOctetsProcessed</a>
* <td>
* <td>
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="JobKOctetsProcessed.html">JobKOctetsProcessed</a>
+ * <th scope="row"><a href="JobMediaSheetsCompleted.html">
+ * JobMediaSheetsCompleted</a>
* <td>
* <td>
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="JobMediaSheetsCompleted.html">JobMediaSheetsCompleted</a>
+ * <th scope="row"><a href="JobMessageFromOperator.html">
+ * JobMessageFromOperator</a>
* <td>
* <td>
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="JobMessageFromOperator.html">JobMessageFromOperator</a>
+ * <th scope="row"><a href="JobOriginatingUserName.html">
+ * JobOriginatingUserName</a>
* <td>
* <td>
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="JobOriginatingUserName.html">JobOriginatingUserName</a>
+ * <th scope="row"><a href="JobState.html">JobState</a>
* <td>
* <td>
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="JobState.html">JobState</a>
+ * <th scope="row"><a href="JobStateReasons.html">JobStateReasons</a>
+ * <br>
+ * Contains zero or more --
* <td>
* <td>
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="JobStateReasons.html">JobStateReasons</a><br>
- * Contains zero or more --
+ * <th scope="row">-- <a href="JobStateReason.html">JobStateReason</a>
+ * <td>
+ * <td>
+ * <td>
+ * <td>
+ * <td>
+ * <tr>
+ * <th scope="row"><a href="NumberOfDocuments.html">NumberOfDocuments</a>
* <td>
* <td>
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td>-- <a href="JobStateReason.html">JobStateReason</a>
- * <td>
- * <td>
- * <td>
- * <td>
- * <td>
- * <tr>
- * <td><a href="NumberOfDocuments.html">NumberOfDocuments</a>
+ * <th scope="row"><a href="NumberOfInterveningJobs.html">
+ * NumberOfInterveningJobs</a>
* <td>
* <td>
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="NumberOfInterveningJobs.html">NumberOfInterveningJobs</a>
- * <td>
- * <td>
- * <td align="center">X
- * <td>
- * <td>
- * <tr>
- * <td><a href="OutputDeviceAssigned.html">OutputDeviceAssigned</a>
+ * <th scope="row"><a href="OutputDeviceAssigned.html">
+ * OutputDeviceAssigned</a>
* <td>
* <td>
* <td align="center">X
* <td>
* <td>
* <tr>
- * <td><a href="ColorSupported.html">ColorSupported</a>
+ * <th scope="row"><a href="ColorSupported.html">ColorSupported</a>
* <td>
* <td>
* <td>
* <td align="center">X
* <td>
* <tr>
- * <td><a href="PagesPerMinute.html">PagesPerMinute</a>
+ * <th scope="row"><a href="PagesPerMinute.html">PagesPerMinute</a>
* <td>
* <td>
* <td>
* <td align="center">X
* <td>
* <tr>
- * <td><a href="PagesPerMinuteColor.html">PagesPerMinuteColor</a>
+ * <th scope="row"><a href="PagesPerMinuteColor.html">
+ * PagesPerMinuteColor</a>
+ * <td>
+ * <td>
+ * <td>
+ * <td align="center">X
+ * <td>
+ * <tr>
+ * <th scope="row"><a href="PDLOverrideSupported.html">
+ * PDLOverrideSupported</a>
* <td>
* <td>
* <td>
* <td align="center">X
* <td>
* <tr>
- * <td><a href="PDLOverrideSupported.html">PDLOverrideSupported</a>
+ * <th scope="row"><a href="PrinterIsAcceptingJobs.html">
+ * PrinterIsAcceptingJobs</a>
* <td>
* <td>
* <td>
* <td align="center">X
* <td>
* <tr>
- * <td><a href="PrinterIsAcceptingJobs.html">PrinterIsAcceptingJobs</a>
+ * <th scope="row"><a href="PrinterInfo.html">PrinterInfo</a>
* <td>
* <td>
* <td>
* <td align="center">X
* <td>
* <tr>
- * <td><a href="PrinterInfo.html">PrinterInfo</a>
+ * <th scope="row"><a href="PrinterLocation.html">PrinterLocation</a>
* <td>
* <td>
* <td>
* <td align="center">X
* <td>
* <tr>
- * <td><a href="PrinterLocation.html">PrinterLocation</a>
+ * <th scope="row"><a href="PrinterMessageFromOperator.html">
+ * PrinterMessageFromOperator</a>
* <td>
* <td>
* <td>
* <td align="center">X
* <td>
* <tr>
- * <td><a href="PrinterMessageFromOperator.html">
- * PrinterMessageFromOperator</a>
+ * <th scope="row"><a href="PrinterMakeAndModel.html">
+ * PrinterMakeAndModel</a>
* <td>
* <td>
* <td>
* <td align="center">X
* <td>
* <tr>
- * <td><a href="PrinterMakeAndModel.html">PrinterMakeAndModel</a>
+ * <th scope="row"><a href="PrinterMoreInfo.html">PrinterMoreInfo</a>
* <td>
* <td>
* <td>
* <td align="center">X
* <td>
* <tr>
- * <td><a href="PrinterMoreInfo.html">PrinterMoreInfo</a>
+ * <th scope="row"><a href="PrinterMoreInfoManufacturer.html">
+ * PrinterMoreInfoManufacturer</a>
* <td>
* <td>
* <td>
* <td align="center">X
* <td>
* <tr>
- * <td><a href="PrinterMoreInfoManufacturer.html">
- * PrinterMoreInfoManufacturer</a>
+ * <th scope="row"><a href="PrinterName.html">PrinterName</a>
* <td>
* <td>
* <td>
* <td align="center">X
* <td>
* <tr>
- * <td><a href="PrinterName.html">PrinterName</a>
+ * <th scope="row"><a href="PrinterState.html">PrinterState</a>
* <td>
* <td>
* <td>
* <td align="center">X
* <td>
* <tr>
- * <td><a href="PrinterState.html">PrinterState</a>
+ * <th scope="row"><a href="PrinterStateReasons.html">
+ * PrinterStateReasons</a>
+ * <br>
+ * Contains zero or more --
* <td>
* <td>
* <td>
* <td align="center">X
* <td>
* <tr>
- * <td><a href="PrinterStateReasons.html">PrinterStateReasons</a><br>
- * Contains zero or more --
+ * <th scope="row">-- <a href="PrinterStateReason.html">
+ * PrinterStateReason</a>
* <td>
* <td>
* <td>
- * <td align="center">X
+ * <td>
* <td>
* <tr>
- * <td>-- <a href="PrinterStateReason.html">PrinterStateReason</a>
+ * <th scope="row">-- <a href="Severity.html">Severity</a>
* <td>
* <td>
* <td>
* <td>
* <td>
* <tr>
- * <td>-- <a href="Severity.html">Severity</a>
- * <td>
- * <td>
- * <td>
- * <td>
- * <td>
- * <tr>
- * <td><a href="QueuedJobCount.html">QueuedJobCount</a>
+ * <th scope="row"><a href="QueuedJobCount.html">QueuedJobCount</a>
* <td>
* <td>
* <td>
* <td align="center">X
* <td>
* <tr>
- * <td><a href="ReferenceUriSchemesSupported.html">
- * ReferenceUriSchemesSupported</a>
+ * <th scope="row"><a href="ReferenceUriSchemesSupported.html">
+ * ReferenceUriSchemesSupported</a>
* <td>
* <td>
* <td>
* <td>
* <td>
+ * </tbody>
* </table>
* <p>
* Please note: In the {@code javax.print} APIs, a {@code null} reference
--- a/src/java.desktop/share/classes/javax/sound/midi/MidiFileFormat.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/sound/midi/MidiFileFormat.java Wed Nov 08 16:03:35 2017 -0500
@@ -43,32 +43,36 @@
* The following table lists some common properties that should be used in
* implementations:
*
- * <table border=1>
+ * <table class="striped">
* <caption>MIDI File Format Properties</caption>
+ * <thead>
* <tr>
- * <th>Property key
- * <th>Value type
- * <th>Description
+ * <th scope="col">Property key
+ * <th scope="col">Value type
+ * <th scope="col">Description
+ * </thead>
+ * <tbody>
* <tr>
- * <td>"author"
+ * <th scope="row">"author"
* <td>{@link String String}
* <td>name of the author of this file
* <tr>
- * <td>"title"
+ * <th scope="row">"title"
* <td>{@link String String}
* <td>title of this file
* <tr>
- * <td>"copyright"
+ * <th scope="row">"copyright"
* <td>{@link String String}
* <td>copyright message
* <tr>
- * <td>"date"
+ * <th scope="row">"date"
* <td>{@link java.util.Date Date}
* <td>date of the recording or release
* <tr>
- * <td>"comment"
+ * <th scope="row">"comment"
* <td>{@link String String}
* <td>an arbitrary text
+ * </tbody>
* </table>
*
* @author Kara Kytle
--- a/src/java.desktop/share/classes/javax/sound/midi/MidiSystem.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/sound/midi/MidiSystem.java Wed Nov 08 16:03:35 2017 -0500
@@ -78,32 +78,32 @@
* <caption>MIDI System Property Keys</caption>
* <thead>
* <tr>
- * <th>Property Key
- * <th>Interface
- * <th>Affected Method
+ * <th scope="col">Property Key
+ * <th scope="col">Interface
+ * <th scope="col">Affected Method
* </thead>
* <tbody>
* <tr>
- * <td>{@code javax.sound.midi.Receiver}
+ * <th scope="row">{@code javax.sound.midi.Receiver}
* <td>{@link Receiver}
* <td>{@link #getReceiver}
* <tr>
- * <td>{@code javax.sound.midi.Sequencer}
+ * <th scope="row">{@code javax.sound.midi.Sequencer}
* <td>{@link Sequencer}
* <td>{@link #getSequencer}
* <tr>
- * <td>{@code javax.sound.midi.Synthesizer}
+ * <th scope="row">{@code javax.sound.midi.Synthesizer}
* <td>{@link Synthesizer}
* <td>{@link #getSynthesizer}
* <tr>
- * <td>{@code javax.sound.midi.Transmitter}
+ * <th scope="row">{@code javax.sound.midi.Transmitter}
* <td>{@link Transmitter}
* <td>{@link #getTransmitter}
* </tbody>
* </table>
*
* The property value consists of the provider class name and the device name,
- * separated by the hash mark ("#"). The provider class name is the
+ * separated by the hash mark ("#"). The provider class name is the
* fully-qualified name of a concrete
* {@link MidiDeviceProvider MIDI device provider} class. The device name is
* matched against the {@code String} returned by the {@code getName} method of
--- a/src/java.desktop/share/classes/javax/sound/sampled/AudioFileFormat.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/sound/sampled/AudioFileFormat.java Wed Nov 08 16:03:35 2017 -0500
@@ -50,36 +50,40 @@
* The following table lists some common properties that should be used in
* implementations:
*
- * <table border=1>
+ * <table class="striped">
* <caption>Audio File Format Properties</caption>
+ * <thead>
* <tr>
- * <th>Property key
- * <th>Value type
- * <th>Description
+ * <th scope="col">Property key
+ * <th scope="col">Value type
+ * <th scope="col">Description
+ * </thead>
+ * <tbody>
* <tr>
- * <td>"duration"
+ * <th scope="row">"duration"
* <td>{@link Long Long}
* <td>playback duration of the file in microseconds
* <tr>
- * <td>"author"
+ * <th scope="row">"author"
* <td>{@link String String}
* <td>name of the author of this file
* <tr>
- * <td>"title"
+ * <th scope="row">"title"
* <td>{@link String String}
* <td>title of this file
* <tr>
- * <td>"copyright"
+ * <th scope="row">"copyright"
* <td>{@link String String}
* <td>copyright message
* <tr>
- * <td>"date"
+ * <th scope="row">"date"
* <td>{@link java.util.Date Date}
* <td>date of the recording or release
* <tr>
- * <td>"comment"
+ * <th scope="row">"comment"
* <td>{@link String String}
* <td>an arbitrary text
+ * </tbody>
* </table>
*
* @author David Rivas
--- a/src/java.desktop/share/classes/javax/sound/sampled/AudioFormat.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/sound/sampled/AudioFormat.java Wed Nov 08 16:03:35 2017 -0500
@@ -94,21 +94,21 @@
* <caption>Audio Format Properties</caption>
* <thead>
* <tr>
- * <th>Property key
- * <th>Value type
- * <th>Description
+ * <th scope="col">Property key
+ * <th scope="col">Value type
+ * <th scope="col">Description
* </thead>
* <tbody>
* <tr>
- * <td>"bitrate"
+ * <th scope="row">"bitrate"
* <td>{@link java.lang.Integer Integer}
* <td>average bit rate in bits per second
* <tr>
- * <td>"vbr"
+ * <th scope="row">"vbr"
* <td>{@link java.lang.Boolean Boolean}
* <td>{@code true}, if the file is encoded in variable bit rate (VBR)
* <tr>
- * <td>"quality"
+ * <th scope="row">"quality"
* <td>{@link java.lang.Integer Integer}
* <td>encoding/conversion quality, 1..100
* </tbody>
--- a/src/java.desktop/share/classes/javax/sound/sampled/AudioPermission.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/sound/sampled/AudioPermission.java Wed Nov 08 16:03:35 2017 -0500
@@ -46,13 +46,13 @@
* risks</caption>
* <thead>
* <tr>
- * <th>Permission Target Name
- * <th>What the Permission Allows
- * <th>Risks of Allowing this Permission
+ * <th scope="col">Permission Target Name
+ * <th scope="col">What the Permission Allows
+ * <th scope="col">Risks of Allowing this Permission
* </thead>
* <tbody>
* <tr>
- * <td>play
+ * <th scope="row">play
* <td>Audio playback through the audio device or devices on the system.
* Allows the application to obtain and manipulate lines and mixers for
* audio playback (rendering).
@@ -61,7 +61,7 @@
* audio being played on the system, or because manipulation of a mixer
* affects the audio for all lines using that mixer.
* <tr>
- * <td>record
+ * <th scope="row">record
* <td>Audio recording through the audio device or devices on the system.
* Allows the application to obtain and manipulate lines and mixers for
* audio recording (capture).
--- a/src/java.desktop/share/classes/javax/sound/sampled/AudioSystem.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/sound/sampled/AudioSystem.java Wed Nov 08 16:03:35 2017 -0500
@@ -75,32 +75,32 @@
* <caption>Audio System Property Keys</caption>
* <thead>
* <tr>
- * <th>Property Key
- * <th>Interface
- * <th>Affected Method(s)
+ * <th scope="col">Property Key
+ * <th scope="col">Interface
+ * <th scope="col">Affected Method(s)
* </thead>
* <tbody>
* <tr>
- * <td>{@code javax.sound.sampled.Clip}
+ * <th scope="row">{@code javax.sound.sampled.Clip}
* <td>{@link Clip}
* <td>{@link #getLine}, {@link #getClip}
* <tr>
- * <td>{@code javax.sound.sampled.Port}
+ * <th scope="row">{@code javax.sound.sampled.Port}
* <td>{@link Port}
* <td>{@link #getLine}
* <tr>
- * <td>{@code javax.sound.sampled.SourceDataLine}
+ * <th scope="row">{@code javax.sound.sampled.SourceDataLine}
* <td>{@link SourceDataLine}
* <td>{@link #getLine}, {@link #getSourceDataLine}
* <tr>
- * <td>{@code javax.sound.sampled.TargetDataLine}
+ * <th scope="row">{@code javax.sound.sampled.TargetDataLine}
* <td>{@link TargetDataLine}
* <td>{@link #getLine}, {@link #getTargetDataLine}
* </tbody>
* </table>
*
* The property value consists of the provider class name and the mixer name,
- * separated by the hash mark ("#"). The provider class name is the
+ * separated by the hash mark ("#"). The provider class name is the
* fully-qualified name of a concrete {@link MixerProvider mixer provider}
* class. The mixer name is matched against the {@code String} returned by the
* {@code getName} method of {@code Mixer.Info}. Either the class name, or the
--- a/src/java.desktop/share/classes/javax/sound/sampled/ReverbType.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/sound/sampled/ReverbType.java Wed Nov 08 16:03:35 2017 -0500
@@ -75,44 +75,44 @@
* early intensity, and early delay</caption>
* <thead>
* <tr>
- * <th>Type
- * <th>Decay Time (ms)
- * <th>Late Intensity (dB)
- * <th>Late Delay (ms)
- * <th>Early Intensity (dB)
- * <th>Early Delay(ms)
+ * <th scope="col">Type
+ * <th scope="col">Decay Time (ms)
+ * <th scope="col">Late Intensity (dB)
+ * <th scope="col">Late Delay (ms)
+ * <th scope="col">Early Intensity (dB)
+ * <th scope="col">Early Delay(ms)
* </thead>
* <tbody>
* <tr>
- * <td>Cavern
+ * <th scope="row">Cavern
* <td>2250
* <td>-2.0
* <td>41.3
* <td>-1.4
* <td>10.3
* <tr>
- * <td>Dungeon
+ * <th scope="row">Dungeon
* <td>1600
* <td>-1.0
* <td>10.3
* <td>-0.7
* <td>2.6
* <tr>
- * <td>Garage
+ * <th scope="row">Garage
* <td>900
* <td>-6.0
* <td>14.7
* <td>-4.0
* <td>3.9
* <tr>
- * <td>Acoustic Lab
+ * <th scope="row">Acoustic Lab
* <td>280
* <td>-3.0
* <td>8.0
* <td>-2.0
* <td>2.0
* <tr>
- * <td>Closet
+ * <th scope="row">Closet
* <td>150
* <td>-10.0
* <td>2.5
--- a/src/java.desktop/share/classes/javax/swing/Action.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/Action.java Wed Nov 08 16:03:35 2017 -0500
@@ -98,102 +98,88 @@
* <caption>Supported Action properties</caption>
* <thead>
* <tr>
- * <th>Component Property
- * <th>Components
- * <th>Action Key
- * <th>Notes
+ * <th scope="col">Component Property
+ * <th scope="col">Components
+ * <th scope="col">Action Key
+ * <th scope="col">Notes
* </thead>
* <tbody>
- * <tr valign="top" style="text-align:left">
- * <td><b><code>enabled</code></b>
- * <td>All
- * <td>The <code>isEnabled</code> method
- * <td>
- * <tr valign="top" style="text-align:left">
- * <td><b><code>toolTipText</code></b>
- * <td>All
- * <td><code>SHORT_DESCRIPTION</code>
- * <td>
- * <tr valign="top" style="text-align:left">
- * <td><b><code>actionCommand</code></b>
- * <td>All
- * <td><code>ACTION_COMMAND_KEY</code>
- * <td>
- * <tr valign="top" style="text-align:left">
- * <td><b><code>mnemonic</code></b>
- * <td>All buttons
- * <td><code>MNEMONIC_KEY</code>
- * <td>A <code>null</code> value or <code>Action</code> results in the
- * button's <code>mnemonic</code> property being set to
- * <code>'\0'</code>.
- * <tr valign="top" style="text-align:left">
- * <td><b><code>text</code></b>
- * <td>All buttons
- * <td><code>NAME</code>
- * <td>If you do not want the text of the button to mirror that
- * of the <code>Action</code>, set the property
- * <code>hideActionText</code> to <code>true</code>. If
- * <code>hideActionText</code> is <code>true</code>, setting the
- * <code>Action</code> changes the text of the button to
- * <code>null</code> and any changes to <code>NAME</code>
- * are ignored. <code>hideActionText</code> is useful for
- * tool bar buttons that typically only show an <code>Icon</code>.
- * <code>JToolBar.add(Action)</code> sets the property to
- * <code>true</code> if the <code>Action</code> has a
- * non-<code>null</code> value for <code>LARGE_ICON_KEY</code> or
- * <code>SMALL_ICON</code>.
- * <tr valign="top" style="text-align:left">
- * <td><b><code>displayedMnemonicIndex</code></b>
- * <td>All buttons
- * <td><code>DISPLAYED_MNEMONIC_INDEX_KEY</code>
- * <td>If the value of <code>DISPLAYED_MNEMONIC_INDEX_KEY</code> is
- * beyond the bounds of the text, it is ignored. When
- * <code>setAction</code> is called, if the value from the
- * <code>Action</code> is <code>null</code>, the displayed
- * mnemonic index is not updated. In any subsequent changes to
- * <code>DISPLAYED_MNEMONIC_INDEX_KEY</code>, <code>null</code>
- * is treated as -1.
- * <tr valign="top" style="text-align:left">
- * <td><b><code>icon</code></b>
- * <td>All buttons except of <code>JCheckBox</code>,
- * <code>JToggleButton</code> and <code>JRadioButton</code>.
- * <td>either <code>LARGE_ICON_KEY</code> or
- * <code>SMALL_ICON</code>
- * <td>The <code>JMenuItem</code> subclasses only use
- * <code>SMALL_ICON</code>. All other buttons will use
- * <code>LARGE_ICON_KEY</code>; if the value is <code>null</code> they
- * use <code>SMALL_ICON</code>.
- * <tr valign="top" style="text-align:left">
- * <td><b><code>accelerator</code></b>
- * <td>All <code>JMenuItem</code> subclasses, with the exception of
- * <code>JMenu</code>.
- * <td><code>ACCELERATOR_KEY</code>
- * <td>
- * <tr valign="top" style="text-align:left">
- * <td><b><code>selected</code></b>
- * <td><code>JToggleButton</code>, <code>JCheckBox</code>,
- * <code>JRadioButton</code>, <code>JCheckBoxMenuItem</code> and
- * <code>JRadioButtonMenuItem</code>
- * <td><code>SELECTED_KEY</code>
- * <td>Components that honor this property only use
- * the value if it is {@code non-null}. For example, if
- * you set an {@code Action} that has a {@code null}
- * value for {@code SELECTED_KEY} on a {@code JToggleButton}, the
- * {@code JToggleButton} will not update it's selected state in
- * any way. Similarly, any time the {@code JToggleButton}'s
- * selected state changes it will only set the value back on
- * the {@code Action} if the {@code Action} has a {@code non-null}
- * value for {@code SELECTED_KEY}.
- * <br>
- * Components that honor this property keep their selected state
- * in sync with this property. When the same {@code Action} is used
- * with multiple components, all the components keep their selected
- * state in sync with this property. Mutually exclusive
- * buttons, such as {@code JToggleButton}s in a {@code ButtonGroup},
- * force only one of the buttons to be selected. As such, do not
- * use the same {@code Action} that defines a value for the
- * {@code SELECTED_KEY} property with multiple mutually
- * exclusive buttons.
+ * <tr>
+ * <th scope="row">{@code enabled}
+ * <td>All
+ * <td>The {@code isEnabled} method
+ * <td>
+ * <tr>
+ * <th scope="row">{@code toolTipText}
+ * <td>All
+ * <td>{@code SHORT_DESCRIPTION}
+ * <td>
+ * <tr>
+ * <th scope="row">{@code actionCommand}
+ * <td>All
+ * <td>{@code ACTION_COMMAND_KEY}
+ * <td>
+ * <tr>
+ * <th scope="row">{@code mnemonic}
+ * <td>All buttons
+ * <td>{@code MNEMONIC_KEY}
+ * <td>A {@code null} value or {@code Action} results in the button's
+ * {@code mnemonic} property being set to {@code '\0'}.
+ * <tr>
+ * <th scope="row">{@code text}
+ * <td>All buttons
+ * <td>{@code NAME}
+ * <td>If you do not want the text of the button to mirror that of the
+ * {@code Action}, set the property {@code hideActionText} to {@code true}.
+ * If {@code hideActionText} is {@code true}, setting the {@code Action}
+ * changes the text of the button to {@code null} and any changes to
+ * {@code NAME} are ignored. {@code hideActionText} is useful for tool bar
+ * buttons that typically only show an {@code Icon}.
+ * {@code JToolBar.add(Action)} sets the property to {@code true} if the
+ * {@code Action} has a non-{@code null} value for {@code LARGE_ICON_KEY} or
+ * {@code SMALL_ICON}.
+ * <tr>
+ * <th scope="row">{@code displayedMnemonicIndex}
+ * <td>All buttons
+ * <td>{@code DISPLAYED_MNEMONIC_INDEX_KEY}
+ * <td>If the value of {@code DISPLAYED_MNEMONIC_INDEX_KEY} is beyond the
+ * bounds of the text, it is ignored. When {@code setAction} is called, if
+ * the value from the {@code Action} is {@code null}, the displayed mnemonic
+ * index is not updated. In any subsequent changes to
+ * {@code DISPLAYED_MNEMONIC_INDEX_KEY}, {@code null} is treated as -1.
+ * <tr>
+ * <th scope="row">{@code icon}
+ * <td>All buttons except of {@code JCheckBox}, {@code JToggleButton} and
+ * {@code JRadioButton}.
+ * <td>either {@code LARGE_ICON_KEY} or {@code SMALL_ICON}
+ * <td>The {@code JMenuItem} subclasses only use {@code SMALL_ICON}. All
+ * other buttons will use {@code LARGE_ICON_KEY}; if the value is
+ * {@code null} they use {@code SMALL_ICON}.
+ * <tr>
+ * <th scope="row">{@code accelerator}
+ * <td>All {@code JMenuItem} subclasses, with the exception of {@code JMenu}.
+ * <td>{@code ACCELERATOR_KEY}
+ * <td>
+ * <tr>
+ * <th scope="row">{@code selected}
+ * <td>{@code JToggleButton}, {@code JCheckBox}, {@code JRadioButton},
+ * {@code JCheckBoxMenuItem} and {@code JRadioButtonMenuItem}
+ * <td>{@code SELECTED_KEY}
+ * <td>Components that honor this property only use the value if it is
+ * {@code non-null}. For example, if you set an {@code Action} that has a
+ * {@code null} value for {@code SELECTED_KEY} on a {@code JToggleButton},
+ * the {@code JToggleButton} will not update it's selected state in any way.
+ * Similarly, any time the {@code JToggleButton}'s selected state changes it
+ * will only set the value back on the {@code Action} if the {@code Action}
+ * has a {@code non-null} value for {@code SELECTED_KEY}.
+ * <br>
+ * Components that honor this property keep their selected state in sync with
+ * this property. When the same {@code Action} is used with multiple
+ * components, all the components keep their selected state in sync with this
+ * property. Mutually exclusive buttons, such as {@code JToggleButton}s in a
+ * {@code ButtonGroup}, force only one of the buttons to be selected. As
+ * such, do not use the same {@code Action} that defines a value for the
+ * {@code SELECTED_KEY} property with multiple mutually exclusive buttons.
* </tbody>
* </table>
* <p>
--- a/src/java.desktop/share/classes/javax/swing/DefaultDesktopManager.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/DefaultDesktopManager.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -23,16 +23,22 @@
* questions.
*/
-
package javax.swing;
-import com.sun.awt.AWTUtilities;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.Window;
+import java.beans.PropertyVetoException;
+
import sun.awt.AWTAccessor;
import sun.awt.SunToolkit;
-import java.awt.*;
-import java.beans.PropertyVetoException;
-
/** This is an implementation of the <code>DesktopManager</code>.
* It currently implements the basic behaviors for managing
* <code>JInternalFrame</code>s in an arbitrary parent.
@@ -315,7 +321,7 @@
if (p != null) {
String mode = (String)p.getClientProperty("JDesktopPane.dragMode");
Window window = SwingUtilities.getWindowAncestor(f);
- if (window != null && !AWTUtilities.isWindowOpaque(window)) {
+ if (window != null && !window.isOpaque()) {
dragMode = DEFAULT_DRAG_MODE;
} else if (mode != null && mode.equals("outline")) {
dragMode = OUTLINE_DRAG_MODE;
--- a/src/java.desktop/share/classes/javax/swing/JComponent.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/JComponent.java Wed Nov 08 16:03:35 2017 -0500
@@ -121,7 +121,7 @@
* both of which are sections in <em>The Java Tutorial</em>.
* </ul>
* For more information on these subjects, see the
- * <a href="package-summary.html#package_description">Swing package description</a>
+ * {@link javax.swing Swing package description}
* and <em>The Java Tutorial</em> section
* <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/jcomponent.html">The JComponent Class</a>.
* <p>
--- a/src/java.desktop/share/classes/javax/swing/JEditorPane.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/JEditorPane.java Wed Nov 08 16:03:35 2017 -0500
@@ -1914,11 +1914,13 @@
/**
* Return an object that represents the link anchor,
- * as appropriate for that link. E.g. from HTML:
- * <a href="http://www.sun.com/access">Accessibility</a>
+ * as appropriate for that link.
+ * <p>
+ * E.g. from HTML:
+ * <a href="http://openjdk.java.net">OpenJDK</a>
* this method would return a String containing the text:
- * 'Accessibility'.
- *
+ * 'OpenJDK'.
+ * <p>
* Similarly, from this HTML:
* <a HREF="#top"><img src="top-hat.gif" alt="top hat"></a>
* this might return the object ImageIcon("top-hat.gif", "top hat");
--- a/src/java.desktop/share/classes/javax/swing/JFormattedTextField.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/JFormattedTextField.java Wed Nov 08 16:03:35 2017 -0500
@@ -59,27 +59,32 @@
* <caption>Possible JFormattedTextField configurations and their descriptions
* </caption>
* <thead>
- * <tr><th>Value</th>
- * <th>Description</th></tr>
+ * <tr>
+ * <th scope="col">Value
+ * <th scope="col">Description
* </thead>
* <tbody>
- * <tr><td>JFormattedTextField.REVERT
- * <td>Revert the display to match that of <code>getValue</code>,
- * possibly losing the current edit.
- * <tr><td>JFormattedTextField.COMMIT
- * <td>Commits the current value. If the value being edited
- * isn't considered a legal value by the
- * <code>AbstractFormatter</code> that is, a
- * <code>ParseException</code> is thrown, then the value
- * will not change, and then edited value will persist.
- * <tr><td>JFormattedTextField.COMMIT_OR_REVERT
- * <td>Similar to <code>COMMIT</code>, but if the value isn't
- * legal, behave like <code>REVERT</code>.
- * <tr><td>JFormattedTextField.PERSIST
- * <td>Do nothing, don't obtain a new
- * <code>AbstractFormatter</code>, and don't update the value.
+ * <tr>
+ * <th scope="row">JFormattedTextField.REVERT
+ * <td>Revert the display to match that of {@code getValue}, possibly losing
+ * the current edit.
+ * <tr>
+ * <th scope="row">JFormattedTextField.COMMIT
+ * <td>Commits the current value. If the value being edited isn't considered
+ * a legal value by the {@code AbstractFormatter} that is, a
+ * {@code ParseException} is thrown, then the value will not change, and
+ * then edited value will persist.
+ * <tr>
+ * <th scope="row">JFormattedTextField.COMMIT_OR_REVERT
+ * <td>Similar to {@code COMMIT}, but if the value isn't legal, behave like
+ * {@code REVERT}.
+ * <tr>
+ * <th scope="row">JFormattedTextField.PERSIST
+ * <td>Do nothing, don't obtain a new {@code AbstractFormatter}, and don't
+ * update the value.
* </tbody>
* </table>
+ *
* The default is <code>JFormattedTextField.COMMIT_OR_REVERT</code>,
* refer to {@link #setFocusLostBehavior} for more information on this.
* <p>
--- a/src/java.desktop/share/classes/javax/swing/JList.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/JList.java Wed Nov 08 16:03:35 2017 -0500
@@ -968,25 +968,30 @@
* <caption>Describes layouts VERTICAL,HORIZONTAL_WRAP, and VERTICAL_WRAP
* </caption>
* <thead>
- * <tr><th>Value</th><th>Description</th></tr>
+ * <tr>
+ * <th scope="col">Value
+ * <th scope="col">Description
* </thead>
* <tbody>
- * <tr><td><code>VERTICAL</code>
- * <td>Cells are layed out vertically in a single column.
- * <tr><td><code>HORIZONTAL_WRAP</code>
- * <td>Cells are layed out horizontally, wrapping to a new row as
- * necessary. If the {@code visibleRowCount} property is less than
- * or equal to zero, wrapping is determined by the width of the
- * list; otherwise wrapping is done in such a way as to ensure
- * {@code visibleRowCount} rows in the list.
- * <tr><td><code>VERTICAL_WRAP</code>
- * <td>Cells are layed out vertically, wrapping to a new column as
- * necessary. If the {@code visibleRowCount} property is less than
- * or equal to zero, wrapping is determined by the height of the
- * list; otherwise wrapping is done at {@code visibleRowCount} rows.
+ * <tr>
+ * <th scope="row">{@code VERTICAL}
+ * <td>Cells are layed out vertically in a single column.
+ * <tr>
+ * <th scope="row">{@code HORIZONTAL_WRAP}
+ * <td>Cells are layed out horizontally, wrapping to a new row as
+ * necessary. If the {@code visibleRowCount} property is less than or
+ * equal to zero, wrapping is determined by the width of the list;
+ * otherwise wrapping is done in such a way as to ensure
+ * {@code visibleRowCount} rows in the list.
+ * <tr>
+ * <th scope="row">{@code VERTICAL_WRAP}
+ * <td>Cells are layed out vertically, wrapping to a new column as
+ * necessary. If the {@code visibleRowCount} property is less than or
+ * equal to zero, wrapping is determined by the height of the list;
+ * otherwise wrapping is done at {@code visibleRowCount} rows.
* </tbody>
* </table>
- * <p>
+ *
* The default value of this property is <code>VERTICAL</code>.
*
* @param layoutOrientation the new layout orientation, one of:
--- a/src/java.desktop/share/classes/javax/swing/JOptionPane.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/JOptionPane.java Wed Nov 08 16:03:35 2017 -0500
@@ -71,37 +71,30 @@
* class may appear complex because of the large number of methods, almost
* all uses of this class are one-line calls to one of the static
* <code>showXxxDialog</code> methods shown below:
- * <blockquote>
*
* <table class="striped">
* <caption>Common JOptionPane method names and their descriptions</caption>
* <thead>
- * <tr>
- * <th>Method Name</th>
- * <th>Description</th>
- * </tr>
+ * <tr>
+ * <th scope="col">Method Name
+ * <th scope="col">Description
* </thead>
* <tbody>
- * <tr>
- * <td>showConfirmDialog</td>
- * <td>Asks a confirming question, like yes/no/cancel.</td>
- * </tr>
- * <tr>
- * <td>showInputDialog</td>
- * <td>Prompt for some input.</td>
- * </tr>
- * <tr>
- * <td>showMessageDialog</td>
- * <td>Tell the user about something that has happened.</td>
- * </tr>
- * <tr>
- * <td>showOptionDialog</td>
- * <td>The Grand Unification of the above three.</td>
- * </tr>
+ * <tr>
+ * <th scope="row">showConfirmDialog
+ * <td>Asks a confirming question, like yes/no/cancel.</td>
+ * <tr>
+ * <th scope="row">showInputDialog
+ * <td>Prompt for some input.
+ * <tr>
+ * <th scope="row">showMessageDialog
+ * <td>Tell the user about something that has happened.
+ * <tr>
+ * <th scope="row">showOptionDialog
+ * <td>The Grand Unification of the above three.
* </tbody>
* </table>
*
- * </blockquote>
* Each of these methods also comes in a <code>showInternalXXX</code>
* flavor, which uses an internal frame to hold the dialog box (see
* {@link JInternalFrame}).
@@ -148,7 +141,7 @@
* in which case a default <code>Frame</code> is used as the parent,
* and the dialog will be
* centered on the screen (depending on the {@literal L&F}).
- * <dt><a id=message>message</a><dd>
+ * <dt>message<dd>
* A descriptive message to be placed in the dialog box.
* In the most common usage, message is just a <code>String</code> or
* <code>String</code> constant.
--- a/src/java.desktop/share/classes/javax/swing/SpinnerNumberModel.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/SpinnerNumberModel.java Wed Nov 08 16:03:35 2017 -0500
@@ -260,8 +260,7 @@
* as the <code>value</code> however it's possible to use any
* <code>Comparable</code> with a <code>compareTo</code>
* method for a <code>Number</code> with the same type as the value.
- * See <a href="#setMinimum(java.lang.Comparable)">
- * <code>setMinimum</code></a> for an example.
+ * See {@link #setMinimum(Comparable)} for an example.
* <p>
* This method fires a <code>ChangeEvent</code> if the
* <code>maximum</code> has changed.
--- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicListUI.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicListUI.java Wed Nov 08 16:03:35 2017 -0500
@@ -588,52 +588,53 @@
* <caption>Describes the preferred size for each layout orientation
* </caption>
* <thead>
- * <tr><th>Layout Orientation</th><th>Preferred Size</th></tr>
+ * <tr>
+ * <th scope="col">Layout Orientation
+ * <th scope="col">Preferred Size
* </thead>
* <tbody>
- * <tr>
- * <td>JList.VERTICAL
- * <td>The preferredSize of the list is total height of the rows
- * and the maximum width of the cells. If JList.fixedCellHeight
- * is specified then the total height of the rows is just
- * (cellVerticalMargins + fixedCellHeight) * model.getSize() where
- * rowVerticalMargins is the space we allocate for drawing
- * the yellow focus outline. Similarly if fixedCellWidth is
- * specified then we just use that.
- * </td>
- * <tr>
- * <td>JList.VERTICAL_WRAP
- * <td>If the visible row count is greater than zero, the preferredHeight
- * is the maximum cell height * visibleRowCount. If the visible row
- * count is <= 0, the preferred height is either the current height
- * of the list, or the maximum cell height, whichever is
- * bigger. The preferred width is than the maximum cell width *
- * number of columns needed. Where the number of columns needs is
- * list.height / max cell height. Max cell height is either the fixed
- * cell height, or is determined by iterating through all the cells
- * to find the maximum height from the ListCellRenderer.
- * <tr>
- * <td>JList.HORIZONTAL_WRAP
- * <td>If the visible row count is greater than zero, the preferredHeight
- * is the maximum cell height * adjustedRowCount. Where
- * visibleRowCount is used to determine the number of columns.
- * Because this lays out horizontally the number of rows is
- * then determined from the column count. For example, lets say
- * you have a model with 10 items and the visible row count is 8.
- * The number of columns needed to display this is 2, but you no
- * longer need 8 rows to display this, you only need 5, thus
- * the adjustedRowCount is 5.
- * <p>If the visible row
- * count is <= 0, the preferred height is dictated by the
- * number of columns, which will be as many as can fit in the width
- * of the <code>JList</code> (width / max cell width), with at
- * least one column. The preferred height then becomes the
- * model size / number of columns * maximum cell height.
- * Max cell height is either the fixed
- * cell height, or is determined by iterating through all the cells
- * to find the maximum height from the ListCellRenderer.
+ * <tr>
+ * <th scope="row">JList.VERTICAL
+ * <td>The preferredSize of the list is total height of the rows
+ * and the maximum width of the cells. If JList.fixedCellHeight
+ * is specified then the total height of the rows is just
+ * (cellVerticalMargins + fixedCellHeight) * model.getSize() where
+ * rowVerticalMargins is the space we allocate for drawing
+ * the yellow focus outline. Similarly if fixedCellWidth is
+ * specified then we just use that.
+ * <tr>
+ * <th scope="row">JList.VERTICAL_WRAP
+ * <td>If the visible row count is greater than zero, the preferredHeight
+ * is the maximum cell height * visibleRowCount. If the visible row
+ * count is <= 0, the preferred height is either the current height
+ * of the list, or the maximum cell height, whichever is
+ * bigger. The preferred width is than the maximum cell width *
+ * number of columns needed. Where the number of columns needs is
+ * list.height / max cell height. Max cell height is either the fixed
+ * cell height, or is determined by iterating through all the cells
+ * to find the maximum height from the ListCellRenderer.
+ * <tr>
+ * <th scope="row">JList.HORIZONTAL_WRAP
+ * <td>If the visible row count is greater than zero, the preferredHeight
+ * is the maximum cell height * adjustedRowCount. Where
+ * visibleRowCount is used to determine the number of columns.
+ * Because this lays out horizontally the number of rows is
+ * then determined from the column count. For example, lets say
+ * you have a model with 10 items and the visible row count is 8.
+ * The number of columns needed to display this is 2, but you no
+ * longer need 8 rows to display this, you only need 5, thus
+ * the adjustedRowCount is 5.
+ * <p>
+ * If the visible row count is <= 0, the preferred height is dictated
+ * by the number of columns, which will be as many as can fit in the
+ * width of the {@code JList} (width / max cell width), with at least
+ * one column. The preferred height then becomes the model size / number
+ * of columns * maximum cell height. Max cell height is either the fixed
+ * cell height, or is determined by iterating through all the cells to
+ * find the maximum height from the ListCellRenderer.
* </tbody>
* </table>
+ *
* The above specifies the raw preferred width and height. The resulting
* preferred width is the above width + insets.left + insets.right and
* the resulting preferred height is the above height + insets.top +
--- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java Wed Nov 08 16:03:35 2017 -0500
@@ -295,87 +295,87 @@
* <caption>Metal's system color mapping</caption>
* <thead>
* <tr>
- * <th>Key
- * <th>Value
+ * <th scope="col">Key
+ * <th scope="col">Value
* </thead>
* <tbody>
- * <tr valign="top" style="text-align:left">
- * <td>"desktop"
+ * <tr>
+ * <th scope="row">"desktop"
* <td>{@code theme.getDesktopColor()}
- * <tr valign="top" style="text-align:left">
- * <td>"activeCaption"
+ * <tr>
+ * <th scope="row">"activeCaption"
* <td>{@code theme.getWindowTitleBackground()}
- * <tr valign="top" style="text-align:left">
- * <td>"activeCaptionText"
+ * <tr>
+ * <th scope="row">"activeCaptionText"
* <td>{@code theme.getWindowTitleForeground()}
- * <tr valign="top" style="text-align:left">
- * <td>"activeCaptionBorder"
+ * <tr>
+ * <th scope="row">"activeCaptionBorder"
* <td>{@code theme.getPrimaryControlShadow()}
- * <tr valign="top" style="text-align:left">
- * <td>"inactiveCaption"
+ * <tr>
+ * <th scope="row">"inactiveCaption"
* <td>{@code theme.getWindowTitleInactiveBackground()}
- * <tr valign="top" style="text-align:left">
- * <td>"inactiveCaptionText"
+ * <tr>
+ * <th scope="row">"inactiveCaptionText"
* <td>{@code theme.getWindowTitleInactiveForeground()}
- * <tr valign="top" style="text-align:left">
- * <td>"inactiveCaptionBorder"
+ * <tr>
+ * <th scope="row">"inactiveCaptionBorder"
* <td>{@code theme.getControlShadow()}
- * <tr valign="top" style="text-align:left">
- * <td>"window"
+ * <tr>
+ * <th scope="row">"window"
* <td>{@code theme.getWindowBackground()}
- * <tr valign="top" style="text-align:left">
- * <td>"windowBorder"
+ * <tr>
+ * <th scope="row">"windowBorder"
* <td>{@code theme.getControl()}
- * <tr valign="top" style="text-align:left">
- * <td>"windowText"
+ * <tr>
+ * <th scope="row">"windowText"
* <td>{@code theme.getUserTextColor()}
- * <tr valign="top" style="text-align:left">
- * <td>"menu"
+ * <tr>
+ * <th scope="row">"menu"
* <td>{@code theme.getMenuBackground()}
- * <tr valign="top" style="text-align:left">
- * <td>"menuText"
+ * <tr>
+ * <th scope="row">"menuText"
* <td>{@code theme.getMenuForeground()}
- * <tr valign="top" style="text-align:left">
- * <td>"text"
+ * <tr>
+ * <th scope="row">"text"
* <td>{@code theme.getWindowBackground()}
- * <tr valign="top" style="text-align:left">
- * <td>"textText"
+ * <tr>
+ * <th scope="row">"textText"
* <td>{@code theme.getUserTextColor()}
- * <tr valign="top" style="text-align:left">
- * <td>"textHighlight"
+ * <tr>
+ * <th scope="row">"textHighlight"
* <td>{@code theme.getTextHighlightColor()}
- * <tr valign="top" style="text-align:left">
- * <td>"textHighlightText"
+ * <tr>
+ * <th scope="row">"textHighlightText"
* <td>{@code theme.getHighlightedTextColor()}
- * <tr valign="top" style="text-align:left">
- * <td>"textInactiveText"
+ * <tr>
+ * <th scope="row">"textInactiveText"
* <td>{@code theme.getInactiveSystemTextColor()}
- * <tr valign="top" style="text-align:left">
- * <td>"control"
+ * <tr>
+ * <th scope="row">"control"
* <td>{@code theme.getControl()}
- * <tr valign="top" style="text-align:left">
- * <td>"controlText"
+ * <tr>
+ * <th scope="row">"controlText"
* <td>{@code theme.getControlTextColor()}
- * <tr valign="top" style="text-align:left">
- * <td>"controlHighlight"
+ * <tr>
+ * <th scope="row">"controlHighlight"
* <td>{@code theme.getControlHighlight()}
- * <tr valign="top" style="text-align:left">
- * <td>"controlLtHighlight"
+ * <tr>
+ * <th scope="row">"controlLtHighlight"
* <td>{@code theme.getControlHighlight()}
- * <tr valign="top" style="text-align:left">
- * <td>"controlShadow"
+ * <tr>
+ * <th scope="row">"controlShadow"
* <td>{@code theme.getControlShadow()}
- * <tr valign="top" style="text-align:left">
- * <td>"controlDkShadow"
+ * <tr>
+ * <th scope="row">"controlDkShadow"
* <td>{@code theme.getControlDarkShadow()}
- * <tr valign="top" style="text-align:left">
- * <td>"scrollbar"
+ * <tr>
+ * <th scope="row">"scrollbar"
* <td>{@code theme.getControl()}
- * <tr valign="top" style="text-align:left">
- * <td>"info"
+ * <tr>
+ * <th scope="row">"info"
* <td>{@code theme.getPrimaryControl()}
- * <tr valign="top" style="text-align:left">
- * <td>"infoText"
+ * <tr>
+ * <th scope="row">"infoText"
* <td>{@code theme.getPrimaryControlInfo()}
* </tbody>
* </table>
--- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalTreeUI.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalTreeUI.java Wed Nov 08 16:03:35 2017 -0500
@@ -47,24 +47,25 @@
* <table class="striped">
* <caption>Descriptions of supported hints: Angled, Horizontal, and None
* </caption>
- * <tr>
- * <th>Angled</th>
- * <td>A line is drawn connecting the child to the parent. For handling
- * of the root node refer to
- * {@link javax.swing.JTree#setRootVisible} and
- * {@link javax.swing.JTree#setShowsRootHandles}.
- * </td>
- * </tr>
- * <tr>
- * <th>Horizontal</th>
- * <td>A horizontal line is drawn dividing the children of the root node.</td>
- * </tr>
- * <tr>
- * <th>None</th>
- * <td>Do not draw any visual indication between nodes.</td>
- * </tr>
+ * <thead>
+ * <tr>
+ * <th scope="col">Hint
+ * <th scope="col">Description
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <th scope="row">Angled
+ * <td>A line is drawn connecting the child to the parent. For handling of
+ * the root node refer to {@link JTree#setRootVisible} and
+ * {@link JTree#setShowsRootHandles}.
+ * <tr>
+ * <th scope="row">Horizontal
+ * <td>A horizontal line is drawn dividing the children of the root node.
+ * <tr>
+ * <th scope="row">None
+ * <td>Do not draw any visual indication between nodes.
+ * </tbody>
* </table>
- *
* <p>
* As it is typically impractical to obtain the <code>TreeUI</code> from
* the <code>JTree</code> and cast to an instance of <code>MetalTreeUI</code>
--- a/src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -352,6 +352,7 @@
setVisible(true);
}
setSelectionVisible(true);
+ updateSystemSelection();
}
}
@@ -365,7 +366,9 @@
*/
public void focusLost(FocusEvent e) {
setVisible(false);
- setSelectionVisible(ownsSelection || e.isTemporary());
+ setSelectionVisible((e.getCause() == FocusEvent.Cause.ACTIVATION ||
+ e.getOppositeComponent() instanceof JRootPane) &&
+ (ownsSelection || e.isTemporary()));
}
@@ -866,7 +869,6 @@
Highlighter.HighlightPainter p = getSelectionPainter();
try {
selectionTag = h.addHighlight(p0, p1, p);
- updateOwnsSelection();
} catch (BadLocationException bl) {
selectionTag = null;
}
@@ -877,7 +879,6 @@
Highlighter h = component.getHighlighter();
h.removeHighlight(selectionTag);
selectionTag = null;
- updateOwnsSelection();
}
}
}
@@ -1119,7 +1120,6 @@
if (selectionTag != null) {
h.removeHighlight(selectionTag);
selectionTag = null;
- updateOwnsSelection();
}
// otherwise, change or add the highlight
} else {
@@ -1130,7 +1130,6 @@
Highlighter.HighlightPainter p = getSelectionPainter();
selectionTag = h.addHighlight(p0, p1, p);
}
- updateOwnsSelection();
} catch (BadLocationException e) {
throw new StateInvariantError("Bad caret position");
}
@@ -1181,7 +1180,6 @@
if (this.dot != dot || this.dotBias != dotBias ||
selectionTag != null || forceCaretPositionChange) {
changeCaretPosition(dot, dotBias);
- updateOwnsSelection();
}
this.markBias = this.dotBias;
this.markLTR = dotLTR;
@@ -1189,7 +1187,6 @@
if ((h != null) && (selectionTag != null)) {
h.removeHighlight(selectionTag);
selectionTag = null;
- updateOwnsSelection();
}
}
@@ -1940,13 +1937,6 @@
}
}
- /**
- * Updates ownsSelection based on text selection in the caret.
- */
- private void updateOwnsSelection() {
- ownsSelection = (selectionTag != null)
- && SwingUtilities2.canAccessSystemClipboard();
- }
private class DefaultFilterBypass extends NavigationFilter.FilterBypass {
public Caret getCaret() {
--- a/src/java.desktop/share/classes/javax/swing/text/Document.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/text/Document.java Wed Nov 08 16:03:35 2017 -0500
@@ -146,10 +146,10 @@
* <p>
* The methods related to observing mutations to the document are:
* <ul>
- * <li><a href="#addDocumentListener(javax.swing.event.DocumentListener)">addDocumentListener(DocumentListener)</a>
- * <li><a href="#removeDocumentListener(javax.swing.event.DocumentListener)">removeDocumentListener(DocumentListener)</a>
- * <li><a href="#addUndoableEditListener(javax.swing.event.UndoableEditListener)">addUndoableEditListener(UndoableEditListener)</a>
- * <li><a href="#removeUndoableEditListener(javax.swing.event.UndoableEditListener)">removeUndoableEditListener(UndoableEditListener)</a>
+ * <li>{@link #addDocumentListener(DocumentListener)}
+ * <li>{@link #removeDocumentListener(DocumentListener)}
+ * <li>{@link #addUndoableEditListener(UndoableEditListener)}
+ * <li>{@link #removeUndoableEditListener(UndoableEditListener)}
* </ul>
*
* <p><b>Properties</b>
--- a/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java Wed Nov 08 16:03:35 2017 -0500
@@ -160,34 +160,39 @@
* <table class="striped">
* <caption>Stages of keyboard and input method event handling</caption>
* <thead>
- * <tr>
- * <th id="stage">Stage</th>
- * <th id="ke">KeyEvent</th>
- * <th id="ime">InputMethodEvent</th></tr>
+ * <tr>
+ * <th scope="col">Stage
+ * <th scope="col">KeyEvent
+ * <th scope="col">InputMethodEvent
* </thead>
* <tbody>
- * <tr><td headers="stage">1. </td>
- * <td headers="ke">input methods </td>
- * <td headers="ime">(generated here)</td></tr>
- * <tr><td headers="stage">2. </td>
- * <td headers="ke">focus manager </td>
- * <td headers="ime"></td>
- * </tr>
- * <tr>
- * <td headers="stage">3. </td>
- * <td headers="ke">registered key listeners</td>
- * <td headers="ime">registered input method listeners</tr>
- * <tr>
- * <td headers="stage">4. </td>
- * <td headers="ke"></td>
- * <td headers="ime">input method handling in JTextComponent</tr>
- * <tr>
- * <td headers="stage">5. </td><td headers="ke ime" colspan=2>keymap handling using the current keymap</td></tr>
- * <tr><td headers="stage">6. </td><td headers="ke">keyboard handling in JComponent (e.g. accelerators, component navigation, etc.)</td>
- * <td headers="ime"></td></tr>
+ * <tr>
+ * <th scope="row">1.
+ * <td>input methods
+ * <td>(generated here)
+ * <tr>
+ * <th scope="row" headers="stage">2.
+ * <td>focus manager
+ * <td>
+ * </tr>
+ * <tr>
+ * <th scope="row">3.
+ * <td>registered key listeners
+ * <td>registered input method listeners
+ * <tr>
+ * <th scope="row">4.
+ * <td>
+ * <td>input method handling in JTextComponent
+ * <tr>
+ * <th scope="row">5.
+ * <td colspan=2>keymap handling using the current keymap
+ * <tr>
+ * <th scope="row">6.
+ * <td>keyboard handling in JComponent (e.g. accelerators, component
+ * navigation, etc.)
+ * <td>
* </tbody>
* </table>
- *
* <p>
* To maintain compatibility with applications that listen to key
* events but are not aware of input method events, the input
--- a/src/java.desktop/share/classes/javax/swing/text/MaskFormatter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/text/MaskFormatter.java Wed Nov 08 16:03:35 2017 -0500
@@ -40,36 +40,39 @@
* <table class="striped">
* <caption>Valid characters and their descriptions</caption>
* <thead>
- * <tr>
- * <th>Character </th>
- * <th>Description</th>
- * </tr>
+ * <tr>
+ * <th scope="col">Character
+ * <th scope="col">Description
* </thead>
* <tbody>
- * <tr>
- * <td>#</td>
- * <td>Any valid number, uses <code>Character.isDigit</code>.</td>
- * </tr>
- * <tr>
- * <td>'</td>
- * <td>Escape character, used to escape any of the
- * special formatting characters.</td>
- * </tr>
- * <tr>
- * <td>U</td><td>Any character (<code>Character.isLetter</code>). All
- * lowercase letters are mapped to upper case.</td>
- * </tr>
- * <tr><td>L</td><td>Any character (<code>Character.isLetter</code>). All
- * upper case letters are mapped to lower case.</td>
- * </tr>
- * <tr><td>A</td><td>Any character or number (<code>Character.isLetter</code>
- * or <code>Character.isDigit</code>)</td>
- * </tr>
- * <tr><td>?</td><td>Any character
- * (<code>Character.isLetter</code>).</td>
- * </tr>
- * <tr><td>*</td><td>Anything.</td></tr>
- * <tr><td>H</td><td>Any hex character (0-9, a-f or A-F).</td></tr>
+ * <tr>
+ * <th scope="row">#
+ * <td>Any valid number, uses {@code Character.isDigit}.
+ * <tr>
+ * <th scope="row">'
+ * <td>Escape character, used to escape any of the special formatting
+ * characters.
+ * <tr>
+ * <th scope="row">U
+ * <td>Any character ({@code Character.isLetter}). All lowercase letters are
+ * mapped to upper case.
+ * <tr>
+ * <th scope="row">L
+ * <td>Any character ({@code Character.isLetter}). All upper case letters
+ * are mapped to lower case.
+ * <tr>
+ * <th scope="row">A
+ * <td>Any character or number ({@code Character.isLetter} or
+ * {@code Character.isDigit}).
+ * <tr>
+ * <th scope="row">?
+ * <td>Any character ({@code Character.isLetter}).
+ * <tr>
+ * <th scope="row">*
+ * <td>Anything.
+ * <tr>
+ * <th scope="row">H
+ * <td>Any hex character (0-9, a-f or A-F).
* </tbody>
* </table>
*
--- a/src/java.desktop/share/classes/javax/swing/text/html/FormView.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/text/html/FormView.java Wed Nov 08 16:03:35 2017 -0500
@@ -50,60 +50,47 @@
* <table class="striped">
* <caption>Shows what components get built by this view</caption>
* <thead>
- * <tr>
- * <th>Element Type</th>
- * <th>Component built</th>
- * </tr>
+ * <tr>
+ * <th scope="col">Element Type
+ * <th scope="col">Component built
* </thead>
* <tbody>
- * <tr>
- * <td>input, type button</td>
- * <td>JButton</td>
- * </tr>
- * <tr>
- * <td>input, type checkbox</td>
- * <td>JCheckBox</td>
- * </tr>
- * <tr>
- * <td>input, type image</td>
- * <td>JButton</td>
- * </tr>
- * <tr>
- * <td>input, type password</td>
- * <td>JPasswordField</td>
- * </tr>
- * <tr>
- * <td>input, type radio</td>
- * <td>JRadioButton</td>
- * </tr>
- * <tr>
- * <td>input, type reset</td>
- * <td>JButton</td>
- * </tr>
- * <tr>
- * <td>input, type submit</td>
- * <td>JButton</td>
- * </tr>
- * <tr>
- * <td>input, type text</td>
- * <td>JTextField</td>
- * </tr>
- * <tr>
- * <td>select, size > 1 or multiple attribute defined</td>
- * <td>JList in a JScrollPane</td>
- * </tr>
- * <tr>
- * <td>select, size unspecified or 1</td>
- * <td>JComboBox</td>
- * </tr>
- * <tr>
- * <td>textarea</td>
- * <td>JTextArea in a JScrollPane</td>
- * </tr>
- * <tr>
- * <td>input, type file</td>
- * <td>JTextField</td>
- * </tr>
+ * <tr>
+ * <th scope="row">input, type button
+ * <td>JButton
+ * <tr>
+ * <th scope="row">input, type checkbox
+ * <td>JCheckBox
+ * <tr>
+ * <th scope="row">input, type image
+ * <td>JButton
+ * <tr>
+ * <th scope="row">input, type password
+ * <td>JPasswordField
+ * <tr>
+ * <th scope="row">input, type radio
+ * <td>JRadioButton
+ * <tr>
+ * <th scope="row">input, type reset
+ * <td>JButton
+ * <tr>
+ * <th scope="row">input, type submit
+ * <td>JButton
+ * <tr>
+ * <th scope="row">input, type text
+ * <td>JTextField
+ * <tr>
+ * <th scope="row">select, size > 1 or multiple attribute defined
+ * <td>JList in a JScrollPane
+ * <tr>
+ * <th scope="row">select, size unspecified or 1
+ * <td>JComboBox
+ * <tr>
+ * <th scope="row">textarea
+ * <td>JTextArea in a JScrollPane
+ * <tr>
+ * <th scope="row">input, type file
+ * <td>JTextField
* </tbody>
* </table>
*
--- a/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java Wed Nov 08 16:03:35 2017 -0500
@@ -2134,81 +2134,227 @@
* <table class="striped">
* <caption>HTML tags and assigned actions</caption>
* <thead>
- * <tr><th>Tag</th><th>Action</th></tr>
+ * <tr>
+ * <th scope="col">Tag
+ * <th scope="col">Action
* </thead>
* <tbody>
- * <tr><td><code>HTML.Tag.A</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.ADDRESS</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.APPLET</code> <td>HiddenAction
- * <tr><td><code>HTML.Tag.AREA</code> <td>AreaAction
- * <tr><td><code>HTML.Tag.B</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.BASE</code> <td>BaseAction
- * <tr><td><code>HTML.Tag.BASEFONT</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.BIG</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.BLOCKQUOTE</code><td>BlockAction
- * <tr><td><code>HTML.Tag.BODY</code> <td>BlockAction
- * <tr><td><code>HTML.Tag.BR</code> <td>SpecialAction
- * <tr><td><code>HTML.Tag.CAPTION</code> <td>BlockAction
- * <tr><td><code>HTML.Tag.CENTER</code> <td>BlockAction
- * <tr><td><code>HTML.Tag.CITE</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.CODE</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.DD</code> <td>BlockAction
- * <tr><td><code>HTML.Tag.DFN</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.DIR</code> <td>BlockAction
- * <tr><td><code>HTML.Tag.DIV</code> <td>BlockAction
- * <tr><td><code>HTML.Tag.DL</code> <td>BlockAction
- * <tr><td><code>HTML.Tag.DT</code> <td>ParagraphAction
- * <tr><td><code>HTML.Tag.EM</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.FONT</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.FORM</code> <td>As of 1.4 a BlockAction
- * <tr><td><code>HTML.Tag.FRAME</code> <td>SpecialAction
- * <tr><td><code>HTML.Tag.FRAMESET</code> <td>BlockAction
- * <tr><td><code>HTML.Tag.H1</code> <td>ParagraphAction
- * <tr><td><code>HTML.Tag.H2</code> <td>ParagraphAction
- * <tr><td><code>HTML.Tag.H3</code> <td>ParagraphAction
- * <tr><td><code>HTML.Tag.H4</code> <td>ParagraphAction
- * <tr><td><code>HTML.Tag.H5</code> <td>ParagraphAction
- * <tr><td><code>HTML.Tag.H6</code> <td>ParagraphAction
- * <tr><td><code>HTML.Tag.HEAD</code> <td>HeadAction
- * <tr><td><code>HTML.Tag.HR</code> <td>SpecialAction
- * <tr><td><code>HTML.Tag.HTML</code> <td>BlockAction
- * <tr><td><code>HTML.Tag.I</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.IMG</code> <td>SpecialAction
- * <tr><td><code>HTML.Tag.INPUT</code> <td>FormAction
- * <tr><td><code>HTML.Tag.ISINDEX</code> <td>IsndexAction
- * <tr><td><code>HTML.Tag.KBD</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.LI</code> <td>BlockAction
- * <tr><td><code>HTML.Tag.LINK</code> <td>LinkAction
- * <tr><td><code>HTML.Tag.MAP</code> <td>MapAction
- * <tr><td><code>HTML.Tag.MENU</code> <td>BlockAction
- * <tr><td><code>HTML.Tag.META</code> <td>MetaAction
- * <tr><td><code>HTML.Tag.NOFRAMES</code> <td>BlockAction
- * <tr><td><code>HTML.Tag.OBJECT</code> <td>SpecialAction
- * <tr><td><code>HTML.Tag.OL</code> <td>BlockAction
- * <tr><td><code>HTML.Tag.OPTION</code> <td>FormAction
- * <tr><td><code>HTML.Tag.P</code> <td>ParagraphAction
- * <tr><td><code>HTML.Tag.PARAM</code> <td>HiddenAction
- * <tr><td><code>HTML.Tag.PRE</code> <td>PreAction
- * <tr><td><code>HTML.Tag.SAMP</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.SCRIPT</code> <td>HiddenAction
- * <tr><td><code>HTML.Tag.SELECT</code> <td>FormAction
- * <tr><td><code>HTML.Tag.SMALL</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.STRIKE</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.S</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.STRONG</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.STYLE</code> <td>StyleAction
- * <tr><td><code>HTML.Tag.SUB</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.SUP</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.TABLE</code> <td>BlockAction
- * <tr><td><code>HTML.Tag.TD</code> <td>BlockAction
- * <tr><td><code>HTML.Tag.TEXTAREA</code> <td>FormAction
- * <tr><td><code>HTML.Tag.TH</code> <td>BlockAction
- * <tr><td><code>HTML.Tag.TITLE</code> <td>TitleAction
- * <tr><td><code>HTML.Tag.TR</code> <td>BlockAction
- * <tr><td><code>HTML.Tag.TT</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.U</code> <td>CharacterAction
- * <tr><td><code>HTML.Tag.UL</code> <td>BlockAction
- * <tr><td><code>HTML.Tag.VAR</code> <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.A}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.ADDRESS}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.APPLET}
+ * <td>HiddenAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.AREA}
+ * <td>AreaAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.B}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.BASE}
+ * <td>BaseAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.BASEFONT}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.BIG}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.BLOCKQUOTE}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.BODY}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.BR}
+ * <td>SpecialAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.CAPTION}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.CENTER}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.CITE}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.CODE}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.DD}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.DFN}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.DIR}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.DIV}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.DL}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.DT}
+ * <td>ParagraphAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.EM}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.FONT}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.FORM}
+ * <td>As of 1.4 a BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.FRAME}
+ * <td>SpecialAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.FRAMESET}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.H1}
+ * <td>ParagraphAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.H2}
+ * <td>ParagraphAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.H3}
+ * <td>ParagraphAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.H4}
+ * <td>ParagraphAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.H5}
+ * <td>ParagraphAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.H6}
+ * <td>ParagraphAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.HEAD}
+ * <td>HeadAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.HR}
+ * <td>SpecialAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.HTML}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.I}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.IMG}
+ * <td>SpecialAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.INPUT}
+ * <td>FormAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.ISINDEX}
+ * <td>IsndexAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.KBD}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.LI}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.LINK}
+ * <td>LinkAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.MAP}
+ * <td>MapAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.MENU}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.META}
+ * <td>MetaAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.NOFRAMES}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.OBJECT}
+ * <td>SpecialAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.OL}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.OPTION}
+ * <td>FormAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.P}
+ * <td>ParagraphAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.PARAM}
+ * <td>HiddenAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.PRE}
+ * <td>PreAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.SAMP}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.SCRIPT}
+ * <td>HiddenAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.SELECT}
+ * <td>FormAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.SMALL}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.STRIKE}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.S}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.STRONG}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.STYLE}
+ * <td>StyleAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.SUB}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.SUP}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.TABLE}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.TD}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.TEXTAREA}
+ * <td>FormAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.TH}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.TITLE}
+ * <td>TitleAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.TR}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.TT}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.U}
+ * <td>CharacterAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.UL}
+ * <td>BlockAction
+ * <tr>
+ * <th scope="row">{@code HTML.Tag.VAR}
+ * <td>CharacterAction
* </tbody>
* </table>
* <p>
@@ -3397,45 +3543,44 @@
* <caption>Model assignments for the various types of form elements
* </caption>
* <thead>
- * <tr>
- * <th>Element Type
- * <th>Model Type
- * </tr>
+ * <tr>
+ * <th scope="col">Element Type
+ * <th scope="col">Model Type
* </thead>
* <tbody>
- * <tr>
- * <td>input, type button
- * <td>{@link DefaultButtonModel}
- * <tr>
- * <td>input, type checkbox
- * <td>{@link javax.swing.JToggleButton.ToggleButtonModel}
- * <tr>
- * <td>input, type image
- * <td>{@link DefaultButtonModel}
- * <tr>
- * <td>input, type password
- * <td>{@link PlainDocument}
- * <tr>
- * <td>input, type radio
- * <td>{@link javax.swing.JToggleButton.ToggleButtonModel}
- * <tr>
- * <td>input, type reset
- * <td>{@link DefaultButtonModel}
- * <tr>
- * <td>input, type submit
- * <td>{@link DefaultButtonModel}
- * <tr>
- * <td>input, type text or type is null.
- * <td>{@link PlainDocument}
- * <tr>
- * <td>select
- * <td>{@link DefaultComboBoxModel} or an {@link DefaultListModel}, with an item type of Option
- * <tr>
- * <td>textarea
- * <td>{@link PlainDocument}
+ * <tr>
+ * <th scope="row">input, type button
+ * <td>{@link DefaultButtonModel}
+ * <tr>
+ * <th scope="row">input, type checkbox
+ * <td>{@link JToggleButton.ToggleButtonModel}
+ * <tr>
+ * <th scope="row">input, type image
+ * <td>{@link DefaultButtonModel}
+ * <tr>
+ * <th scope="row">input, type password
+ * <td>{@link PlainDocument}
+ * <tr>
+ * <th scope="row">input, type radio
+ * <td>{@link JToggleButton.ToggleButtonModel}
+ * <tr>
+ * <th scope="row">input, type reset
+ * <td>{@link DefaultButtonModel}
+ * <tr>
+ * <th scope="row">input, type submit
+ * <td>{@link DefaultButtonModel}
+ * <tr>
+ * <th scope="row">input, type text or type is null.
+ * <td>{@link PlainDocument}
+ * <tr>
+ * <th scope="row">select
+ * <td>{@link DefaultComboBoxModel} or an {@link DefaultListModel},
+ * with an item type of Option
+ * <tr>
+ * <td>textarea
+ * <td>{@link PlainDocument}
* </tbody>
* </table>
- *
*/
public class FormAction extends SpecialAction {
--- a/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java Wed Nov 08 16:03:35 2017 -0500
@@ -1122,83 +1122,116 @@
* <caption>Describes the tag and view created by this factory by default
* </caption>
* <thead>
- * <tr>
- * <th>Tag
- * <th>View created
- * </tr>
+ * <tr>
+ * <th scope="col">Tag
+ * <th scope="col">View created
* </thead>
* <tbody>
- * <tr>
- * <td>HTML.Tag.CONTENT<td>InlineView
- * </tr><tr>
- * <td>HTML.Tag.IMPLIED<td>javax.swing.text.html.ParagraphView
- * </tr><tr>
- * <td>HTML.Tag.P<td>javax.swing.text.html.ParagraphView
- * </tr><tr>
- * <td>HTML.Tag.H1<td>javax.swing.text.html.ParagraphView
- * </tr><tr>
- * <td>HTML.Tag.H2<td>javax.swing.text.html.ParagraphView
- * </tr><tr>
- * <td>HTML.Tag.H3<td>javax.swing.text.html.ParagraphView
- * </tr><tr>
- * <td>HTML.Tag.H4<td>javax.swing.text.html.ParagraphView
- * </tr><tr>
- * <td>HTML.Tag.H5<td>javax.swing.text.html.ParagraphView
- * </tr><tr>
- * <td>HTML.Tag.H6<td>javax.swing.text.html.ParagraphView
- * </tr><tr>
- * <td>HTML.Tag.DT<td>javax.swing.text.html.ParagraphView
- * </tr><tr>
- * <td>HTML.Tag.MENU<td>ListView
- * </tr><tr>
- * <td>HTML.Tag.DIR<td>ListView
- * </tr><tr>
- * <td>HTML.Tag.UL<td>ListView
- * </tr><tr>
- * <td>HTML.Tag.OL<td>ListView
- * </tr><tr>
- * <td>HTML.Tag.LI<td>BlockView
- * </tr><tr>
- * <td>HTML.Tag.DL<td>BlockView
- * </tr><tr>
- * <td>HTML.Tag.DD<td>BlockView
- * </tr><tr>
- * <td>HTML.Tag.BODY<td>BlockView
- * </tr><tr>
- * <td>HTML.Tag.HTML<td>BlockView
- * </tr><tr>
- * <td>HTML.Tag.CENTER<td>BlockView
- * </tr><tr>
- * <td>HTML.Tag.DIV<td>BlockView
- * </tr><tr>
- * <td>HTML.Tag.BLOCKQUOTE<td>BlockView
- * </tr><tr>
- * <td>HTML.Tag.PRE<td>BlockView
- * </tr><tr>
- * <td>HTML.Tag.BLOCKQUOTE<td>BlockView
- * </tr><tr>
- * <td>HTML.Tag.PRE<td>BlockView
- * </tr><tr>
- * <td>HTML.Tag.IMG<td>ImageView
- * </tr><tr>
- * <td>HTML.Tag.HR<td>HRuleView
- * </tr><tr>
- * <td>HTML.Tag.BR<td>BRView
- * </tr><tr>
- * <td>HTML.Tag.TABLE<td>javax.swing.text.html.TableView
- * </tr><tr>
- * <td>HTML.Tag.INPUT<td>FormView
- * </tr><tr>
- * <td>HTML.Tag.SELECT<td>FormView
- * </tr><tr>
- * <td>HTML.Tag.TEXTAREA<td>FormView
- * </tr><tr>
- * <td>HTML.Tag.OBJECT<td>ObjectView
- * </tr><tr>
- * <td>HTML.Tag.FRAMESET<td>FrameSetView
- * </tr><tr>
- * <td>HTML.Tag.FRAME<td>FrameView
- * </tr>
+ * <tr>
+ * <th scope="row">HTML.Tag.CONTENT
+ * <td>InlineView
+ * <tr>
+ * <th scope="row">HTML.Tag.IMPLIED
+ * <td>javax.swing.text.html.ParagraphView
+ * <tr>
+ * <th scope="row">HTML.Tag.P
+ * <td>javax.swing.text.html.ParagraphView
+ * <tr>
+ * <th scope="row">HTML.Tag.H1
+ * <td>javax.swing.text.html.ParagraphView
+ * <tr>
+ * <th scope="row">HTML.Tag.H2
+ * <td>javax.swing.text.html.ParagraphView
+ * <tr>
+ * <th scope="row">HTML.Tag.H3
+ * <td>javax.swing.text.html.ParagraphView
+ * <tr>
+ * <th scope="row">HTML.Tag.H4
+ * <td>javax.swing.text.html.ParagraphView
+ * <tr>
+ * <th scope="row">HTML.Tag.H5
+ * <td>javax.swing.text.html.ParagraphView
+ * <tr>
+ * <th scope="row">HTML.Tag.H6
+ * <td>javax.swing.text.html.ParagraphView
+ * <tr>
+ * <th scope="row">HTML.Tag.DT
+ * <td>javax.swing.text.html.ParagraphView
+ * <tr>
+ * <th scope="row">HTML.Tag.MENU
+ * <td>ListView
+ * <tr>
+ * <th scope="row">HTML.Tag.DIR
+ * <td>ListView
+ * <tr>
+ * <th scope="row">HTML.Tag.UL
+ * <td>ListView
+ * <tr>
+ * <th scope="row">HTML.Tag.OL
+ * <td>ListView
+ * <tr>
+ * <th scope="row">HTML.Tag.LI
+ * <td>BlockView
+ * <tr>
+ * <th scope="row">HTML.Tag.DL
+ * <td>BlockView
+ * <tr>
+ * <th scope="row">HTML.Tag.DD
+ * <td>BlockView
+ * <tr>
+ * <th scope="row">HTML.Tag.BODY
+ * <td>BlockView
+ * <tr>
+ * <th scope="row">HTML.Tag.HTML
+ * <td>BlockView
+ * <tr>
+ * <th scope="row">HTML.Tag.CENTER
+ * <td>BlockView
+ * <tr>
+ * <th scope="row">HTML.Tag.DIV
+ * <td>BlockView
+ * <tr>
+ * <th scope="row">HTML.Tag.BLOCKQUOTE
+ * <td>BlockView
+ * <tr>
+ * <th scope="row">HTML.Tag.PRE
+ * <td>BlockView
+ * <tr>
+ * <th scope="row">HTML.Tag.BLOCKQUOTE
+ * <td>BlockView
+ * <tr>
+ * <th scope="row">HTML.Tag.PRE
+ * <td>BlockView
+ * <tr>
+ * <th scope="row">HTML.Tag.IMG
+ * <td>ImageView
+ * <tr>
+ * <th scope="row">HTML.Tag.HR
+ * <td>HRuleView
+ * <tr>
+ * <th scope="row">HTML.Tag.BR
+ * <td>BRView
+ * <tr>
+ * <th scope="row">HTML.Tag.TABLE
+ * <td>javax.swing.text.html.TableView
+ * <tr>
+ * <th scope="row">HTML.Tag.INPUT
+ * <td>FormView
+ * <tr>
+ * <th scope="row">HTML.Tag.SELECT
+ * <td>FormView
+ * <tr>
+ * <th scope="row">HTML.Tag.TEXTAREA
+ * <td>FormView
+ * <tr>
+ * <th scope="row">HTML.Tag.OBJECT
+ * <td>ObjectView
+ * <tr>
+ * <th scope="row">HTML.Tag.FRAMESET
+ * <td>FrameSetView
+ * <tr>
+ * <th scope="row">HTML.Tag.FRAME
+ * <td>FrameView
* </tbody>
* </table>
*/
--- a/src/java.desktop/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java Wed Nov 08 16:03:35 2017 -0500
@@ -65,19 +65,35 @@
* <caption>Properties</caption>
* <thead>
* <tr>
- * <th>Property:
- * <th>Key:
+ * <th scope="col">Property
+ * <th scope="col">Key
* </tr>
* </thead>
* <tbody>
- * <tr><td>"leafIcon"<td>"Tree.leafIcon"
- * <tr><td>"closedIcon"<td>"Tree.closedIcon"
- * <tr><td>"openIcon"<td>"Tree.openIcon"
- * <tr><td>"textSelectionColor"<td>"Tree.selectionForeground"
- * <tr><td>"textNonSelectionColor"<td>"Tree.textForeground"
- * <tr><td>"backgroundSelectionColor"<td>"Tree.selectionBackground"
- * <tr><td>"backgroundNonSelectionColor"<td>"Tree.textBackground"
- * <tr><td>"borderSelectionColor"<td>"Tree.selectionBorderColor"
+ * <tr>
+ * <th scope="row">"leafIcon"
+ * <td>"Tree.leafIcon"
+ * <tr>
+ * <th scope="row">"closedIcon"
+ * <td>"Tree.closedIcon"
+ * <tr>
+ * <th scope="row">"openIcon"
+ * <td>"Tree.openIcon"
+ * <tr>
+ * <th scope="row">"textSelectionColor"
+ * <td>"Tree.selectionForeground"
+ * <tr>
+ * <th scope="row">"textNonSelectionColor"
+ * <td>"Tree.textForeground"
+ * <tr>
+ * <th scope="row">"backgroundSelectionColor"
+ * <td>"Tree.selectionBackground"
+ * <tr>
+ * <th scope="row">"backgroundNonSelectionColor"
+ * <td>"Tree.textBackground"
+ * <tr>
+ * <th scope="row">"borderSelectionColor"
+ * <td>"Tree.selectionBorderColor"
* </tbody>
* </table>
* <p>
--- a/src/java.desktop/share/classes/sun/awt/AWTAccessor.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/sun/awt/AWTAccessor.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -291,26 +291,6 @@
*/
public interface WindowAccessor {
/*
- * Get opacity level of the given window.
- */
- float getOpacity(Window window);
- /*
- * Set opacity level to the given window.
- */
- void setOpacity(Window window, float opacity);
- /*
- * Get a shape assigned to the given window.
- */
- Shape getShape(Window window);
- /*
- * Set a shape to the given window.
- */
- void setShape(Window window, Shape shape);
- /*
- * Set the opaque preoperty to the given window.
- */
- void setOpaque(Window window, boolean isOpaque);
- /*
* Update the image of a non-opaque (translucent) window.
*/
void updateWindow(Window window);
--- a/src/java.desktop/unix/classes/sun/awt/X11/XDragSourceContextPeer.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XDragSourceContextPeer.java Wed Nov 08 16:03:35 2017 -0500
@@ -38,6 +38,7 @@
import java.util.*;
+import sun.java2d.pipe.Region;
import sun.util.logging.PlatformLogger;
import sun.awt.dnd.SunDragSourceContextPeer;
@@ -811,10 +812,10 @@
}
public int scaleUp(int x) {
- return x * windowScale;
+ return Region.clipRound(x * (double)windowScale);
}
public int scaleDown(int x) {
- return x / windowScale;
+ return Region.clipRound(x / (double)windowScale);
}
}
--- a/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -22,41 +22,135 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package sun.awt.X11;
-import java.awt.peer.TaskbarPeer;
-import java.awt.*;
-import java.awt.event.InputEvent;
-import java.awt.event.MouseEvent;
-import java.awt.event.KeyEvent;
+import java.awt.AWTError;
+import java.awt.AWTException;
+import java.awt.Button;
+import java.awt.Canvas;
+import java.awt.Checkbox;
+import java.awt.CheckboxMenuItem;
+import java.awt.Choice;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.Desktop;
+import java.awt.Dialog;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.FileDialog;
+import java.awt.Frame;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
+import java.awt.Image;
+import java.awt.Insets;
+import java.awt.JobAttributes;
+import java.awt.Label;
+import java.awt.Menu;
+import java.awt.MenuBar;
+import java.awt.MenuItem;
+import java.awt.PageAttributes;
+import java.awt.Panel;
+import java.awt.Point;
+import java.awt.PopupMenu;
+import java.awt.PrintJob;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.ScrollPane;
+import java.awt.Scrollbar;
+import java.awt.SystemColor;
+import java.awt.SystemTray;
+import java.awt.Taskbar;
+import java.awt.TextArea;
+import java.awt.TextField;
+import java.awt.Toolkit;
+import java.awt.TrayIcon;
+import java.awt.Window;
import java.awt.datatransfer.Clipboard;
+import java.awt.dnd.DragGestureEvent;
+import java.awt.dnd.DragGestureListener;
+import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSource;
-import java.awt.dnd.DragGestureListener;
-import java.awt.dnd.DragGestureEvent;
-import java.awt.dnd.DragGestureRecognizer;
+import java.awt.dnd.InvalidDnDOperationException;
import java.awt.dnd.MouseDragGestureRecognizer;
-import java.awt.dnd.InvalidDnDOperationException;
import java.awt.dnd.peer.DragSourceContextPeer;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
import java.awt.font.TextAttribute;
import java.awt.im.InputMethodHighlight;
import java.awt.im.spi.InputMethodDescriptor;
-import java.awt.peer.*;
+import java.awt.peer.ButtonPeer;
+import java.awt.peer.CanvasPeer;
+import java.awt.peer.CheckboxMenuItemPeer;
+import java.awt.peer.CheckboxPeer;
+import java.awt.peer.ChoicePeer;
+import java.awt.peer.DesktopPeer;
+import java.awt.peer.DialogPeer;
+import java.awt.peer.FileDialogPeer;
+import java.awt.peer.FontPeer;
+import java.awt.peer.FramePeer;
+import java.awt.peer.KeyboardFocusManagerPeer;
+import java.awt.peer.LabelPeer;
+import java.awt.peer.ListPeer;
+import java.awt.peer.MenuBarPeer;
+import java.awt.peer.MenuItemPeer;
+import java.awt.peer.MenuPeer;
+import java.awt.peer.MouseInfoPeer;
+import java.awt.peer.PanelPeer;
+import java.awt.peer.PopupMenuPeer;
+import java.awt.peer.RobotPeer;
+import java.awt.peer.ScrollPanePeer;
+import java.awt.peer.ScrollbarPeer;
+import java.awt.peer.SystemTrayPeer;
+import java.awt.peer.TaskbarPeer;
+import java.awt.peer.TextAreaPeer;
+import java.awt.peer.TextFieldPeer;
+import java.awt.peer.TrayIconPeer;
+import java.awt.peer.WindowPeer;
import java.beans.PropertyChangeListener;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Properties;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.Vector;
+
import javax.swing.LookAndFeel;
import javax.swing.UIDefaults;
-import sun.awt.*;
+
+import sun.awt.AWTAccessor;
+import sun.awt.AWTPermissions;
+import sun.awt.AppContext;
+import sun.awt.DisplayChangedListener;
+import sun.awt.LightweightFrame;
+import sun.awt.SunToolkit;
+import sun.awt.UNIXToolkit;
+import sun.awt.X11GraphicsConfig;
+import sun.awt.X11GraphicsDevice;
+import sun.awt.X11GraphicsEnvironment;
+import sun.awt.XSettings;
import sun.awt.datatransfer.DataTransferer;
+import sun.awt.util.PerformanceLogger;
+import sun.awt.util.ThreadGroupUtils;
import sun.font.FontConfigManager;
import sun.java2d.SunGraphicsEnvironment;
-import sun.awt.util.PerformanceLogger;
-import sun.awt.util.ThreadGroupUtils;
import sun.print.PrintJob2D;
+import sun.security.action.GetBooleanAction;
import sun.security.action.GetPropertyAction;
-import sun.security.action.GetBooleanAction;
import sun.util.logging.PlatformLogger;
+
import static sun.awt.X11.XlibUtil.scaleDown;
public final class XToolkit extends UNIXToolkit implements Runnable {
@@ -2587,7 +2681,7 @@
@Override
public boolean isWindowTranslucencySupported() {
//NOTE: it may not be supported. The actual check is being performed
- // at com.sun.awt.AWTUtilities(). In X11 we need to check
+ // at java.awt.GraphicsDevice. In X11 we need to check
// whether there's any translucency-capable GC available.
return true;
}
--- a/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -22,42 +22,50 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package sun.awt.X11;
-import java.awt.*;
-
+import java.awt.AWTEvent;
+import java.awt.Component;
+import java.awt.Dialog;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.SystemColor;
+import java.awt.Window;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent;
import java.awt.event.WindowEvent;
-import java.awt.geom.AffineTransform;
-
import java.awt.peer.ComponentPeer;
import java.awt.peer.WindowPeer;
-
import java.io.UnsupportedEncodingException;
-
import java.security.AccessController;
import java.security.PrivilegedAction;
-
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;
-
import java.util.concurrent.atomic.AtomicBoolean;
+import sun.awt.AWTAccessor;
import sun.awt.AWTAccessor.ComponentAccessor;
-import sun.util.logging.PlatformLogger;
-
-import sun.awt.AWTAccessor;
import sun.awt.DisplayChangedListener;
+import sun.awt.IconInfo;
import sun.awt.SunToolkit;
import sun.awt.X11GraphicsDevice;
import sun.awt.X11GraphicsEnvironment;
-import sun.awt.IconInfo;
-
import sun.java2d.pipe.Region;
+import sun.util.logging.PlatformLogger;
class XWindowPeer extends XPanelPeer implements WindowPeer,
DisplayChangedListener {
@@ -446,16 +454,14 @@
}
private void updateShape() {
- // Shape shape = ((Window)target).getShape();
- Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
+ Shape shape = ((Window)target).getShape();
if (shape != null) {
applyShape(Region.getInstance(shape, null));
}
}
private void updateOpacity() {
- // float opacity = ((Window)target).getOpacity();
- float opacity = AWTAccessor.getWindowAccessor().getOpacity((Window)target);
+ float opacity = ((Window)target).getOpacity();
if (opacity < 1.0f) {
setOpacity(opacity);
}
@@ -2375,7 +2381,7 @@
public void print(Graphics g) {
// We assume we print the whole frame,
// so we expect no clip was set previously
- Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
+ Shape shape = ((Window)target).getShape();
if (shape != null) {
g.setClip(shape);
}
--- a/src/java.desktop/unix/classes/sun/awt/X11/XlibUtil.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XlibUtil.java Wed Nov 08 16:03:35 2017 -0500
@@ -38,6 +38,8 @@
import sun.awt.X11GraphicsDevice;
import sun.awt.X11GraphicsEnvironment;
+import sun.java2d.pipe.Region;
+
/*
* This class is a collection of utility methods that operate
* with native windows.
@@ -414,6 +416,6 @@
}
static int scaleDown(int x, int scale) {
- return x / scale;
+ return Region.clipRound(x / (double)scale);
}
}
--- a/src/java.desktop/unix/classes/sun/awt/X11GraphicsConfig.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/unix/classes/sun/awt/X11GraphicsConfig.java Wed Nov 08 16:03:35 2017 -0500
@@ -49,6 +49,7 @@
import sun.java2d.loops.RenderLoops;
import sun.java2d.loops.SurfaceType;
import sun.java2d.loops.CompositeType;
+import sun.java2d.pipe.Region;
import sun.java2d.x11.X11SurfaceData;
import sun.awt.image.OffScreenImage;
import sun.awt.image.SunVolatileImage;
@@ -265,11 +266,11 @@
}
public int scaleUp(int x) {
- return x * getScale();
+ return Region.clipRound(x * (double)getScale());
}
public int scaleDown(int x) {
- return x / getScale();
+ return Region.clipRound(x / (double)getScale());
}
/**
--- a/src/java.desktop/unix/legal/fontconfig.md Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-## Fontconfig v2.5
-
-### Fontconfig License
-<pre>
-
-Copyright 2001,2003 Keith Packard
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that the
-above copyright notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting documentation, and that
-the name of Keith Packard not be used in advertising or publicity pertaining
-to distribution of the software without specific, written prior permission.
-Keith Packard makes no representations about the suitability of this software
-for any purpose. It is provided "as is" without express or implied warranty.
-
-KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL KEITH
-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
-DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-</pre>
--- a/src/java.desktop/unix/native/common/awt/fontconfig.h Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,941 +0,0 @@
-/*
- * $RCSId: xc/lib/fontconfig/fontconfig/fontconfig.h,v 1.30 2002/09/26 00:17:27 keithp Exp $
- *
- * Copyright © 2001 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _FONTCONFIG_H_
-#define _FONTCONFIG_H_
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdarg.h>
-
-#if defined(__GNUC__) && (__GNUC__ >= 4)
-#define FC_ATTRIBUTE_SENTINEL(x) __attribute__((__sentinel__(0)))
-#else
-#define FC_ATTRIBUTE_SENTINEL(x)
-#endif
-
-#ifndef FcPublic
-#define FcPublic
-#endif
-
-typedef unsigned char FcChar8;
-typedef unsigned short FcChar16;
-typedef unsigned int FcChar32;
-typedef int FcBool;
-
-/*
- * Current Fontconfig version number. This same number
- * must appear in the fontconfig configure.in file. Yes,
- * it'a a pain to synchronize version numbers like this.
- */
-
-#define FC_MAJOR 2
-#define FC_MINOR 5
-#define FC_REVISION 0
-
-#define FC_VERSION ((FC_MAJOR * 10000) + (FC_MINOR * 100) + (FC_REVISION))
-
-/*
- * Current font cache file format version
- * This is appended to the cache files so that multiple
- * versions of the library will peacefully coexist
- *
- * Change this value whenever the disk format for the cache file
- * changes in any non-compatible way. Try to avoid such changes as
- * it means multiple copies of the font information.
- */
-
-#define FC_CACHE_VERSION "2"
-
-#define FcTrue 1
-#define FcFalse 0
-
-#define FC_FAMILY "family" /* String */
-#define FC_STYLE "style" /* String */
-#define FC_SLANT "slant" /* Int */
-#define FC_WEIGHT "weight" /* Int */
-#define FC_SIZE "size" /* Double */
-#define FC_ASPECT "aspect" /* Double */
-#define FC_PIXEL_SIZE "pixelsize" /* Double */
-#define FC_SPACING "spacing" /* Int */
-#define FC_FOUNDRY "foundry" /* String */
-#define FC_ANTIALIAS "antialias" /* Bool (depends) */
-#define FC_HINTING "hinting" /* Bool (true) */
-#define FC_HINT_STYLE "hintstyle" /* Int */
-#define FC_VERTICAL_LAYOUT "verticallayout" /* Bool (false) */
-#define FC_AUTOHINT "autohint" /* Bool (false) */
-#define FC_GLOBAL_ADVANCE "globaladvance" /* Bool (true) */
-#define FC_WIDTH "width" /* Int */
-#define FC_FILE "file" /* String */
-#define FC_INDEX "index" /* Int */
-#define FC_FT_FACE "ftface" /* FT_Face */
-#define FC_RASTERIZER "rasterizer" /* String */
-#define FC_OUTLINE "outline" /* Bool */
-#define FC_SCALABLE "scalable" /* Bool */
-#define FC_SCALE "scale" /* double */
-#define FC_DPI "dpi" /* double */
-#define FC_RGBA "rgba" /* Int */
-#define FC_MINSPACE "minspace" /* Bool use minimum line spacing */
-#define FC_SOURCE "source" /* String (deprecated) */
-#define FC_CHARSET "charset" /* CharSet */
-#define FC_LANG "lang" /* String RFC 3066 langs */
-#define FC_FONTVERSION "fontversion" /* Int from 'head' table */
-#define FC_FULLNAME "fullname" /* String */
-#define FC_FAMILYLANG "familylang" /* String RFC 3066 langs */
-#define FC_STYLELANG "stylelang" /* String RFC 3066 langs */
-#define FC_FULLNAMELANG "fullnamelang" /* String RFC 3066 langs */
-#define FC_CAPABILITY "capability" /* String */
-#define FC_FONTFORMAT "fontformat" /* String */
-#define FC_EMBOLDEN "embolden" /* Bool - true if emboldening needed*/
-#define FC_EMBEDDED_BITMAP "embeddedbitmap" /* Bool - true to enable embedded bitmaps */
-#define FC_DECORATIVE "decorative" /* Bool - true if style is a decorative variant */
-
-#define FC_CACHE_SUFFIX ".cache-"FC_CACHE_VERSION
-#define FC_DIR_CACHE_FILE "fonts.cache-"FC_CACHE_VERSION
-#define FC_USER_CACHE_FILE ".fonts.cache-"FC_CACHE_VERSION
-
-/* Adjust outline rasterizer */
-#define FC_CHAR_WIDTH "charwidth" /* Int */
-#define FC_CHAR_HEIGHT "charheight"/* Int */
-#define FC_MATRIX "matrix" /* FcMatrix */
-
-#define FC_WEIGHT_THIN 0
-#define FC_WEIGHT_EXTRALIGHT 40
-#define FC_WEIGHT_ULTRALIGHT FC_WEIGHT_EXTRALIGHT
-#define FC_WEIGHT_LIGHT 50
-#define FC_WEIGHT_BOOK 75
-#define FC_WEIGHT_REGULAR 80
-#define FC_WEIGHT_NORMAL FC_WEIGHT_REGULAR
-#define FC_WEIGHT_MEDIUM 100
-#define FC_WEIGHT_DEMIBOLD 180
-#define FC_WEIGHT_SEMIBOLD FC_WEIGHT_DEMIBOLD
-#define FC_WEIGHT_BOLD 200
-#define FC_WEIGHT_EXTRABOLD 205
-#define FC_WEIGHT_ULTRABOLD FC_WEIGHT_EXTRABOLD
-#define FC_WEIGHT_BLACK 210
-#define FC_WEIGHT_HEAVY FC_WEIGHT_BLACK
-#define FC_WEIGHT_EXTRABLACK 215
-#define FC_WEIGHT_ULTRABLACK FC_WEIGHT_EXTRABLACK
-
-#define FC_SLANT_ROMAN 0
-#define FC_SLANT_ITALIC 100
-#define FC_SLANT_OBLIQUE 110
-
-#define FC_WIDTH_ULTRACONDENSED 50
-#define FC_WIDTH_EXTRACONDENSED 63
-#define FC_WIDTH_CONDENSED 75
-#define FC_WIDTH_SEMICONDENSED 87
-#define FC_WIDTH_NORMAL 100
-#define FC_WIDTH_SEMIEXPANDED 113
-#define FC_WIDTH_EXPANDED 125
-#define FC_WIDTH_EXTRAEXPANDED 150
-#define FC_WIDTH_ULTRAEXPANDED 200
-
-#define FC_PROPORTIONAL 0
-#define FC_DUAL 90
-#define FC_MONO 100
-#define FC_CHARCELL 110
-
-/* sub-pixel order */
-#define FC_RGBA_UNKNOWN 0
-#define FC_RGBA_RGB 1
-#define FC_RGBA_BGR 2
-#define FC_RGBA_VRGB 3
-#define FC_RGBA_VBGR 4
-#define FC_RGBA_NONE 5
-
-/* hinting style */
-#define FC_HINT_NONE 0
-#define FC_HINT_SLIGHT 1
-#define FC_HINT_MEDIUM 2
-#define FC_HINT_FULL 3
-
-typedef enum _FcType {
- FcTypeVoid,
- FcTypeInteger,
- FcTypeDouble,
- FcTypeString,
- FcTypeBool,
- FcTypeMatrix,
- FcTypeCharSet,
- FcTypeFTFace,
- FcTypeLangSet
-} FcType;
-
-typedef struct _FcMatrix {
- double xx, xy, yx, yy;
-} FcMatrix;
-
-#define FcMatrixInit(m) ((m)->xx = (m)->yy = 1, \
- (m)->xy = (m)->yx = 0)
-
-/*
- * A data structure to represent the available glyphs in a font.
- * This is represented as a sparse boolean btree.
- */
-
-typedef struct _FcCharSet FcCharSet;
-
-typedef struct _FcObjectType {
- const char *object;
- FcType type;
-} FcObjectType;
-
-typedef struct _FcConstant {
- const FcChar8 *name;
- const char *object;
- int value;
-} FcConstant;
-
-typedef enum _FcResult {
- FcResultMatch, FcResultNoMatch, FcResultTypeMismatch, FcResultNoId,
- FcResultOutOfMemory
-} FcResult;
-
-typedef struct _FcPattern FcPattern;
-
-typedef struct _FcLangSet FcLangSet;
-
-typedef struct _FcValue {
- FcType type;
- union {
- const FcChar8 *s;
- int i;
- FcBool b;
- double d;
- const FcMatrix *m;
- const FcCharSet *c;
- void *f;
- const FcLangSet *l;
- } u;
-} FcValue;
-
-typedef struct _FcFontSet {
- int nfont;
- int sfont;
- FcPattern **fonts;
-} FcFontSet;
-
-typedef struct _FcObjectSet {
- int nobject;
- int sobject;
- const char **objects;
-} FcObjectSet;
-
-typedef enum _FcMatchKind {
- FcMatchPattern, FcMatchFont, FcMatchScan
-} FcMatchKind;
-
-typedef enum _FcLangResult {
- FcLangEqual = 0,
- FcLangDifferentCountry = 1,
- FcLangDifferentTerritory = 1,
- FcLangDifferentLang = 2
-} FcLangResult;
-
-typedef enum _FcSetName {
- FcSetSystem = 0,
- FcSetApplication = 1
-} FcSetName;
-
-typedef struct _FcAtomic FcAtomic;
-
-#if defined(__cplusplus) || defined(c_plusplus) /* for C++ V2.0 */
-#define _FCFUNCPROTOBEGIN extern "C" { /* do not leave open across includes */
-#define _FCFUNCPROTOEND }
-#else
-#define _FCFUNCPROTOBEGIN
-#define _FCFUNCPROTOEND
-#endif
-
-typedef enum { FcEndianBig, FcEndianLittle } FcEndian;
-
-typedef struct _FcConfig FcConfig;
-
-typedef struct _FcGlobalCache FcFileCache;
-
-typedef struct _FcBlanks FcBlanks;
-
-typedef struct _FcStrList FcStrList;
-
-typedef struct _FcStrSet FcStrSet;
-
-typedef struct _FcCache FcCache;
-
-_FCFUNCPROTOBEGIN
-
-/* fcblanks.c */
-FcPublic FcBlanks *
-FcBlanksCreate (void);
-
-FcPublic void
-FcBlanksDestroy (FcBlanks *b);
-
-FcPublic FcBool
-FcBlanksAdd (FcBlanks *b, FcChar32 ucs4);
-
-FcPublic FcBool
-FcBlanksIsMember (FcBlanks *b, FcChar32 ucs4);
-
-/* fccache.c */
-
-FcPublic const FcChar8 *
-FcCacheDir(const FcCache *c);
-
-FcPublic FcFontSet *
-FcCacheCopySet(const FcCache *c);
-
-FcPublic const FcChar8 *
-FcCacheSubdir (const FcCache *c, int i);
-
-FcPublic int
-FcCacheNumSubdir (const FcCache *c);
-
-FcPublic int
-FcCacheNumFont (const FcCache *c);
-
-FcPublic FcBool
-FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config);
-
-FcPublic FcBool
-FcDirCacheValid (const FcChar8 *cache_file);
-
-/* fccfg.c */
-FcPublic FcChar8 *
-FcConfigHome (void);
-
-FcPublic FcBool
-FcConfigEnableHome (FcBool enable);
-
-FcPublic FcChar8 *
-FcConfigFilename (const FcChar8 *url);
-
-FcPublic FcConfig *
-FcConfigCreate (void);
-
-FcPublic void
-FcConfigDestroy (FcConfig *config);
-
-FcPublic FcBool
-FcConfigSetCurrent (FcConfig *config);
-
-FcPublic FcConfig *
-FcConfigGetCurrent (void);
-
-FcPublic FcBool
-FcConfigUptoDate (FcConfig *config);
-
-FcPublic FcBool
-FcConfigBuildFonts (FcConfig *config);
-
-FcPublic FcStrList *
-FcConfigGetFontDirs (FcConfig *config);
-
-FcPublic FcStrList *
-FcConfigGetConfigDirs (FcConfig *config);
-
-FcPublic FcStrList *
-FcConfigGetConfigFiles (FcConfig *config);
-
-FcPublic FcChar8 *
-FcConfigGetCache (FcConfig *config);
-
-FcPublic FcBlanks *
-FcConfigGetBlanks (FcConfig *config);
-
-FcPublic FcStrList *
-FcConfigGetCacheDirs (FcConfig *config);
-
-FcPublic int
-FcConfigGetRescanInterval (FcConfig *config);
-
-FcPublic FcBool
-FcConfigSetRescanInterval (FcConfig *config, int rescanInterval);
-
-FcPublic FcFontSet *
-FcConfigGetFonts (FcConfig *config,
- FcSetName set);
-
-FcPublic FcBool
-FcConfigAppFontAddFile (FcConfig *config,
- const FcChar8 *file);
-
-FcPublic FcBool
-FcConfigAppFontAddDir (FcConfig *config,
- const FcChar8 *dir);
-
-FcPublic void
-FcConfigAppFontClear (FcConfig *config);
-
-FcPublic FcBool
-FcConfigSubstituteWithPat (FcConfig *config,
- FcPattern *p,
- FcPattern *p_pat,
- FcMatchKind kind);
-
-FcPublic FcBool
-FcConfigSubstitute (FcConfig *config,
- FcPattern *p,
- FcMatchKind kind);
-
-/* fccharset.c */
-FcPublic FcCharSet*
-FcCharSetCreate (void);
-
-/* deprecated alias for FcCharSetCreate */
-FcPublic FcCharSet *
-FcCharSetNew (void);
-
-FcPublic void
-FcCharSetDestroy (FcCharSet *fcs);
-
-FcPublic FcBool
-FcCharSetAddChar (FcCharSet *fcs, FcChar32 ucs4);
-
-FcPublic FcCharSet*
-FcCharSetCopy (FcCharSet *src);
-
-FcPublic FcBool
-FcCharSetEqual (const FcCharSet *a, const FcCharSet *b);
-
-FcPublic FcCharSet*
-FcCharSetIntersect (const FcCharSet *a, const FcCharSet *b);
-
-FcPublic FcCharSet*
-FcCharSetUnion (const FcCharSet *a, const FcCharSet *b);
-
-FcPublic FcCharSet*
-FcCharSetSubtract (const FcCharSet *a, const FcCharSet *b);
-
-FcPublic FcBool
-FcCharSetHasChar (const FcCharSet *fcs, FcChar32 ucs4);
-
-FcPublic FcChar32
-FcCharSetCount (const FcCharSet *a);
-
-FcPublic FcChar32
-FcCharSetIntersectCount (const FcCharSet *a, const FcCharSet *b);
-
-FcPublic FcChar32
-FcCharSetSubtractCount (const FcCharSet *a, const FcCharSet *b);
-
-FcPublic FcBool
-FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b);
-
-#define FC_CHARSET_MAP_SIZE (256/32)
-#define FC_CHARSET_DONE ((FcChar32) -1)
-
-FcPublic FcChar32
-FcCharSetFirstPage (const FcCharSet *a,
- FcChar32 map[FC_CHARSET_MAP_SIZE],
- FcChar32 *next);
-
-FcPublic FcChar32
-FcCharSetNextPage (const FcCharSet *a,
- FcChar32 map[FC_CHARSET_MAP_SIZE],
- FcChar32 *next);
-
-/*
- * old coverage API, rather hard to use correctly
- */
-
-FcPublic FcChar32
-FcCharSetCoverage (const FcCharSet *a, FcChar32 page, FcChar32 *result);
-
-/* fcdbg.c */
-FcPublic void
-FcValuePrint (const FcValue v);
-
-FcPublic void
-FcPatternPrint (const FcPattern *p);
-
-FcPublic void
-FcFontSetPrint (const FcFontSet *s);
-
-/* fcdefault.c */
-FcPublic void
-FcDefaultSubstitute (FcPattern *pattern);
-
-/* fcdir.c */
-FcPublic FcBool
-FcFileIsDir (const FcChar8 *file);
-
-FcPublic FcBool
-FcFileScan (FcFontSet *set,
- FcStrSet *dirs,
- FcFileCache *cache,
- FcBlanks *blanks,
- const FcChar8 *file,
- FcBool force);
-
-FcPublic FcBool
-FcDirScan (FcFontSet *set,
- FcStrSet *dirs,
- FcFileCache *cache,
- FcBlanks *blanks,
- const FcChar8 *dir,
- FcBool force);
-
-FcPublic FcBool
-FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir);
-
-FcPublic FcCache *
-FcDirCacheLoad (const FcChar8 *dir, FcConfig *config, FcChar8 **cache_file);
-
-FcPublic FcCache *
-FcDirCacheRead (const FcChar8 *dir, FcBool force, FcConfig *config);
-
-FcPublic FcCache *
-FcDirCacheLoadFile (const FcChar8 *cache_file, struct stat *file_stat);
-
-FcPublic void
-FcDirCacheUnload (FcCache *cache);
-
-/* fcfreetype.c */
-FcPublic FcPattern *
-FcFreeTypeQuery (const FcChar8 *file, int id, FcBlanks *blanks, int *count);
-
-/* fcfs.c */
-
-FcPublic FcFontSet *
-FcFontSetCreate (void);
-
-FcPublic void
-FcFontSetDestroy (FcFontSet *s);
-
-FcPublic FcBool
-FcFontSetAdd (FcFontSet *s, FcPattern *font);
-
-/* fcinit.c */
-FcPublic FcConfig *
-FcInitLoadConfig (void);
-
-FcPublic FcConfig *
-FcInitLoadConfigAndFonts (void);
-
-FcPublic FcBool
-FcInit (void);
-
-FcPublic void
-FcFini (void);
-
-FcPublic int
-FcGetVersion (void);
-
-FcPublic FcBool
-FcInitReinitialize (void);
-
-FcPublic FcBool
-FcInitBringUptoDate (void);
-
-/* fclang.c */
-FcPublic FcStrSet *
-FcGetLangs (void);
-
-FcPublic const FcCharSet *
-FcLangGetCharSet (const FcChar8 *lang);
-
-FcPublic FcLangSet*
-FcLangSetCreate (void);
-
-FcPublic void
-FcLangSetDestroy (FcLangSet *ls);
-
-FcPublic FcLangSet*
-FcLangSetCopy (const FcLangSet *ls);
-
-FcPublic FcBool
-FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang);
-
-FcPublic FcLangResult
-FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang);
-
-FcPublic FcLangResult
-FcLangSetCompare (const FcLangSet *lsa, const FcLangSet *lsb);
-
-FcPublic FcBool
-FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb);
-
-FcPublic FcBool
-FcLangSetEqual (const FcLangSet *lsa, const FcLangSet *lsb);
-
-FcPublic FcChar32
-FcLangSetHash (const FcLangSet *ls);
-
-/* fclist.c */
-FcPublic FcObjectSet *
-FcObjectSetCreate (void);
-
-FcPublic FcBool
-FcObjectSetAdd (FcObjectSet *os, const char *object);
-
-FcPublic void
-FcObjectSetDestroy (FcObjectSet *os);
-
-FcPublic FcObjectSet *
-FcObjectSetVaBuild (const char *first, va_list va);
-
-FcPublic FcObjectSet *
-FcObjectSetBuild (const char *first, ...) FC_ATTRIBUTE_SENTINEL(0);
-
-FcPublic FcFontSet *
-FcFontSetList (FcConfig *config,
- FcFontSet **sets,
- int nsets,
- FcPattern *p,
- FcObjectSet *os);
-
-FcPublic FcFontSet *
-FcFontList (FcConfig *config,
- FcPattern *p,
- FcObjectSet *os);
-
-/* fcatomic.c */
-
-FcPublic FcAtomic *
-FcAtomicCreate (const FcChar8 *file);
-
-FcPublic FcBool
-FcAtomicLock (FcAtomic *atomic);
-
-FcPublic FcChar8 *
-FcAtomicNewFile (FcAtomic *atomic);
-
-FcPublic FcChar8 *
-FcAtomicOrigFile (FcAtomic *atomic);
-
-FcPublic FcBool
-FcAtomicReplaceOrig (FcAtomic *atomic);
-
-FcPublic void
-FcAtomicDeleteNew (FcAtomic *atomic);
-
-FcPublic void
-FcAtomicUnlock (FcAtomic *atomic);
-
-FcPublic void
-FcAtomicDestroy (FcAtomic *atomic);
-
-/* fcmatch.c */
-FcPublic FcPattern *
-FcFontSetMatch (FcConfig *config,
- FcFontSet **sets,
- int nsets,
- FcPattern *p,
- FcResult *result);
-
-FcPublic FcPattern *
-FcFontMatch (FcConfig *config,
- FcPattern *p,
- FcResult *result);
-
-FcPublic FcPattern *
-FcFontRenderPrepare (FcConfig *config,
- FcPattern *pat,
- FcPattern *font);
-
-FcPublic FcFontSet *
-FcFontSetSort (FcConfig *config,
- FcFontSet **sets,
- int nsets,
- FcPattern *p,
- FcBool trim,
- FcCharSet **csp,
- FcResult *result);
-
-FcPublic FcFontSet *
-FcFontSort (FcConfig *config,
- FcPattern *p,
- FcBool trim,
- FcCharSet **csp,
- FcResult *result);
-
-FcPublic void
-FcFontSetSortDestroy (FcFontSet *fs);
-
-/* fcmatrix.c */
-FcPublic FcMatrix *
-FcMatrixCopy (const FcMatrix *mat);
-
-FcPublic FcBool
-FcMatrixEqual (const FcMatrix *mat1, const FcMatrix *mat2);
-
-FcPublic void
-FcMatrixMultiply (FcMatrix *result, const FcMatrix *a, const FcMatrix *b);
-
-FcPublic void
-FcMatrixRotate (FcMatrix *m, double c, double s);
-
-FcPublic void
-FcMatrixScale (FcMatrix *m, double sx, double sy);
-
-FcPublic void
-FcMatrixShear (FcMatrix *m, double sh, double sv);
-
-/* fcname.c */
-
-FcPublic FcBool
-FcNameRegisterObjectTypes (const FcObjectType *types, int ntype);
-
-FcPublic FcBool
-FcNameUnregisterObjectTypes (const FcObjectType *types, int ntype);
-
-FcPublic const FcObjectType *
-FcNameGetObjectType (const char *object);
-
-FcPublic FcBool
-FcNameRegisterConstants (const FcConstant *consts, int nconsts);
-
-FcPublic FcBool
-FcNameUnregisterConstants (const FcConstant *consts, int nconsts);
-
-FcPublic const FcConstant *
-FcNameGetConstant (FcChar8 *string);
-
-FcPublic FcBool
-FcNameConstant (FcChar8 *string, int *result);
-
-FcPublic FcPattern *
-FcNameParse (const FcChar8 *name);
-
-FcPublic FcChar8 *
-FcNameUnparse (FcPattern *pat);
-
-/* fcpat.c */
-FcPublic FcPattern *
-FcPatternCreate (void);
-
-FcPublic FcPattern *
-FcPatternDuplicate (const FcPattern *p);
-
-FcPublic void
-FcPatternReference (FcPattern *p);
-
-FcPublic void
-FcValueDestroy (FcValue v);
-
-FcPublic FcBool
-FcValueEqual (FcValue va, FcValue vb);
-
-FcPublic FcValue
-FcValueSave (FcValue v);
-
-FcPublic void
-FcPatternDestroy (FcPattern *p);
-
-FcPublic FcBool
-FcPatternEqual (const FcPattern *pa, const FcPattern *pb);
-
-FcPublic FcBool
-FcPatternEqualSubset (const FcPattern *pa, const FcPattern *pb, const FcObjectSet *os);
-
-FcPublic FcChar32
-FcPatternHash (const FcPattern *p);
-
-FcPublic FcBool
-FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append);
-
-FcPublic FcBool
-FcPatternAddWeak (FcPattern *p, const char *object, FcValue value, FcBool append);
-
-FcPublic FcResult
-FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v);
-
-FcPublic FcBool
-FcPatternDel (FcPattern *p, const char *object);
-
-FcPublic FcBool
-FcPatternRemove (FcPattern *p, const char *object, int id);
-
-FcPublic FcBool
-FcPatternAddInteger (FcPattern *p, const char *object, int i);
-
-FcPublic FcBool
-FcPatternAddDouble (FcPattern *p, const char *object, double d);
-
-FcPublic FcBool
-FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s);
-
-FcPublic FcBool
-FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s);
-
-FcPublic FcBool
-FcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c);
-
-FcPublic FcBool
-FcPatternAddBool (FcPattern *p, const char *object, FcBool b);
-
-FcPublic FcBool
-FcPatternAddLangSet (FcPattern *p, const char *object, const FcLangSet *ls);
-
-FcPublic FcResult
-FcPatternGetInteger (const FcPattern *p, const char *object, int n, int *i);
-
-FcPublic FcResult
-FcPatternGetDouble (const FcPattern *p, const char *object, int n, double *d);
-
-FcPublic FcResult
-FcPatternGetString (const FcPattern *p, const char *object, int n, FcChar8 ** s);
-
-FcPublic FcResult
-FcPatternGetMatrix (const FcPattern *p, const char *object, int n, FcMatrix **s);
-
-FcPublic FcResult
-FcPatternGetCharSet (const FcPattern *p, const char *object, int n, FcCharSet **c);
-
-FcPublic FcResult
-FcPatternGetBool (const FcPattern *p, const char *object, int n, FcBool *b);
-
-FcPublic FcResult
-FcPatternGetLangSet (const FcPattern *p, const char *object, int n, FcLangSet **ls);
-
-FcPublic FcPattern *
-FcPatternVaBuild (FcPattern *orig, va_list va);
-
-FcPublic FcPattern *
-FcPatternBuild (FcPattern *orig, ...) FC_ATTRIBUTE_SENTINEL(0);
-
-/* fcstr.c */
-
-FcPublic FcChar8 *
-FcStrCopy (const FcChar8 *s);
-
-FcPublic FcChar8 *
-FcStrCopyFilename (const FcChar8 *s);
-
-FcPublic FcChar8 *
-FcStrPlus (const FcChar8 *s1, const FcChar8 *s2);
-
-FcPublic void
-FcStrFree (FcChar8 *s);
-
-/* These are ASCII only, suitable only for pattern element names */
-#define FcIsUpper(c) ((0101 <= (c) && (c) <= 0132))
-#define FcIsLower(c) ((0141 <= (c) && (c) <= 0172))
-#define FcToLower(c) (FcIsUpper(c) ? (c) - 0101 + 0141 : (c))
-
-FcPublic FcChar8 *
-FcStrDowncase (const FcChar8 *s);
-
-FcPublic int
-FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2);
-
-FcPublic int
-FcStrCmp (const FcChar8 *s1, const FcChar8 *s2);
-
-FcPublic const FcChar8 *
-FcStrStrIgnoreCase (const FcChar8 *s1, const FcChar8 *s2);
-
-FcPublic const FcChar8 *
-FcStrStr (const FcChar8 *s1, const FcChar8 *s2);
-
-FcPublic int
-FcUtf8ToUcs4 (const FcChar8 *src_orig,
- FcChar32 *dst,
- int len);
-
-FcPublic FcBool
-FcUtf8Len (const FcChar8 *string,
- int len,
- int *nchar,
- int *wchar);
-
-#define FC_UTF8_MAX_LEN 6
-
-FcPublic int
-FcUcs4ToUtf8 (FcChar32 ucs4,
- FcChar8 dest[FC_UTF8_MAX_LEN]);
-
-FcPublic int
-FcUtf16ToUcs4 (const FcChar8 *src_orig,
- FcEndian endian,
- FcChar32 *dst,
- int len); /* in bytes */
-
-FcPublic FcBool
-FcUtf16Len (const FcChar8 *string,
- FcEndian endian,
- int len, /* in bytes */
- int *nchar,
- int *wchar);
-
-FcPublic FcChar8 *
-FcStrDirname (const FcChar8 *file);
-
-FcPublic FcChar8 *
-FcStrBasename (const FcChar8 *file);
-
-FcPublic FcStrSet *
-FcStrSetCreate (void);
-
-FcPublic FcBool
-FcStrSetMember (FcStrSet *set, const FcChar8 *s);
-
-FcPublic FcBool
-FcStrSetEqual (FcStrSet *sa, FcStrSet *sb);
-
-FcPublic FcBool
-FcStrSetAdd (FcStrSet *set, const FcChar8 *s);
-
-FcPublic FcBool
-FcStrSetAddFilename (FcStrSet *set, const FcChar8 *s);
-
-FcPublic FcBool
-FcStrSetDel (FcStrSet *set, const FcChar8 *s);
-
-FcPublic void
-FcStrSetDestroy (FcStrSet *set);
-
-FcPublic FcStrList *
-FcStrListCreate (FcStrSet *set);
-
-FcPublic FcChar8 *
-FcStrListNext (FcStrList *list);
-
-FcPublic void
-FcStrListDone (FcStrList *list);
-
-/* fcxml.c */
-FcPublic FcBool
-FcConfigParseAndLoad (FcConfig *config, const FcChar8 *file, FcBool complain);
-
-_FCFUNCPROTOEND
-
-#undef FC_ATTRIBUTE_SENTINEL
-
-
-#ifndef _FCINT_H_
-
-/*
- * Deprecated functions are placed here to help users fix their code without
- * digging through documentation
- */
-
-#define FcConfigGetRescanInverval FcConfigGetRescanInverval_REPLACE_BY_FcConfigGetRescanInterval
-#define FcConfigSetRescanInverval FcConfigSetRescanInverval_REPLACE_BY_FcConfigSetRescanInterval
-
-#endif
-
-#endif /* _FONTCONFIG_H_ */
--- a/src/java.desktop/unix/native/common/awt/fontpath.c Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/unix/native/common/awt/fontpath.c Wed Nov 08 16:03:35 2017 -0500
@@ -578,7 +578,7 @@
#include <dlfcn.h>
-#include "fontconfig.h"
+#include <fontconfig/fontconfig.h>
static void* openFontConfig() {
@@ -1254,6 +1254,7 @@
&& (strcmp((char*)fontformat, "TrueType") != 0)
#if defined(__linux__) || defined(_AIX)
&& (strcmp((char*)fontformat, "Type 1") != 0)
+ && (strcmp((char*)fontformat, "CFF") != 0)
#endif
) {
continue;
--- a/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -22,23 +22,48 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package sun.awt.windows;
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.image.*;
-import java.awt.peer.*;
-
-import java.beans.*;
+import java.awt.AWTEvent;
+import java.awt.AWTEventMulticaster;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dialog;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Insets;
+import java.awt.KeyboardFocusManager;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.SystemColor;
+import java.awt.Window;
+import java.awt.event.FocusEvent;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.awt.geom.AffineTransform;
+import java.awt.image.DataBufferInt;
+import java.awt.peer.WindowPeer;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.LinkedList;
+import java.util.List;
-import java.util.*;
-import java.util.List;
-import sun.util.logging.PlatformLogger;
-import java.awt.geom.AffineTransform;
-import sun.awt.*;
-
+import sun.awt.AWTAccessor;
+import sun.awt.AppContext;
+import sun.awt.DisplayChangedListener;
+import sun.awt.SunToolkit;
+import sun.awt.Win32GraphicsConfig;
+import sun.awt.Win32GraphicsDevice;
+import sun.awt.Win32GraphicsEnvironment;
import sun.java2d.pipe.Region;
import sun.swing.SwingUtilities2;
+import sun.util.logging.PlatformLogger;
public class WWindowPeer extends WPanelPeer implements WindowPeer,
DisplayChangedListener
@@ -671,7 +696,7 @@
public void print(Graphics g) {
// We assume we print the whole frame,
// so we expect no clip was set previously
- Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
+ Shape shape = ((Window)target).getShape();
if (shape != null) {
g.setClip(shape);
}
--- a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp Wed Nov 08 16:03:35 2017 -0500
@@ -632,22 +632,38 @@
int AwtWin32GraphicsDevice::ScaleUpX(int x)
{
- return (int)ceil(x * scaleX);
+ return ClipRound(x * scaleX);
}
int AwtWin32GraphicsDevice::ScaleUpY(int y)
{
- return (int)ceil(y * scaleY);
+ return ClipRound(y * scaleY);
}
int AwtWin32GraphicsDevice::ScaleDownX(int x)
{
- return (int)ceil(x / scaleX);
+ return ClipRound(x / scaleX);
}
int AwtWin32GraphicsDevice::ScaleDownY(int y)
{
- return (int)ceil(y / scaleY);
+ return ClipRound(y / scaleY);
+}
+
+int AwtWin32GraphicsDevice::ClipRound(double value)
+{
+ value -= 0.5;
+ if (value < INT_MIN)
+ {
+ return INT_MIN;
+ }
+
+ if (value > INT_MAX)
+ {
+ return INT_MAX;
+ }
+
+ return (int)ceil(value);
}
void AwtWin32GraphicsDevice::InitDesktopScales()
--- a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.h Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.h Wed Nov 08 16:03:35 2017 -0500
@@ -119,6 +119,7 @@
float scaleY;
static HDC MakeDCFromMonitor(HMONITOR);
+ static int ClipRound(double value);
};
#endif AWT_WIN32GRAPHICSDEVICE_H
--- a/src/java.management/share/classes/java/lang/management/RuntimeMXBean.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.management/share/classes/java/lang/management/RuntimeMXBean.java Wed Nov 08 16:03:35 2017 -0500
@@ -25,6 +25,9 @@
package java.lang.management;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
/**
* The management interface for the runtime system of
* the Java virtual machine.
@@ -61,6 +64,22 @@
*/
public interface RuntimeMXBean extends PlatformManagedObject {
/**
+ * Returns the {@linkplain ProcessHandle#pid process ID} representing
+ * the running Java virtual machine.
+ *
+ * @implSpec The default implementation returns {@link ProcessHandle#pid process ID}
+ * of the {@linkplain ProcessHandle#current current process}.
+ *
+ * @return the process ID representing the running Java virtual machine.
+ *
+ * @since 10
+ */
+ public default long getPid() {
+ return AccessController.doPrivileged((PrivilegedAction<Long>)
+ () -> ProcessHandle.current().pid());
+ }
+
+ /**
* Returns the name representing the running Java virtual machine.
* The returned name string can be any arbitrary string and
* a Java virtual machine implementation can choose
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -181,6 +181,7 @@
* @throws IOException if a failure from reading from the bytes argument
* occurs
*/
+ @SuppressWarnings("fallthrough") // by design for case Const.INSTANCEOF
public static String codeToString(final ByteSequence bytes, final ConstantPool constant_pool,
final boolean verbose) throws IOException {
final short opcode = (short) bytes.readUnsignedByte();
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -175,6 +175,7 @@
@Override
+ @SuppressWarnings("fallthrough") // by design for case Const.ANEWARRAY
public void visitAllocationInstruction( final AllocationInstruction i ) {
Type type;
if (i instanceof CPInstruction) {
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Message.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Message.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -54,6 +54,7 @@
return Type.Void;
}
+ @SuppressWarnings("fallthrough") // at default
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Step.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Step.java Wed Nov 08 16:03:35 2017 -0500
@@ -232,6 +232,7 @@
translateStep(classGen, methodGen, hasPredicates() ? _predicates.size() - 1 : -1);
}
+ @SuppressWarnings("fallthrough") // at case NodeTest.ANODE and NodeTest.ELEMENT
private void translateStep(ClassGenerator classGen,
MethodGenerator methodGen,
int predicateIndex) {
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Whitespace.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Whitespace.java Wed Nov 08 16:03:35 2017 -0500
@@ -191,6 +191,7 @@
* Scans through the rules vector and looks for a rule of higher
* priority that contradicts the current rule.
*/
+ @SuppressWarnings("fallthrough") // case RULE_NAMESPACE
private static WhitespaceRule findContradictingRule(List<WhitespaceRule> rules,
WhitespaceRule rule) {
for (WhitespaceRule currentRule : rules) {
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XPathLexer.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XPathLexer.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -73,6 +74,7 @@
* name instead of a keyword (Jira-1912). Look two tokens behind
* to desambiguate expressions like "* and *" or "and * and".
*/
+ @SuppressWarnings("fallthrough")
Symbol disambiguateOperator(int ss) throws Exception {
switch (last) {
case sym.STAR:
@@ -745,6 +747,7 @@
":13,-1:2,184:10,-1:3,76,184,76:3,-1:4,184:6,64,-1:2,76,-1:6,184:5,-1:3,184:" +
"4,232,184:8,-1:2,184:10,-1:3,76,184,76:3");
+ @SuppressWarnings("fallthrough") // at case 18 and -1
public com.sun.java_cup.internal.runtime.Symbol next_token ()
throws java.io.IOException,
Exception
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XPathParser.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XPathParser.java Wed Nov 08 16:03:35 2017 -0500
@@ -1591,13 +1591,13 @@
RESULT = new CurrentCall(fname);
}
else if (fname == parser.getQNameIgnoreDefaultNs("number")) {
- RESULT = new NumberCall(fname, parser.EmptyArgs);
+ RESULT = new NumberCall(fname, XPathParser.EmptyArgs);
}
else if (fname == parser.getQNameIgnoreDefaultNs("string")) {
- RESULT = new StringCall(fname, parser.EmptyArgs);
+ RESULT = new StringCall(fname, XPathParser.EmptyArgs);
}
else if (fname == parser.getQNameIgnoreDefaultNs("concat")) {
- RESULT = new ConcatCall(fname, parser.EmptyArgs);
+ RESULT = new ConcatCall(fname, XPathParser.EmptyArgs);
}
else if (fname == parser.getQNameIgnoreDefaultNs("true")) {
RESULT = new BooleanExpr(true);
@@ -1609,10 +1609,10 @@
RESULT = new NameCall(fname);
}
else if (fname == parser.getQNameIgnoreDefaultNs("generate-id")) {
- RESULT = new GenerateIdCall(fname, parser.EmptyArgs);
+ RESULT = new GenerateIdCall(fname, XPathParser.EmptyArgs);
}
else if (fname == parser.getQNameIgnoreDefaultNs("string-length")) {
- RESULT = new StringLengthCall(fname, parser.EmptyArgs);
+ RESULT = new StringLengthCall(fname, XPathParser.EmptyArgs);
}
else if (fname == parser.getQNameIgnoreDefaultNs("position")) {
RESULT = new PositionCall(fname);
@@ -1627,7 +1627,7 @@
RESULT = new NamespaceUriCall(fname);
}
else {
- RESULT = new FunctionCall(fname, parser.EmptyArgs);
+ RESULT = new FunctionCall(fname, XPathParser.EmptyArgs);
}
parser_result = new Symbol(16/*FunctionCall*/, (parser_stack.get(parser_top-2)).left, (parser_stack.get(parser_top-0)).right, RESULT);
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/dom/SAXImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/dom/SAXImpl.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -1278,11 +1279,13 @@
// For "attribute::p:*", the principal node kind is
// attribute
m_baseIterator = getAxisIterator(axis);
+ break;
}
case Axis.NAMESPACE: {
// This covers "namespace::p:*". It is syntactically
// correct, though it doesn't make much sense.
m_baseIterator = getAxisIterator(axis);
+ break;
}
default: {
// In all other cases, the principal node kind is
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/output/TransletOutputHandlerFactory.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/output/TransletOutputHandlerFactory.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -145,6 +145,7 @@
_indentNumber = value;
}
+ @SuppressWarnings("fallthrough") // intentional at case STAX, SAX
public SerializationHandler getSerializationHandler()
throws IOException, ParserConfigurationException
{
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DeferredDocumentTypeImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DeferredDocumentTypeImpl.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -161,8 +161,8 @@
if (((DocumentImpl)getOwnerDocument()).allowGrammarAccess){
insertBefore(node, last);
last = node;
- break;
}
+ break;
}
// NOTE: Should never get here! -Ac
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDElementTraverser.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDElementTraverser.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -439,7 +439,7 @@
fSchemaHandler.checkForDuplicateNames(
(schemaDoc.fTargetNamespace == null) ? ","+DOMUtil.getAttrValue(child, SchemaSymbols.ATT_NAME)
: schemaDoc.fTargetNamespace+","+ DOMUtil.getAttrValue(child, SchemaSymbols.ATT_NAME),
- fSchemaHandler.ATTRIBUTE_TYPE, fSchemaHandler.getIDRegistry(), fSchemaHandler.getIDRegistry_sub(),
+ XSDHandler.ATTRIBUTE_TYPE, fSchemaHandler.getIDRegistry(), fSchemaHandler.getIDRegistry_sub(),
child, schemaDoc);
}
} else if (childName.equals(SchemaSymbols.ELT_KEYREF)) {
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java Wed Nov 08 16:03:35 2017 -0500
@@ -3025,6 +3025,7 @@
return newComponents;
}
+ @SuppressWarnings("fallthrough")
private void expandRelatedComponents(XSObject component,List<XSObject>componentList, Map<String, List<String>> dependencies) {
short componentType = component.getType();
switch (componentType) {
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractDOMParser.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractDOMParser.java Wed Nov 08 16:03:35 2017 -0500
@@ -600,6 +600,7 @@
*
* @throws XNIException Thrown by application to signal an error.
*/
+ @SuppressWarnings("fallthrough") // by design at case LSParserFilter.FILTER_SKIP
public void comment (XMLString text, Augmentations augs) throws XNIException {
if (fInDTD) {
if (fInternalSubset != null && !fInDTDExternalSubset) {
@@ -673,6 +674,7 @@
*
* @throws XNIException Thrown by handler to signal an error.
*/
+ @SuppressWarnings("fallthrough") // by design at case LSParserFilter.FILTER_REJECT
public void processingInstruction (String target, XMLString data, Augmentations augs)
throws XNIException {
@@ -1416,6 +1418,7 @@
*
* @throws XNIException Thrown by handler to signal an error.
*/
+ @SuppressWarnings("fallthrough") // by design at case LSParserFilter.FILTER_REJECT
public void endCDATA (Augmentations augs) throws XNIException {
fInCDATASection = false;
@@ -2596,6 +2599,7 @@
* or removed fFistChunk must be set to true, otherwise some data can be lost.
*
*/
+ @SuppressWarnings("fallthrough") // by design at case LSParserFilter.FILTER_REJECT
protected void setCharacterData (boolean sawChars){
// handle character data
--- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/ref/DTMDocumentImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/ref/DTMDocumentImpl.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -1697,6 +1697,7 @@
* @return String Value of this node, or null if not
* meaningful for this node type.
*/
+ @SuppressWarnings("fallthrough")
public String getNodeValue(int nodeHandle)
{
nodes.readSlot(nodeHandle, gotslot);
--- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/ref/dom2dtm/DOM2DTM.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/ref/dom2dtm/DOM2DTM.java Wed Nov 08 16:03:35 2017 -0500
@@ -1651,6 +1651,7 @@
* @param node Node whose subtree is to be walked, gathering the
* contents of all Text or CDATASection nodes.
*/
+ @SuppressWarnings("fallthrough")
protected static void dispatchNodeData(Node node,
org.xml.sax.ContentHandler ch,
int depth)
--- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/BaseMarkupSerializer.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/BaseMarkupSerializer.java Wed Nov 08 16:03:35 2017 -0500
@@ -1020,6 +1020,7 @@
* @throws IOException An I/O exception occured while
* serializing
*/
+ @SuppressWarnings("fallthrough") // by design at case Node.DOCUMENT_FRAGMENT_NODE
protected void serializeNode( Node node )
throws IOException
{
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/FilterExprWalker.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/FilterExprWalker.java Wed Nov 08 16:03:35 2017 -0500
@@ -62,6 +62,7 @@
*
* @throws javax.xml.transform.TransformerException
*/
+ @SuppressWarnings("fallthrough")
public void init(Compiler compiler, int opPos, int stepType)
throws javax.xml.transform.TransformerException
{
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/MatchPatternIterator.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/MatchPatternIterator.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -299,7 +299,7 @@
System.out.println(", "+m_cdtm.getNodeName(n));
// if(m_cdtm.getNodeName(n).equals("near-east"))
System.out.println("pattern: "+m_pattern.toString());
- m_pattern.debugWhatToShow(m_pattern.getWhatToShow());
+ NodeTest.debugWhatToShow(m_pattern.getWhatToShow());
}
XObject score = m_pattern.execute(xctxt);
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/WalkerFactory.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/WalkerFactory.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -554,6 +554,7 @@
*
* @throws javax.xml.transform.TransformerException
*/
+ @SuppressWarnings("fallthrough") // by design at case OpCodes.FROM_DESCENDANTS
private static boolean isOptimizableForDescendantIterator(
Compiler compiler, int stepOpCodePos, int stepIndex)
throws javax.xml.transform.TransformerException
@@ -1102,7 +1103,7 @@
System.out.print(", predAxis: " + Axis.getNames(ai.getAxis()));
System.out.print(", what: ");
System.out.print(" ");
- ai.debugWhatToShow(ai.getWhatToShow());
+ NodeTest.debugWhatToShow(ai.getWhatToShow());
}
int argLen = compiler.getFirstPredicateOpPos(opPos);
@@ -1621,6 +1622,7 @@
*
* @throws javax.xml.transform.TransformerException
*/
+ @SuppressWarnings("fallthrough") // by design at case OpCodes.FROM_ROOT
private static boolean isNaturalDocOrder(
Compiler compiler, int stepOpCodePos, int stepIndex, int analysis)
throws javax.xml.transform.TransformerException
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/Lexer.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/Lexer.java Wed Nov 08 16:03:35 2017 -0500
@@ -106,6 +106,7 @@
*
* @throws javax.xml.transform.TransformerException
*/
+ @SuppressWarnings("fallthrough") // on purpose at case '-', '(' and default
void tokenize(String pat, List<String> targetStrings)
throws javax.xml.transform.TransformerException
{
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/patterns/ContextMatchStepPattern.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/patterns/ContextMatchStepPattern.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -65,7 +65,7 @@
if (xctxt.getIteratorRoot() == xctxt.getCurrentNode())
return getStaticScore();
else
- return this.SCORE_NONE;
+ return NodeTest.SCORE_NONE;
}
/**
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/patterns/StepPattern.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/patterns/StepPattern.java Wed Nov 08 16:03:35 2017 -0500
@@ -116,7 +116,7 @@
m_targetString = PsuedoNames.PSEUDONAME_ROOT;
break;
case DTMFilter.SHOW_ELEMENT :
- if (this.WILD == m_name)
+ if (WILD.equals(m_name))
m_targetString = PsuedoNames.PSEUDONAME_ANY;
else
m_targetString = m_name;
--- a/src/java.xml/share/classes/org/xml/sax/helpers/ParserAdapter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/org/xml/sax/helpers/ParserAdapter.java Wed Nov 08 16:03:35 2017 -0500
@@ -586,7 +586,7 @@
// note funky case: localname can be null
// when declaring the default prefix, and
// yet the uri isn't null.
- atts.addAttribute (nsSupport.XMLNS, prefix,
+ atts.addAttribute (NamespaceSupport.XMLNS, prefix,
attQName.intern(), type, value);
else
atts.addAttribute ("", "",
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java Wed Nov 08 16:03:35 2017 -0500
@@ -192,6 +192,8 @@
{"StubRoutines::_checkcast_arraycopy", "_aot_stub_routines_checkcast_arraycopy"},
+ {"StubRoutines::_generic_arraycopy", "_aot_stub_routines_generic_arraycopy"},
+
{"StubRoutines::_aescrypt_encryptBlock", "_aot_stub_routines_aescrypt_encryptBlock"},
{"StubRoutines::_aescrypt_decryptBlock", "_aot_stub_routines_aescrypt_decryptBlock"},
{"StubRoutines::_cipherBlockChaining_encryptAESCrypt", "_aot_stub_routines_cipherBlockChaining_encryptAESCrypt"},
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Wed Nov 08 16:03:35 2017 -0500
@@ -1473,11 +1473,6 @@
d.packge.modle = msym;
}
}
-
- if (!allowAccessIntoSystem && (msym.flags() & Flags.SYSTEM_MODULE) != 0 &&
- msym.patchLocation != null) {
- log.error(Errors.PatchModuleWithRelease(msym));
- }
}
private Set<ModuleSymbol> retrieveRequiresTransitive(ModuleSymbol msym) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Nov 08 16:03:35 2017 -0500
@@ -3126,10 +3126,6 @@
compiler.err.add.reads.with.release=\
adding read edges for system module {0} is not allowed with --release
-# 0: symbol
-compiler.err.patch.module.with.release=\
- patching system module {0} is not allowed in combination with --release
-
compiler.warn.addopens.ignored=\
--add-opens has no effect at compile time
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/BlackholeDirectiveTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/BlackholeDirectiveTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -34,6 +34,9 @@
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
/**
* Tests for {@link GraalDirectives#blackhole}.
@@ -129,6 +132,11 @@
}
@Override
+ protected HighTierContext getDefaultHighTierContext() {
+ return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+ }
+
+ @Override
protected boolean checkLowTierGraph(StructuredGraph graph) {
BlackholeSnippet snippet = graph.method().getAnnotation(BlackholeSnippet.class);
ParameterNode arg = graph.getParameter(0);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/ControlFlowAnchorDirectiveTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/ControlFlowAnchorDirectiveTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -46,6 +46,9 @@
import org.graalvm.compiler.nodes.debug.ControlFlowAnchorNode;
import jdk.vm.ci.meta.ResolvedJavaMethod;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
public class ControlFlowAnchorDirectiveTest extends GraalCompilerTest {
@@ -239,6 +242,11 @@
}
@Override
+ protected HighTierContext getDefaultHighTierContext() {
+ return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+ }
+
+ @Override
protected boolean checkLowTierGraph(StructuredGraph graph) {
List<ControlFlowAnchorNode> anchors = graph.getNodes().filter(ControlFlowAnchorNode.class).snapshot();
for (int i = 0; i < anchors.size(); i++) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/OpaqueDirectiveTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/OpaqueDirectiveTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -37,6 +37,9 @@
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.calc.AddNode;
import org.graalvm.compiler.nodes.calc.ConditionalNode;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
/**
* Tests for {@link GraalDirectives#opaque}.
@@ -128,6 +131,11 @@
}
@Override
+ protected HighTierContext getDefaultHighTierContext() {
+ return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+ }
+
+ @Override
protected boolean checkLowTierGraph(StructuredGraph graph) {
OpaqueSnippet snippet = graph.method().getAnnotation(OpaqueSnippet.class);
for (ReturnNode returnNode : graph.getNodes(ReturnNode.TYPE)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/Snippet.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/Snippet.java Wed Nov 08 16:03:35 2017 -0500
@@ -36,6 +36,13 @@
public @interface Snippet {
/**
+ * A partial intrinsic exits by (effectively) calling the intrinsified method. Normally, this
+ * call must use exactly the same arguments as the call that is being intrinsified. For well
+ * known snippets that are used after frame state assignment, we want to relax this restriction.
+ */
+ boolean allowPartialIntrinsicArgumentMismatch() default false;
+
+ /**
* Denotes a snippet parameter representing 0 or more arguments that will be bound during
* snippet template instantiation. During snippet template creation, its value must be an array
* whose length specifies the number of arguments (the contents of the array are ignored) bound
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,10 +22,14 @@
*/
package org.graalvm.compiler.asm.amd64;
-import static org.graalvm.compiler.core.common.NumUtil.isByte;
-import static org.graalvm.compiler.core.common.NumUtil.isInt;
-import static org.graalvm.compiler.core.common.NumUtil.isShiftCount;
-import static org.graalvm.compiler.core.common.NumUtil.isUByte;
+import static jdk.vm.ci.amd64.AMD64.CPU;
+import static jdk.vm.ci.amd64.AMD64.XMM;
+import static jdk.vm.ci.amd64.AMD64.r12;
+import static jdk.vm.ci.amd64.AMD64.r13;
+import static jdk.vm.ci.amd64.AMD64.rbp;
+import static jdk.vm.ci.amd64.AMD64.rip;
+import static jdk.vm.ci.amd64.AMD64.rsp;
+import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD;
import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseAddressNop;
import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseNormalNop;
import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.ADD;
@@ -47,25 +51,24 @@
import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SD;
import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SS;
import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.WORD;
-import static jdk.vm.ci.amd64.AMD64.CPU;
-import static jdk.vm.ci.amd64.AMD64.XMM;
-import static jdk.vm.ci.amd64.AMD64.r12;
-import static jdk.vm.ci.amd64.AMD64.r13;
-import static jdk.vm.ci.amd64.AMD64.rbp;
-import static jdk.vm.ci.amd64.AMD64.rip;
-import static jdk.vm.ci.amd64.AMD64.rsp;
-import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD;
+import static org.graalvm.compiler.core.common.NumUtil.isByte;
+import static org.graalvm.compiler.core.common.NumUtil.isInt;
+import static org.graalvm.compiler.core.common.NumUtil.isShiftCount;
+import static org.graalvm.compiler.core.common.NumUtil.isUByte;
import org.graalvm.compiler.asm.Assembler;
import org.graalvm.compiler.asm.Label;
+import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
import org.graalvm.compiler.core.common.NumUtil;
-import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
+import org.graalvm.compiler.debug.GraalError;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.amd64.AMD64.CPUFeature;
+import jdk.vm.ci.amd64.AMD64Kind;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.Register.RegisterCategory;
import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.meta.PlatformKind;
/**
* This class implements an assembler that can encode most X86 instructions.
@@ -225,7 +228,7 @@
* The x86 operand sizes.
*/
public enum OperandSize {
- BYTE(1) {
+ BYTE(1, AMD64Kind.BYTE) {
@Override
protected void emitImmediate(AMD64Assembler asm, int imm) {
assert imm == (byte) imm;
@@ -238,7 +241,7 @@
}
},
- WORD(2, 0x66) {
+ WORD(2, AMD64Kind.WORD, 0x66) {
@Override
protected void emitImmediate(AMD64Assembler asm, int imm) {
assert imm == (short) imm;
@@ -251,7 +254,7 @@
}
},
- DWORD(4) {
+ DWORD(4, AMD64Kind.DWORD) {
@Override
protected void emitImmediate(AMD64Assembler asm, int imm) {
asm.emitInt(imm);
@@ -263,7 +266,7 @@
}
},
- QWORD(8) {
+ QWORD(8, AMD64Kind.QWORD) {
@Override
protected void emitImmediate(AMD64Assembler asm, int imm) {
asm.emitInt(imm);
@@ -275,34 +278,35 @@
}
},
- SS(4, 0xF3, true),
-
- SD(8, 0xF2, true),
-
- PS(16, true),
-
- PD(16, 0x66, true);
+ SS(4, AMD64Kind.SINGLE, 0xF3, true),
+
+ SD(8, AMD64Kind.DOUBLE, 0xF2, true),
+
+ PS(16, AMD64Kind.V128_SINGLE, true),
+
+ PD(16, AMD64Kind.V128_DOUBLE, 0x66, true);
private final int sizePrefix;
-
private final int bytes;
private final boolean xmm;
-
- OperandSize(int bytes) {
- this(bytes, 0);
+ private final AMD64Kind kind;
+
+ OperandSize(int bytes, AMD64Kind kind) {
+ this(bytes, kind, 0);
}
- OperandSize(int bytes, int sizePrefix) {
- this(bytes, sizePrefix, false);
+ OperandSize(int bytes, AMD64Kind kind, int sizePrefix) {
+ this(bytes, kind, sizePrefix, false);
}
- OperandSize(int bytes, boolean xmm) {
- this(bytes, 0, xmm);
+ OperandSize(int bytes, AMD64Kind kind, boolean xmm) {
+ this(bytes, kind, 0, xmm);
}
- OperandSize(int bytes, int sizePrefix, boolean xmm) {
+ OperandSize(int bytes, AMD64Kind kind, int sizePrefix, boolean xmm) {
this.sizePrefix = sizePrefix;
this.bytes = bytes;
+ this.kind = kind;
this.xmm = xmm;
}
@@ -314,6 +318,19 @@
return xmm;
}
+ public AMD64Kind getKind() {
+ return kind;
+ }
+
+ public static OperandSize get(PlatformKind kind) {
+ for (OperandSize operandSize : OperandSize.values()) {
+ if (operandSize.kind.equals(kind)) {
+ return operandSize;
+ }
+ }
+ throw GraalError.shouldNotReachHere("Unexpected kind: " + kind.toString());
+ }
+
/**
* Emit an immediate of this size. Note that immediate {@link #QWORD} operands are encoded
* as sign-extended 32-bit values.
@@ -2230,6 +2247,14 @@
emitOperandHelper(dst, src, 0);
}
+ public final void movzbl(Register dst, Register src) {
+ AMD64RMOp.MOVZXB.emit(this, OperandSize.DWORD, dst, src);
+ }
+
+ public final void movzbq(Register dst, Register src) {
+ AMD64RMOp.MOVZXB.emit(this, OperandSize.QWORD, dst, src);
+ }
+
public final void movzwl(Register dst, AMD64Address src) {
prefix(src, dst);
emitByte(0x0F);
@@ -3198,6 +3223,13 @@
emitByte(0xC0 | encode);
}
+ public final void setb(ConditionFlag cc, Register dst) {
+ int encode = prefixAndEncode(dst.encoding, true);
+ emitByte(0x0F);
+ emitByte(0x90 | cc.getValue());
+ emitByte(0xC0 | encode);
+ }
+
public final void cmovq(ConditionFlag cc, Register dst, AMD64Address src) {
prefixq(src, dst);
emitByte(0x0F);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64MacroAssembler.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64MacroAssembler.java Wed Nov 08 16:03:35 2017 -0500
@@ -31,8 +31,8 @@
import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseXmmRegToRegMoveAll;
import org.graalvm.compiler.asm.Label;
+import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
import org.graalvm.compiler.core.common.NumUtil;
-import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.amd64.AMD64Kind;
@@ -281,6 +281,16 @@
}
+ public final void setl(ConditionFlag cc, Register dst) {
+ setb(cc, dst);
+ movzbl(dst, dst);
+ }
+
+ public final void setq(ConditionFlag cc, Register dst) {
+ setb(cc, dst);
+ movzbq(dst, dst);
+ }
+
public final void flog(Register dest, Register value, boolean base10) {
if (base10) {
fldlg2();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64.test/src/org/graalvm/compiler/core/amd64/test/AMD64AddressLoweringTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+package org.graalvm.compiler.core.amd64.test;
+
+import static org.junit.Assume.assumeTrue;
+
+import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
+import org.graalvm.compiler.core.amd64.AMD64AddressLowering;
+import org.graalvm.compiler.core.amd64.AMD64AddressNode;
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.calc.AddNode;
+import org.graalvm.compiler.nodes.calc.LeftShiftNode;
+import org.graalvm.compiler.nodes.calc.NegateNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import jdk.vm.ci.amd64.AMD64;
+
+public class AMD64AddressLoweringTest extends GraalCompilerTest {
+
+ private StructuredGraph graph;
+ private AMD64AddressLowering lowering;
+
+ @Before
+ public void checkAMD64() {
+ assumeTrue("skipping AMD64 specific test", getTarget().arch instanceof AMD64);
+ graph = new StructuredGraph.Builder(getInitialOptions(), getDebugContext()).build();
+ lowering = new AMD64AddressLowering();
+ }
+
+ @Test
+ public void convertBaseAndIndexToDisplacement() {
+ ValueNode base = graph.unique(const64(1000));
+ ValueNode index = graph.unique(const64(10));
+ AddressNode result = lowering.lower(base, index);
+ assertAddress(result, null, null, Scale.Times1, 1010);
+ }
+
+ @Test
+ public void convertBaseToDisplacement() {
+ ValueNode constantAddress = graph.addOrUniqueWithInputs(const64(1000));
+ AddressNode result = lowering.lower(constantAddress, null);
+ assertAddress(result, null, null, Scale.Times1, 1000);
+ }
+
+ @Test
+ public void convertBaseAndShiftedIndexToDisplacement() {
+ ValueNode base = graph.addOrUniqueWithInputs(const64(1000));
+ ValueNode index = graph.addOrUniqueWithInputs(new LeftShiftNode(const64(10), const32(1)));
+ AddressNode result = lowering.lower(base, index);
+ assertAddress(result, null, null, Scale.Times2, 1020);
+ }
+
+ @Test
+ public void convertBaseAndNegatedShiftedIndexToDisplacement() {
+ ValueNode base = graph.addOrUniqueWithInputs(const64(1000));
+ ValueNode index = graph.addOrUniqueWithInputs(new NegateNode(new LeftShiftNode(const64(10), const32(2))));
+ AddressNode result = lowering.lower(base, index);
+ assertAddress(result, null, null, Scale.Times4, 960);
+ }
+
+ @Test
+ public void convertNegatedBaseAndNegatedShiftedIndexToDisplacement() {
+ ValueNode base = graph.addOrUniqueWithInputs(new NegateNode(const64(1000)));
+ ValueNode index = graph.addOrUniqueWithInputs(new NegateNode(new LeftShiftNode(const64(10), const32(2))));
+ AddressNode result = lowering.lower(base, index);
+ assertAddress(result, null, null, Scale.Times4, -1040);
+ }
+
+ @Test
+ public void convertNegatedShiftedBaseAndNegatedIndexToDisplacement() {
+ ValueNode base = graph.addOrUniqueWithInputs(new NegateNode(new LeftShiftNode(const64(10), const32(2))));
+ ValueNode index = graph.addOrUniqueWithInputs(new NegateNode(const64(1000)));
+ AddressNode result = lowering.lower(base, index);
+ assertAddress(result, null, null, Scale.Times4, -1040);
+ }
+
+ @Test
+ public void convertTwoLevelsOfNegatedShiftedBaseAndNegatedIndexToDisplacement() {
+ ValueNode base = graph.addOrUniqueWithInputs(new NegateNode(new LeftShiftNode(new NegateNode(new LeftShiftNode(const64(500), const32(1))), const32(1))));
+ ValueNode index = graph.addOrUniqueWithInputs(new NegateNode(new AddNode(new NegateNode(const64(13)), const64(3))));
+ AddressNode result = lowering.lower(base, index);
+ assertAddress(result, null, null, Scale.Times4, 2010);
+ }
+
+ private static ConstantNode const64(long value) {
+ return ConstantNode.forIntegerBits(Long.SIZE, value);
+ }
+
+ private static ConstantNode const32(long value) {
+ return ConstantNode.forIntegerBits(Integer.SIZE, value);
+ }
+
+ private static void assertAddress(AddressNode actual, ValueNode expectedBase, ValueNode expectedIndex, Scale expectedScale, int expectedDisplacement) {
+ AMD64AddressNode address = (AMD64AddressNode) actual;
+ Assert.assertEquals(expectedBase, address.getBase());
+ Assert.assertEquals(expectedIndex, address.getIndex());
+ Assert.assertEquals(expectedScale, address.getScale());
+ Assert.assertEquals(expectedDisplacement, address.getDisplacement());
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressLowering.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressLowering.java Wed Nov 08 16:03:35 2017 -0500
@@ -23,21 +23,22 @@
package org.graalvm.compiler.core.amd64;
-import jdk.vm.ci.meta.JavaConstant;
-
+import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
import org.graalvm.compiler.core.common.NumUtil;
-import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.AddNode;
import org.graalvm.compiler.nodes.calc.LeftShiftNode;
+import org.graalvm.compiler.nodes.calc.NegateNode;
import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
import org.graalvm.compiler.nodes.memory.address.AddressNode;
import org.graalvm.compiler.phases.common.AddressLoweringPhase.AddressLowering;
+import jdk.vm.ci.meta.JavaConstant;
+
public class AMD64AddressLowering extends AddressLowering {
-
@Override
public AddressNode lower(ValueNode address) {
return lower(address, null);
@@ -46,24 +47,37 @@
@Override
public AddressNode lower(ValueNode base, ValueNode offset) {
AMD64AddressNode ret = new AMD64AddressNode(base, offset);
+ StructuredGraph graph = base.graph();
+
boolean changed;
do {
- changed = improve(base.getDebug(), ret);
+ changed = improve(graph, base.getDebug(), ret, false, false);
} while (changed);
- return base.graph().unique(ret);
+
+ return graph.unique(ret);
}
/**
- * @param debug
+ * Tries to optimize addresses so that they match the AMD64-specific addressing mode better
+ * (base + index * scale + displacement).
+ *
+ * @param graph the current graph
+ * @param debug the current debug context
+ * @param ret the address that should be optimized
+ * @param isBaseNegated determines if the address base is negated. if so, all values that are
+ * extracted from the base will be negated as well
+ * @param isIndexNegated determines if the index is negated. if so, all values that are
+ * extracted from the index will be negated as well
+ * @return true if the address was modified
*/
- protected boolean improve(DebugContext debug, AMD64AddressNode ret) {
- ValueNode newBase = improveInput(ret, ret.getBase(), 0);
+ protected boolean improve(StructuredGraph graph, DebugContext debug, AMD64AddressNode ret, boolean isBaseNegated, boolean isIndexNegated) {
+ ValueNode newBase = improveInput(ret, ret.getBase(), 0, isBaseNegated);
if (newBase != ret.getBase()) {
ret.setBase(newBase);
return true;
}
- ValueNode newIdx = improveInput(ret, ret.getIndex(), ret.getScale().log2);
+ ValueNode newIdx = improveInput(ret, ret.getIndex(), ret.getScale().log2, isIndexNegated);
if (newIdx != ret.getIndex()) {
ret.setIndex(newIdx);
return true;
@@ -83,55 +97,122 @@
}
if (ret.getScale() == Scale.Times1) {
- if (ret.getBase() == null || ret.getIndex() == null) {
- if (ret.getBase() instanceof AddNode) {
- AddNode add = (AddNode) ret.getBase();
- ret.setBase(add.getX());
- ret.setIndex(add.getY());
- return true;
- } else if (ret.getIndex() instanceof AddNode) {
- AddNode add = (AddNode) ret.getIndex();
- ret.setBase(add.getX());
- ret.setIndex(add.getY());
- return true;
- }
+ if (ret.getIndex() == null && ret.getBase() instanceof AddNode) {
+ AddNode add = (AddNode) ret.getBase();
+ ret.setBase(add.getX());
+ ret.setIndex(considerNegation(graph, add.getY(), isBaseNegated));
+ return true;
+ } else if (ret.getBase() == null && ret.getIndex() instanceof AddNode) {
+ AddNode add = (AddNode) ret.getIndex();
+ ret.setBase(considerNegation(graph, add.getX(), isIndexNegated));
+ ret.setIndex(add.getY());
+ return true;
}
if (ret.getBase() instanceof LeftShiftNode && !(ret.getIndex() instanceof LeftShiftNode)) {
ValueNode tmp = ret.getBase();
- ret.setBase(ret.getIndex());
- ret.setIndex(tmp);
+ ret.setBase(considerNegation(graph, ret.getIndex(), isIndexNegated != isBaseNegated));
+ ret.setIndex(considerNegation(graph, tmp, isIndexNegated != isBaseNegated));
return true;
}
}
+ return improveNegation(graph, debug, ret, isBaseNegated, isIndexNegated);
+ }
+
+ private boolean improveNegation(StructuredGraph graph, DebugContext debug, AMD64AddressNode ret, boolean originalBaseNegated, boolean originalIndexNegated) {
+ boolean baseNegated = originalBaseNegated;
+ boolean indexNegated = originalIndexNegated;
+
+ ValueNode originalBase = ret.getBase();
+ ValueNode originalIndex = ret.getIndex();
+
+ if (ret.getBase() instanceof NegateNode) {
+ NegateNode negate = (NegateNode) ret.getBase();
+ ret.setBase(negate.getValue());
+ baseNegated = !baseNegated;
+ }
+
+ if (ret.getIndex() instanceof NegateNode) {
+ NegateNode negate = (NegateNode) ret.getIndex();
+ ret.setIndex(negate.getValue());
+ indexNegated = !indexNegated;
+ }
+
+ if (baseNegated != originalBaseNegated || indexNegated != originalIndexNegated) {
+ ValueNode base = ret.getBase();
+ ValueNode index = ret.getIndex();
+
+ boolean improved = improve(graph, debug, ret, baseNegated, indexNegated);
+ if (baseNegated != originalBaseNegated) {
+ if (base == ret.getBase()) {
+ ret.setBase(originalBase);
+ } else if (ret.getBase() != null) {
+ ret.setBase(graph.maybeAddOrUnique(NegateNode.create(ret.getBase())));
+ }
+ }
+
+ if (indexNegated != originalIndexNegated) {
+ if (index == ret.getIndex()) {
+ ret.setIndex(originalIndex);
+ } else if (ret.getIndex() != null) {
+ ret.setIndex(graph.maybeAddOrUnique(NegateNode.create(ret.getIndex())));
+ }
+ }
+ return improved;
+ } else {
+ assert ret.getBase() == originalBase && ret.getIndex() == originalIndex;
+ }
return false;
}
- private static ValueNode improveInput(AMD64AddressNode address, ValueNode node, int shift) {
+ private static ValueNode considerNegation(StructuredGraph graph, ValueNode value, boolean negate) {
+ if (negate && value != null) {
+ return graph.maybeAddOrUnique(NegateNode.create(value));
+ }
+ return value;
+ }
+
+ private ValueNode improveInput(AMD64AddressNode address, ValueNode node, int shift, boolean negateExtractedDisplacement) {
if (node == null) {
return null;
}
JavaConstant c = node.asJavaConstant();
if (c != null) {
- return improveConstDisp(address, node, c, null, shift);
+ return improveConstDisp(address, node, c, null, shift, negateExtractedDisplacement);
} else {
- if (node.stamp() instanceof IntegerStamp && ((IntegerStamp) node.stamp()).getBits() == 64) {
- if (node instanceof ZeroExtendNode) {
- if (((ZeroExtendNode) node).getInputBits() == 32) {
- /*
- * We can just swallow a zero-extend from 32 bit to 64 bit because the upper
- * half of the register will always be zero.
- */
- return ((ZeroExtendNode) node).getValue();
+ if (node.stamp() instanceof IntegerStamp) {
+ if (node instanceof ZeroExtendNode && (((ZeroExtendNode) node).getInputBits() == 32)) {
+ /*
+ * we can't just swallow all zero-extends as we might encounter something like
+ * the following: ZeroExtend(Add(negativeValue, positiveValue)).
+ *
+ * if we swallow the zero-extend in this case and subsequently optimize the add,
+ * we might end up with a negative value that has less than 64 bits in base or
+ * index. such a value would require sign extension instead of zero-extension
+ * but the backend can only do zero-extension. if we ever want to optimize that
+ * further, we would also need to be careful about over-/underflows.
+ *
+ * furthermore, we also can't swallow zero-extends with less than 32 bits as
+ * most of these values are immediately sign-extended to 32 bit by the backend
+ * (therefore, the subsequent implicit zero-extension to 64 bit won't do what we
+ * expect).
+ */
+ ValueNode value = ((ZeroExtendNode) node).getValue();
+ if (!mightBeOptimized(value)) {
+ // if the value is not optimized further by the address lowering, then we
+ // can safely rely on the backend doing the implicitly zero-extension.
+ return value;
}
- } else if (node instanceof AddNode) {
+ }
+
+ if (node instanceof AddNode) {
AddNode add = (AddNode) node;
if (add.getX().isConstant()) {
- return improveConstDisp(address, node, add.getX().asJavaConstant(), add.getY(), shift);
+ return improveConstDisp(address, node, add.getX().asJavaConstant(), add.getY(), shift, negateExtractedDisplacement);
} else if (add.getY().isConstant()) {
- return improveConstDisp(address, node, add.getY().asJavaConstant(), add.getX(), shift);
+ return improveConstDisp(address, node, add.getY().asJavaConstant(), add.getX(), shift, negateExtractedDisplacement);
}
}
}
@@ -140,15 +221,30 @@
return node;
}
- private static ValueNode improveConstDisp(AMD64AddressNode address, ValueNode original, JavaConstant c, ValueNode other, int shift) {
+ /**
+ * This method returns true for all nodes that might be optimized by the address lowering.
+ */
+ protected boolean mightBeOptimized(ValueNode value) {
+ return value instanceof AddNode || value instanceof LeftShiftNode || value instanceof NegateNode || value instanceof ZeroExtendNode;
+ }
+
+ private static ValueNode improveConstDisp(AMD64AddressNode address, ValueNode original, JavaConstant c, ValueNode other, int shift, boolean negateExtractedDisplacement) {
if (c.getJavaKind().isNumericInteger()) {
- long disp = address.getDisplacement();
- disp += c.asLong() << shift;
- if (NumUtil.isInt(disp)) {
- address.setDisplacement((int) disp);
+ long delta = c.asLong() << shift;
+ if (updateDisplacement(address, delta, negateExtractedDisplacement)) {
return other;
}
}
return original;
}
+
+ protected static boolean updateDisplacement(AMD64AddressNode address, long displacementDelta, boolean negateDelta) {
+ long sign = negateDelta ? -1 : 1;
+ long disp = address.getDisplacement() + displacementDelta * sign;
+ if (NumUtil.isInt(disp)) {
+ address.setDisplacement((int) disp);
+ return true;
+ }
+ return false;
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java Wed Nov 08 16:03:35 2017 -0500
@@ -33,15 +33,17 @@
import static org.graalvm.compiler.lir.LIRValueUtil.asConstantValue;
import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant;
import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
+import static org.graalvm.compiler.lir.LIRValueUtil.isIntConstant;
import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
-import org.graalvm.compiler.core.common.NumUtil;
+import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.core.common.calc.Condition;
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.core.common.spi.LIRKindTool;
@@ -58,13 +60,17 @@
import org.graalvm.compiler.lir.amd64.AMD64AddressValue;
import org.graalvm.compiler.lir.amd64.AMD64ArithmeticLIRGeneratorTool;
import org.graalvm.compiler.lir.amd64.AMD64ArrayEqualsOp;
+import org.graalvm.compiler.lir.amd64.AMD64Binary;
import org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer;
import org.graalvm.compiler.lir.amd64.AMD64ByteSwapOp;
import org.graalvm.compiler.lir.amd64.AMD64Call;
+import org.graalvm.compiler.lir.amd64.AMD64ControlFlow;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.BranchOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.CondMoveOp;
+import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.CondSetOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatBranchOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondMoveOp;
+import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondSetOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.ReturnOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.StrategySwitchOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.TableSwitchOp;
@@ -257,8 +263,7 @@
@Override
public void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) {
- boolean mirrored = emitCompare(cmpKind, left, right);
- Condition finalCondition = mirrored ? cond.mirror() : cond;
+ Condition finalCondition = emitCompare(cmpKind, left, right, cond);
if (cmpKind == AMD64Kind.SINGLE || cmpKind == AMD64Kind.DOUBLE) {
append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability));
} else {
@@ -290,14 +295,60 @@
@Override
public Variable emitConditionalMove(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
- boolean mirrored = emitCompare(cmpKind, left, right);
- Condition finalCondition = mirrored ? cond.mirror() : cond;
+ boolean isFloatComparison = cmpKind == AMD64Kind.SINGLE || cmpKind == AMD64Kind.DOUBLE;
- Variable result = newVariable(trueValue.getValueKind());
- if (cmpKind == AMD64Kind.SINGLE || cmpKind == AMD64Kind.DOUBLE) {
- append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue)));
+ Condition finalCondition = cond;
+ Value finalTrueValue = trueValue;
+ Value finalFalseValue = falseValue;
+ if (isFloatComparison) {
+ // eliminate the parity check in case of a float comparison
+ Value finalLeft = left;
+ Value finalRight = right;
+ if (unorderedIsTrue != AMD64ControlFlow.trueOnUnordered(finalCondition)) {
+ if (unorderedIsTrue == AMD64ControlFlow.trueOnUnordered(finalCondition.mirror())) {
+ finalCondition = finalCondition.mirror();
+ finalLeft = right;
+ finalRight = left;
+ } else if (finalCondition != Condition.EQ && finalCondition != Condition.NE) {
+ // negating EQ and NE does not make any sense as we would need to negate
+ // unorderedIsTrue as well (otherwise, we would no longer fulfill the Java
+ // NaN semantics)
+ assert unorderedIsTrue == AMD64ControlFlow.trueOnUnordered(finalCondition.negate());
+ finalCondition = finalCondition.negate();
+ finalTrueValue = falseValue;
+ finalFalseValue = trueValue;
+ }
+ }
+ emitRawCompare(cmpKind, finalLeft, finalRight);
} else {
- append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue)));
+ finalCondition = emitCompare(cmpKind, left, right, cond);
+ }
+
+ boolean isParityCheckNecessary = isFloatComparison && unorderedIsTrue != AMD64ControlFlow.trueOnUnordered(finalCondition);
+ Variable result = newVariable(finalTrueValue.getValueKind());
+ if (!isParityCheckNecessary && isIntConstant(finalTrueValue, 1) && isIntConstant(finalFalseValue, 0)) {
+ if (isFloatComparison) {
+ append(new FloatCondSetOp(result, finalCondition));
+ } else {
+ append(new CondSetOp(result, finalCondition));
+ }
+ } else if (!isParityCheckNecessary && isIntConstant(finalTrueValue, 0) && isIntConstant(finalFalseValue, 1)) {
+ if (isFloatComparison) {
+ if (unorderedIsTrue == AMD64ControlFlow.trueOnUnordered(finalCondition.negate())) {
+ append(new FloatCondSetOp(result, finalCondition.negate()));
+ } else {
+ append(new FloatCondSetOp(result, finalCondition));
+ Variable negatedResult = newVariable(result.getValueKind());
+ append(new AMD64Binary.ConstOp(AMD64BinaryArithmetic.XOR, OperandSize.get(result.getPlatformKind()), negatedResult, result, 1));
+ result = negatedResult;
+ }
+ } else {
+ append(new CondSetOp(result, finalCondition.negate()));
+ }
+ } else if (isFloatComparison) {
+ append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(finalTrueValue), load(finalFalseValue)));
+ } else {
+ append(new CondMoveOp(result, finalCondition, load(finalTrueValue), loadNonConst(finalFalseValue)));
}
return result;
}
@@ -394,23 +445,21 @@
*
* @param a the left operand of the comparison
* @param b the right operand of the comparison
+ * @param cond the condition of the comparison
* @return true if the left and right operands were switched, false otherwise
*/
- private boolean emitCompare(PlatformKind cmpKind, Value a, Value b) {
- Variable left;
- Value right;
- boolean mirrored;
+ private Condition emitCompare(PlatformKind cmpKind, Value a, Value b, Condition cond) {
if (LIRValueUtil.isVariable(b)) {
- left = load(b);
- right = loadNonConst(a);
- mirrored = true;
+ emitRawCompare(cmpKind, b, a);
+ return cond.mirror();
} else {
- left = load(a);
- right = loadNonConst(b);
- mirrored = false;
+ emitRawCompare(cmpKind, a, b);
+ return cond;
}
- ((AMD64ArithmeticLIRGeneratorTool) arithmeticLIRGen).emitCompareOp((AMD64Kind) cmpKind, left, right);
- return mirrored;
+ }
+
+ private void emitRawCompare(PlatformKind cmpKind, Value left, Value right) {
+ ((AMD64ArithmeticLIRGeneratorTool) arithmeticLIRGen).emitCompareOp((AMD64Kind) cmpKind, load(left), loadNonConst(right));
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRKindTool.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRKindTool.java Wed Nov 08 16:03:35 2017 -0500
@@ -28,7 +28,7 @@
import jdk.vm.ci.amd64.AMD64Kind;
-public class AMD64LIRKindTool implements LIRKindTool {
+public abstract class AMD64LIRKindTool implements LIRKindTool {
@Override
public LIRKind getIntegerKind(int bits) {
@@ -67,12 +67,8 @@
}
@Override
- public LIRKind getNarrowOopKind() {
- return LIRKind.reference(AMD64Kind.DWORD);
- }
+ public abstract LIRKind getNarrowOopKind();
@Override
- public LIRKind getNarrowPointerKind() {
- return LIRKind.value(AMD64Kind.DWORD);
- }
+ public abstract LIRKind getNarrowPointerKind();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/CompressEncoding.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/CompressEncoding.java Wed Nov 08 16:03:35 2017 -0500
@@ -34,14 +34,6 @@
this.shift = shift;
}
- public int compress(long ptr) {
- if (ptr == 0L) {
- return 0;
- } else {
- return (int) ((ptr - base) >>> shift);
- }
- }
-
public boolean hasBase() {
return base != 0;
}
@@ -58,14 +50,6 @@
return shift;
}
- public long uncompress(int ptr) {
- if (ptr == 0) {
- return 0L;
- } else {
- return ((ptr & 0xFFFFFFFFL) << shift) + base;
- }
- }
-
@Override
public String toString() {
return "base: " + base + " shift: " + shift;
@@ -85,8 +69,7 @@
if (obj instanceof CompressEncoding) {
CompressEncoding other = (CompressEncoding) obj;
return base == other.base && shift == other.shift;
- } else {
- return false;
}
+ return false;
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/calc/FloatConvert.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/calc/FloatConvert.java Wed Nov 08 16:03:35 2017 -0500
@@ -25,21 +25,23 @@
import org.graalvm.compiler.debug.GraalError;
public enum FloatConvert {
- F2I(FloatConvertCategory.FloatingPointToInteger),
- D2I(FloatConvertCategory.FloatingPointToInteger),
- F2L(FloatConvertCategory.FloatingPointToInteger),
- D2L(FloatConvertCategory.FloatingPointToInteger),
- I2F(FloatConvertCategory.IntegerToFloatingPoint),
- L2F(FloatConvertCategory.IntegerToFloatingPoint),
- D2F(FloatConvertCategory.FloatingPointToFloatingPoint),
- I2D(FloatConvertCategory.IntegerToFloatingPoint),
- L2D(FloatConvertCategory.IntegerToFloatingPoint),
- F2D(FloatConvertCategory.FloatingPointToFloatingPoint);
+ F2I(FloatConvertCategory.FloatingPointToInteger, 32),
+ D2I(FloatConvertCategory.FloatingPointToInteger, 64),
+ F2L(FloatConvertCategory.FloatingPointToInteger, 32),
+ D2L(FloatConvertCategory.FloatingPointToInteger, 64),
+ I2F(FloatConvertCategory.IntegerToFloatingPoint, 32),
+ L2F(FloatConvertCategory.IntegerToFloatingPoint, 64),
+ D2F(FloatConvertCategory.FloatingPointToFloatingPoint, 64),
+ I2D(FloatConvertCategory.IntegerToFloatingPoint, 32),
+ L2D(FloatConvertCategory.IntegerToFloatingPoint, 64),
+ F2D(FloatConvertCategory.FloatingPointToFloatingPoint, 32);
- private FloatConvertCategory category;
+ private final FloatConvertCategory category;
+ private final int inputBits;
- FloatConvert(FloatConvertCategory category) {
+ FloatConvert(FloatConvertCategory category, int inputBits) {
this.category = category;
+ this.inputBits = inputBits;
}
public FloatConvertCategory getCategory() {
@@ -72,4 +74,8 @@
throw GraalError.shouldNotReachHere();
}
}
+
+ public int getInputBits() {
+ return inputBits;
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/cfg/Loop.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/cfg/Loop.java Wed Nov 08 16:03:35 2017 -0500
@@ -41,7 +41,6 @@
this.parent = parent;
if (parent != null) {
this.depth = parent.getDepth() + 1;
- parent.getChildren().add(this);
} else {
this.depth = 1;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/ArithmeticOpTable.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/ArithmeticOpTable.java Wed Nov 08 16:03:35 2017 -0500
@@ -96,6 +96,22 @@
}
}
+ public BinaryOp<?>[] getBinaryOps() {
+ return new BinaryOp<?>[]{add, sub, mul, mulHigh, umulHigh, div, rem, and, or, xor};
+ }
+
+ public UnaryOp<?>[] getUnaryOps() {
+ return new UnaryOp<?>[]{neg, not, abs, sqrt};
+ }
+
+ public ShiftOp<?>[] getShiftOps() {
+ return new ShiftOp<?>[]{shl, shr, ushr};
+ }
+
+ public IntegerConvertOp<?>[] getIntegerConvertOps() {
+ return new IntegerConvertOp<?>[]{zeroExtend, signExtend, narrow};
+ }
+
public static final ArithmeticOpTable EMPTY = new ArithmeticOpTable(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
public interface ArithmeticOpWrapper {
@@ -562,7 +578,10 @@
}
/**
- * Apply the operation to two {@linkplain Constant Constants}.
+ * Applies this operation to {@code a} and {@code b}.
+ *
+ * @return the result of applying this operation or {@code null} if applying it would raise
+ * an exception (e.g., {@link ArithmeticException} for dividing by 0)
*/
public abstract Constant foldConstant(Constant a, Constant b);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java Wed Nov 08 16:03:35 2017 -0500
@@ -291,7 +291,7 @@
@Override
public JavaConstant asConstant() {
- if (nonNaN && Double.compare(lowerBound, upperBound) == 0) {
+ if (isConstant()) {
switch (getBits()) {
case 32:
return JavaConstant.forFloat((float) lowerBound);
@@ -302,6 +302,68 @@
return null;
}
+ private boolean isConstant() {
+ /*
+ * There are many forms of NaNs and any operations on them can silently convert them into
+ * the canonical NaN.
+ */
+ return (Double.compare(lowerBound, upperBound) == 0 && nonNaN);
+ }
+
+ private static FloatStamp stampForConstant(Constant constant) {
+ FloatStamp result;
+ PrimitiveConstant value = (PrimitiveConstant) constant;
+ switch (value.getJavaKind()) {
+ case Float:
+ if (Float.isNaN(value.asFloat())) {
+ result = new FloatStamp(32, Double.NaN, Double.NaN, false);
+ } else {
+ result = new FloatStamp(32, value.asFloat(), value.asFloat(), !Float.isNaN(value.asFloat()));
+ }
+ break;
+ case Double:
+ if (Double.isNaN(value.asDouble())) {
+ result = new FloatStamp(64, Double.NaN, Double.NaN, false);
+ } else {
+ result = new FloatStamp(64, value.asDouble(), value.asDouble(), !Double.isNaN(value.asDouble()));
+ }
+ break;
+ default:
+ throw GraalError.shouldNotReachHere();
+ }
+ if (result.isConstant()) {
+ return result;
+ }
+ return null;
+ }
+
+ private static Stamp maybeFoldConstant(UnaryOp<?> op, FloatStamp stamp) {
+ if (stamp.isConstant()) {
+ JavaConstant constant = stamp.asConstant();
+ Constant folded = op.foldConstant(constant);
+ if (folded != null) {
+ return FloatStamp.stampForConstant(folded);
+ }
+ }
+ return null;
+ }
+
+ private static Stamp maybeFoldConstant(BinaryOp<?> op, FloatStamp stamp1, FloatStamp stamp2) {
+ if (stamp1.isConstant() && stamp2.isConstant()) {
+ JavaConstant constant1 = stamp1.asConstant();
+ JavaConstant constant2 = stamp2.asConstant();
+ Constant folded = op.foldConstant(constant1, constant2);
+ if (folded != null) {
+ FloatStamp stamp = stampForConstant(folded);
+ if (stamp != null && stamp.isConstant()) {
+ assert stamp.asConstant().equals(folded);
+ return stamp;
+ }
+ }
+ }
+ return null;
+ }
+
public static final ArithmeticOpTable OPS = new ArithmeticOpTable(
new UnaryOp.Neg() {
@@ -322,8 +384,13 @@
@Override
public Stamp foldStamp(Stamp s) {
FloatStamp stamp = (FloatStamp) s;
+ Stamp folded = maybeFoldConstant(this, stamp);
+ if (folded != null) {
+ return folded;
+ }
return new FloatStamp(stamp.getBits(), -stamp.upperBound(), -stamp.lowerBound(), stamp.isNonNaN());
}
+
},
new BinaryOp.Add(false, true) {
@@ -344,8 +411,13 @@
}
@Override
- public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
- // TODO
+ public Stamp foldStamp(Stamp s1, Stamp s2) {
+ FloatStamp stamp1 = (FloatStamp) s1;
+ FloatStamp stamp2 = (FloatStamp) s2;
+ Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+ if (folded != null) {
+ return folded;
+ }
return stamp1.unrestricted();
}
@@ -381,8 +453,13 @@
}
@Override
- public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
- // TODO
+ public Stamp foldStamp(Stamp s1, Stamp s2) {
+ FloatStamp stamp1 = (FloatStamp) s1;
+ FloatStamp stamp2 = (FloatStamp) s2;
+ Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+ if (folded != null) {
+ return folded;
+ }
return stamp1.unrestricted();
}
@@ -418,9 +495,14 @@
}
@Override
- public Stamp foldStamp(Stamp a, Stamp b) {
- // TODO
- return a.unrestricted();
+ public Stamp foldStamp(Stamp s1, Stamp s2) {
+ FloatStamp stamp1 = (FloatStamp) s1;
+ FloatStamp stamp2 = (FloatStamp) s2;
+ Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+ if (folded != null) {
+ return folded;
+ }
+ return stamp1.unrestricted();
}
@Override
@@ -450,17 +532,24 @@
assert a.getJavaKind() == b.getJavaKind();
switch (a.getJavaKind()) {
case Float:
- return JavaConstant.forFloat(a.asFloat() / b.asFloat());
+ float floatDivisor = b.asFloat();
+ return (floatDivisor == 0) ? null : JavaConstant.forFloat(a.asFloat() / floatDivisor);
case Double:
- return JavaConstant.forDouble(a.asDouble() / b.asDouble());
+ double doubleDivisor = b.asDouble();
+ return (doubleDivisor == 0) ? null : JavaConstant.forDouble(a.asDouble() / doubleDivisor);
default:
throw GraalError.shouldNotReachHere();
}
}
@Override
- public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
- // TODO
+ public Stamp foldStamp(Stamp s1, Stamp s2) {
+ FloatStamp stamp1 = (FloatStamp) s1;
+ FloatStamp stamp2 = (FloatStamp) s2;
+ Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+ if (folded != null) {
+ return folded;
+ }
return stamp1.unrestricted();
}
@@ -496,8 +585,13 @@
}
@Override
- public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
- // TODO
+ public Stamp foldStamp(Stamp s1, Stamp s2) {
+ FloatStamp stamp1 = (FloatStamp) s1;
+ FloatStamp stamp2 = (FloatStamp) s2;
+ Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+ if (folded != null) {
+ return folded;
+ }
return stamp1.unrestricted();
}
},
@@ -521,6 +615,17 @@
@Override
public Stamp foldStamp(Stamp s) {
+ FloatStamp stamp = (FloatStamp) s;
+ JavaConstant constant = stamp.asConstant();
+ if (constant != null) {
+ Constant folded = foldConstant(constant);
+ if (folded != null) {
+ FloatStamp result = stampForConstant(folded);
+ if (result != null && result.isConstant()) {
+ return result;
+ }
+ }
+ }
return s.unrestricted();
}
},
@@ -547,7 +652,13 @@
}
@Override
- public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+ public Stamp foldStamp(Stamp s1, Stamp s2) {
+ FloatStamp stamp1 = (FloatStamp) s1;
+ FloatStamp stamp2 = (FloatStamp) s2;
+ Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+ if (folded != null) {
+ return folded;
+ }
return stamp1.unrestricted();
}
@@ -576,7 +687,9 @@
case Float:
int fa = Float.floatToRawIntBits(a.asFloat());
int fb = Float.floatToRawIntBits(b.asFloat());
- return JavaConstant.forFloat(Float.intBitsToFloat(fa | fb));
+ float floatOr = Float.intBitsToFloat(fa | fb);
+ assert (fa | fb) == Float.floatToRawIntBits((floatOr));
+ return JavaConstant.forFloat(floatOr);
case Double:
long da = Double.doubleToRawLongBits(a.asDouble());
long db = Double.doubleToRawLongBits(b.asDouble());
@@ -587,7 +700,13 @@
}
@Override
- public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+ public Stamp foldStamp(Stamp s1, Stamp s2) {
+ FloatStamp stamp1 = (FloatStamp) s1;
+ FloatStamp stamp2 = (FloatStamp) s2;
+ Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+ if (folded != null) {
+ return folded;
+ }
return stamp1.unrestricted();
}
@@ -627,7 +746,13 @@
}
@Override
- public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+ public Stamp foldStamp(Stamp s1, Stamp s2) {
+ FloatStamp stamp1 = (FloatStamp) s1;
+ FloatStamp stamp2 = (FloatStamp) s2;
+ Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+ if (folded != null) {
+ return folded;
+ }
return stamp1.unrestricted();
}
@@ -665,6 +790,10 @@
@Override
public Stamp foldStamp(Stamp s) {
FloatStamp stamp = (FloatStamp) s;
+ Stamp folded = maybeFoldConstant(this, stamp);
+ if (folded != null) {
+ return folded;
+ }
if (stamp.isNaN()) {
return stamp;
}
@@ -689,6 +818,11 @@
@Override
public Stamp foldStamp(Stamp s) {
+ FloatStamp stamp = (FloatStamp) s;
+ Stamp folded = maybeFoldConstant(this, stamp);
+ if (folded != null) {
+ return folded;
+ }
return s.unrestricted();
}
},
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/IntegerStamp.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/IntegerStamp.java Wed Nov 08 16:03:35 2017 -0500
@@ -597,6 +597,10 @@
public Stamp foldStamp(Stamp s) {
IntegerStamp stamp = (IntegerStamp) s;
int bits = stamp.getBits();
+ if (stamp.lowerBound == stamp.upperBound) {
+ long value = CodeUtil.convert(-stamp.lowerBound(), stamp.getBits(), false);
+ return StampFactory.forInteger(stamp.getBits(), value, value);
+ }
if (stamp.lowerBound() != CodeUtil.minValue(bits)) {
// TODO(ls) check if the mask calculation is correct...
return StampFactory.forInteger(bits, -stamp.upperBound(), -stamp.lowerBound());
@@ -624,6 +628,11 @@
int bits = a.getBits();
assert bits == b.getBits();
+ if (a.lowerBound == a.upperBound && b.lowerBound == b.upperBound) {
+ long value = CodeUtil.convert(a.lowerBound() + b.lowerBound(), a.getBits(), false);
+ return StampFactory.forInteger(a.getBits(), value, value);
+ }
+
if (a.isUnrestricted()) {
return a;
} else if (b.isUnrestricted()) {
@@ -711,6 +720,12 @@
int bits = a.getBits();
assert bits == b.getBits();
+
+ if (a.lowerBound == a.upperBound && b.lowerBound == b.upperBound) {
+ long value = CodeUtil.convert(a.lowerBound() * b.lowerBound(), a.getBits(), false);
+ return StampFactory.forInteger(a.getBits(), value, value);
+ }
+
// if a==0 or b==0 result of a*b is always 0
if (a.upMask() == 0) {
return a;
@@ -791,7 +806,7 @@
long maxPosB = b.upperBound();
// multiplication has shift semantics
- long newUpMask = ~CodeUtil.mask(Long.numberOfTrailingZeros(a.upMask) + Long.numberOfTrailingZeros(b.upMask)) & CodeUtil.mask(bits);
+ long newUpMask = ~CodeUtil.mask(Math.min(64, Long.numberOfTrailingZeros(a.upMask) + Long.numberOfTrailingZeros(b.upMask))) & CodeUtil.mask(bits);
if (a.canBePositive()) {
if (b.canBePositive()) {
@@ -1023,6 +1038,9 @@
PrimitiveConstant a = (PrimitiveConstant) const1;
PrimitiveConstant b = (PrimitiveConstant) const2;
assert a.getJavaKind() == b.getJavaKind();
+ if (b.asLong() == 0) {
+ return null;
+ }
return JavaConstant.forIntegerKind(a.getJavaKind(), a.asLong() / b.asLong());
}
@@ -1031,9 +1049,12 @@
IntegerStamp a = (IntegerStamp) stamp1;
IntegerStamp b = (IntegerStamp) stamp2;
assert a.getBits() == b.getBits();
- if (b.isStrictlyPositive()) {
- long newLowerBound = a.lowerBound() / b.upperBound();
- long newUpperBound = a.upperBound() / b.lowerBound();
+ if (a.lowerBound == a.upperBound && b.lowerBound == b.upperBound && b.lowerBound != 0) {
+ long value = CodeUtil.convert(a.lowerBound() / b.lowerBound(), a.getBits(), false);
+ return StampFactory.forInteger(a.getBits(), value, value);
+ } else if (b.isStrictlyPositive()) {
+ long newLowerBound = a.lowerBound() < 0 ? a.lowerBound() / b.lowerBound() : a.lowerBound() / b.upperBound();
+ long newUpperBound = a.upperBound() < 0 ? a.upperBound() / b.upperBound() : a.upperBound() / b.lowerBound();
return StampFactory.forInteger(a.getBits(), newLowerBound, newUpperBound);
} else {
return a.unrestricted();
@@ -1054,6 +1075,9 @@
PrimitiveConstant a = (PrimitiveConstant) const1;
PrimitiveConstant b = (PrimitiveConstant) const2;
assert a.getJavaKind() == b.getJavaKind();
+ if (b.asLong() == 0) {
+ return null;
+ }
return JavaConstant.forIntegerKind(a.getJavaKind(), a.asLong() % b.asLong());
}
@@ -1062,6 +1086,12 @@
IntegerStamp a = (IntegerStamp) stamp1;
IntegerStamp b = (IntegerStamp) stamp2;
assert a.getBits() == b.getBits();
+
+ if (a.lowerBound == a.upperBound && b.lowerBound == b.upperBound && b.lowerBound != 0) {
+ long value = CodeUtil.convert(a.lowerBound() % b.lowerBound(), a.getBits(), false);
+ return StampFactory.forInteger(a.getBits(), value, value);
+ }
+
// zero is always possible
long newLowerBound = Math.min(a.lowerBound(), 0);
long newUpperBound = Math.max(a.upperBound(), 0);
@@ -1364,6 +1394,10 @@
public Stamp foldStamp(Stamp input) {
IntegerStamp stamp = (IntegerStamp) input;
int bits = stamp.getBits();
+ if (stamp.lowerBound == stamp.upperBound) {
+ long value = CodeUtil.convert(Math.abs(stamp.lowerBound()), stamp.getBits(), false);
+ return StampFactory.forInteger(stamp.getBits(), value, value);
+ }
if (stamp.lowerBound() == CodeUtil.minValue(bits)) {
return input.unrestricted();
} else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java Wed Nov 08 16:03:35 2017 -0500
@@ -49,8 +49,8 @@
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
import org.graalvm.compiler.debug.DebugCloseable;
+import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugHandlersFactory;
-import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
@@ -73,6 +73,8 @@
import org.graalvm.compiler.phases.verify.VerifyBailoutUsage;
import org.graalvm.compiler.phases.verify.VerifyCallerSensitiveMethods;
import org.graalvm.compiler.phases.verify.VerifyDebugUsage;
+import org.graalvm.compiler.phases.verify.VerifyGetOptionsUsage;
+import org.graalvm.compiler.phases.verify.VerifyGraphAddUsage;
import org.graalvm.compiler.phases.verify.VerifyInstanceOfUsage;
import org.graalvm.compiler.phases.verify.VerifyUpdateUsages;
import org.graalvm.compiler.phases.verify.VerifyUsageWithEquals;
@@ -381,6 +383,8 @@
new VerifyUpdateUsages().apply(graph, context);
new VerifyBailoutUsage().apply(graph, context);
new VerifyInstanceOfUsage().apply(graph, context);
+ new VerifyGraphAddUsage().apply(graph, context);
+ new VerifyGetOptionsUsage().apply(graph, context);
if (graph.method().isBridge()) {
BridgeMethodUtils.getBridgedMethod(graph.method());
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest14.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ * 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 org.graalvm.compiler.core.test;
+
+import org.graalvm.compiler.graph.iterators.NodeIterable;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.FixedGuardNode;
+import org.graalvm.compiler.nodes.GuardNode;
+import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
+import org.graalvm.compiler.nodes.java.LoadIndexedNode;
+import org.graalvm.compiler.nodes.memory.FloatingReadNode;
+import org.graalvm.compiler.nodes.memory.ReadNode;
+import org.graalvm.compiler.nodes.spi.LoweringTool;
+import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+import org.graalvm.compiler.phases.common.FloatingReadPhase;
+import org.graalvm.compiler.phases.common.IterativeConditionalEliminationPhase;
+import org.graalvm.compiler.phases.common.LoweringPhase;
+import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.junit.Assert;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.DeoptimizationReason;
+
+/**
+ * Check that multiple bounds checks are correctly grouped together.
+ */
+public class ConditionalEliminationTest14 extends ConditionalEliminationTestBase {
+
+ public static void test1Snippet(Object[] args) {
+ Object a5 = args[5];
+ Object a7 = args[7];
+ Object a6 = args[6];
+
+ /*
+ * The order of the conditions matters: The scheduler processes the floating reads for the
+ * array loads in the order of the conditions here, and we want the index 7 access to be
+ * processed before the index 6 access.
+ */
+ if (a5 != null && a7 != null && a6 != null) {
+ sink1 = 1;
+ }
+ sink0 = 0;
+ }
+
+ @Test
+ public void test1() {
+ StructuredGraph graph = parseEager("test1Snippet", AllowAssumptions.YES);
+ CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ PhaseContext context = new PhaseContext(getProviders());
+
+ /* Convert the LoadIndexNode to ReadNode with floating guards. */
+ new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
+ /* Convert the ReadNode to FloatingReadNode. */
+ new FloatingReadPhase().apply(graph);
+ /* Apply the phase that we want to test. */
+ new IterativeConditionalEliminationPhase(canonicalizer, true).apply(graph, context);
+
+ Assert.assertEquals("All guards must be floating", 0, graph.getNodes(FixedGuardNode.TYPE).count());
+ Assert.assertEquals("All array accesses must have been lowered", 0, graph.getNodes().filter(LoadIndexedNode.class).count());
+ Assert.assertEquals("All reads must be floating", 0, graph.getNodes().filter(ReadNode.class).count());
+ Assert.assertEquals("Must have floating reads (3 array accesses, 1 array length)", 4, graph.getNodes().filter(FloatingReadNode.class).count());
+
+ NodeIterable<GuardNode> boundsChecks = graph.getNodes(GuardNode.TYPE).filter(n -> ((GuardNode) n).getReason() == DeoptimizationReason.BoundsCheckException);
+ Assert.assertEquals("Must have only 1 bounds check remaining", 1, boundsChecks.count());
+ LogicNode condition = boundsChecks.first().getCondition();
+ Assert.assertTrue("Bounds check must check for array length 8", condition instanceof IntegerBelowNode && ((IntegerBelowNode) condition).getY().valueEquals(ConstantNode.forInt(8)));
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTestBase.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTestBase.java Wed Nov 08 16:03:35 2017 -0500
@@ -27,12 +27,15 @@
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.nodes.spi.LoweringTool;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.ConditionalEliminationPhase;
import org.graalvm.compiler.phases.common.ConvertDeoptimizeToGuardPhase;
import org.graalvm.compiler.phases.common.IterativeConditionalEliminationPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.graalvm.compiler.phases.schedule.SchedulePhase;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.graalvm.compiler.phases.tiers.PhaseContext;
import org.junit.Assert;
@@ -45,6 +48,15 @@
protected static int sink1;
protected static int sink2;
+ /**
+ * These tests assume all code paths in called routines are reachable so disable removal of dead
+ * code based on method profiles.
+ */
+ @Override
+ protected HighTierContext getDefaultHighTierContext() {
+ return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+ }
+
protected void testConditionalElimination(String snippet, String referenceSnippet) {
testConditionalElimination(snippet, referenceSnippet, false, false);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DumpPathTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+package org.graalvm.compiler.core.test;
+
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.graalvm.compiler.debug.DebugOptions;
+import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.util.EconomicMap;
+import org.junit.Test;
+
+/**
+ * Check that setting the dump path results in files ending up in the right directory with matching
+ * names.
+ */
+public class DumpPathTest extends GraalCompilerTest {
+
+ public static Object snippet() {
+ return new String("snippet");
+ }
+
+ @Test
+ public void testDump() throws IOException {
+ Path dumpDirectoryPath = Files.createTempDirectory("DumpPathTest");
+ String[] extensions = new String[]{".cfg", ".bgv", ".graph-strings"};
+ EconomicMap<OptionKey<?>, Object> overrides = OptionValues.newOptionMap();
+ overrides.put(DebugOptions.DumpPath, dumpDirectoryPath.toString());
+ overrides.put(DebugOptions.PrintGraphFile, true);
+ overrides.put(DebugOptions.PrintCanonicalGraphStrings, true);
+ overrides.put(DebugOptions.Dump, "*");
+
+ // Generate dump files.
+ test(new OptionValues(getInitialOptions(), overrides), "snippet");
+ // Check that Ideal files got created, in the right place.
+ checkForFiles(dumpDirectoryPath, extensions);
+
+ // Clean up the generated files.
+ scrubDirectory(dumpDirectoryPath);
+ }
+
+ /**
+ * Check that the given directory contains file or directory names with all the given
+ * extensions.
+ */
+ private static void checkForFiles(Path directoryPath, String[] extensions) throws IOException {
+ String[] paths = new String[extensions.length];
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(directoryPath)) {
+ for (Path filePath : stream) {
+ String fileName = filePath.getFileName().toString();
+ for (int i = 0; i < extensions.length; i++) {
+ String extension = extensions[i];
+ if (fileName.endsWith(extensions[i])) {
+ assertTrue(paths[i] == null, "multiple files found for %s in %s", extension, directoryPath);
+ paths[i] = fileName.replace(extensions[i], "");
+ }
+ }
+ }
+ }
+ for (int i = 0; i < paths.length; i++) {
+ assertTrue(paths[i] != null, "missing file for extension %s in %s", extensions[i], directoryPath);
+ }
+ // Ensure that all file names are the same.
+ for (int i = 1; i < paths.length; i++) {
+ assertTrue(paths[0].equals(paths[i]), paths[0] + " != " + paths[i]);
+ }
+ }
+
+ /**
+ * Remove the temporary directory.
+ */
+ private static void scrubDirectory(Path directoryPath) {
+ try {
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(directoryPath)) {
+ for (Path filePath : stream) {
+ if (Files.isRegularFile(filePath)) {
+ Files.delete(filePath);
+ } else if (Files.isDirectory(filePath)) {
+ scrubDirectory(filePath);
+ }
+ }
+ }
+ Files.delete(directoryPath);
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FinalizableSubclassTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FinalizableSubclassTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -72,7 +72,7 @@
Assert.assertTrue(constructors.length == 1);
final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(constructors[0]);
OptionValues options = getInitialOptions();
- StructuredGraph graph = new StructuredGraph.Builder(options, getDebugContext(options), allowAssumptions).method(javaMethod).build();
+ StructuredGraph graph = new StructuredGraph.Builder(options, getDebugContext(options, null, javaMethod), allowAssumptions).method(javaMethod).build();
GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(getDefaultGraphBuilderPlugins());
new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), getProviders().getConstantFieldProvider(), conf,
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -389,7 +389,7 @@
* {@link DebugDumpHandler}s closed in {@link #afterTest()}.
*/
protected DebugContext getDebugContext() {
- return getDebugContext(getInitialOptions());
+ return getDebugContext(getInitialOptions(), null, null);
}
@Override
@@ -862,7 +862,7 @@
Result actual = executeActual(options, method, receiver, args);
profile = method.getProfilingInfo(); // profile can change after execution
for (DeoptimizationReason reason : shouldNotDeopt) {
- Assert.assertEquals((int) deoptCounts.get(reason), profile.getDeoptimizationCount(reason));
+ Assert.assertEquals("wrong number of deopt counts for " + reason, (int) deoptCounts.get(reason), profile.getDeoptimizationCount(reason));
}
return actual;
}
@@ -1216,15 +1216,15 @@
protected final Builder builder(ResolvedJavaMethod method, AllowAssumptions allowAssumptions) {
OptionValues options = getInitialOptions();
- return new Builder(options, getDebugContext(options), allowAssumptions).method(method).compilationId(getCompilationId(method));
+ return new Builder(options, getDebugContext(options, null, method), allowAssumptions).method(method).compilationId(getCompilationId(method));
}
protected final Builder builder(ResolvedJavaMethod method, AllowAssumptions allowAssumptions, CompilationIdentifier compilationId, OptionValues options) {
- return new Builder(options, getDebugContext(options), allowAssumptions).method(method).compilationId(compilationId);
+ return new Builder(options, getDebugContext(options, compilationId.toString(CompilationIdentifier.Verbosity.ID), method), allowAssumptions).method(method).compilationId(compilationId);
}
protected final Builder builder(ResolvedJavaMethod method, AllowAssumptions allowAssumptions, OptionValues options) {
- return new Builder(options, getDebugContext(options), allowAssumptions).method(method).compilationId(getCompilationId(method));
+ return new Builder(options, getDebugContext(options, null, method), allowAssumptions).method(method).compilationId(getCompilationId(method));
}
protected PhaseSuite<HighTierContext> getDebugGraphBuilderSuite() {
@@ -1234,6 +1234,7 @@
@SuppressWarnings("try")
protected StructuredGraph parse(StructuredGraph.Builder builder, PhaseSuite<HighTierContext> graphBuilderSuite) {
ResolvedJavaMethod javaMethod = builder.getMethod();
+ builder.speculationLog(getSpeculationLog());
if (builder.getCancellable() == null) {
builder.cancellable(getCancellable(javaMethod));
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalDebugHandlersFactoryTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalDebugHandlersFactoryTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -31,8 +31,12 @@
import java.nio.file.Paths;
import java.util.Comparator;
-import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
+import org.graalvm.compiler.debug.DebugOptions;
+import org.graalvm.compiler.debug.PathUtilities;
+import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.test.AddExports;
+import org.junit.Assume;
import org.junit.Test;
@AddExports("jdk.internal.vm.compiler/org.graalvm.compiler.printer")
@@ -40,23 +44,28 @@
@Test
public void createUniqueTest() throws Exception {
- Field maxFileNameLengthField = GraalDebugHandlersFactory.class.getDeclaredField("MAX_FILE_NAME_LENGTH");
- maxFileNameLengthField.setAccessible(true);
+ Field maxFileNameLengthField = PathUtilities.class.getDeclaredField("MAX_FILE_NAME_LENGTH");
+ try {
+ maxFileNameLengthField.setAccessible(true);
+ } catch (RuntimeException ex) {
+ Assume.assumeFalse("If InaccessibleObjectException is thrown, skip the test, we are on JDK9", ex.getClass().getSimpleName().equals("InaccessibleObjectException"));
+ }
int maxFileNameLength = maxFileNameLengthField.getInt(null);
- Method createUniqueMethod = GraalDebugHandlersFactory.class.getDeclaredMethod("createUnique", Path.class, String.class, String.class, String.class, boolean.class);
+ Method createUniqueMethod = PathUtilities.class.getDeclaredMethod("createUnique", OptionValues.class, OptionKey.class, String.class, String.class, String.class, boolean.class);
createUniqueMethod.setAccessible(true);
Path tmpDir = Files.createTempDirectory(Paths.get("."), "createUniqueTest");
+ OptionValues options = new OptionValues(OptionValues.asMap(DebugOptions.DumpPath, tmpDir.toString()));
try {
for (boolean createDirectory : new boolean[]{true, false}) {
for (String ext : new String[]{"", ".bgv", ".graph-strings"}) {
for (int i = 0; i < maxFileNameLength + 5; i++) {
String id = new String(new char[i]).replace('\0', 'i');
String label = "";
- createUniqueMethod.invoke(null, tmpDir, id, label, ext, createDirectory);
+ createUniqueMethod.invoke(null, options, null, id, label, ext, createDirectory);
id = "";
label = new String(new char[i]).replace('\0', 'l');
- createUniqueMethod.invoke(null, tmpDir, id, label, ext, createDirectory);
+ createUniqueMethod.invoke(null, options, null, id, label, ext, createDirectory);
}
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GuardedIntrinsicTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GuardedIntrinsicTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -144,6 +144,11 @@
public void test01() {
Super inheritsHC = new Super();
Person overridesHC = new Person(0);
+
+ // Ensure the profile for getSuperAge includes both receiver types
+ getSuperAge(inheritsHC);
+ getSuperAge(overridesHC);
+
test("getSuperAge", inheritsHC);
test("getSuperAge", overridesHC);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/HashCodeTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/HashCodeTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,6 +22,8 @@
*/
package org.graalvm.compiler.core.test;
+import java.util.HashMap;
+
import org.graalvm.compiler.core.phases.HighTier;
import org.graalvm.compiler.core.phases.MidTier;
import org.graalvm.compiler.nodes.InvokeNode;
@@ -139,6 +141,10 @@
public void test08() {
initialize(Appendable.class);
checkForGuardedIntrinsicPattern("hashCodeInterface");
+
+ // Ensure the profile for the dispatch in hashCodeSnippet01
+ // has a receiver type that does not select Object.hashCode intrinsic
+ hashCodeSnippet01(new HashMap<>());
checkForGuardedIntrinsicPattern("hashCodeSnippet01");
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MarkUnsafeAccessTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MarkUnsafeAccessTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -25,6 +25,7 @@
import static java.nio.file.StandardOpenOption.READ;
import static java.nio.file.StandardOpenOption.WRITE;
+import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
@@ -33,22 +34,20 @@
import java.nio.file.Files;
import java.nio.file.Path;
-import jdk.vm.ci.code.InstalledCode;
-import jdk.vm.ci.code.InvalidInstalledCodeException;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.ResolvedJavaType;
-
-import org.junit.Assert;
-import org.junit.Assume;
-import org.junit.Test;
-
-import sun.misc.Unsafe;
-
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.inlining.InliningPhase;
import org.graalvm.compiler.phases.common.inlining.policy.InlineEverythingPolicy;
import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.code.InvalidInstalledCodeException;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import sun.misc.Unsafe;
public class MarkUnsafeAccessTest extends GraalCompilerTest {
@@ -170,7 +169,9 @@
try {
mbb.position(BLOCK_SIZE);
getter.get(mbb);
- System.currentTimeMillis(); // materialize async exception
+
+ // Make a call that goes into native code to materialize async exception
+ new File("").exists();
} catch (InternalError e) {
return;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MergeCanonicalizerTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MergeCanonicalizerTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -26,12 +26,23 @@
import org.graalvm.compiler.nodes.ReturnNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.graalvm.compiler.phases.tiers.PhaseContext;
import org.junit.Test;
public class MergeCanonicalizerTest extends GraalCompilerTest {
+ /**
+ * These tests assume all code paths are reachable so disable profile based dead code removal.
+ */
+ @Override
+ protected HighTierContext getDefaultHighTierContext() {
+ return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+ }
+
public static int staticField;
private int field;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ProfilingInfoTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ProfilingInfoTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -24,15 +24,17 @@
import java.io.Serializable;
+import org.graalvm.compiler.test.SubprocessUtil;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+
import jdk.vm.ci.meta.JavaTypeProfile;
import jdk.vm.ci.meta.ProfilingInfo;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.TriState;
-import org.junit.Assert;
-import org.junit.Test;
-
/**
* Tests profiling information provided by the runtime.
* <p>
@@ -40,7 +42,7 @@
* information may be gathered for any given method. For example, HotSpot's advanced compilation
* policy can decide to only gather partial profiles in a first level compilation (see
* AdvancedThresholdPolicy::common(...) in advancedThresholdPolicy.cpp). Because of this,
- * occasionally tests for {@link ProfilingInfo#getNullSeen(int)} can fail since HotSpot only set's
+ * occasionally tests for {@link ProfilingInfo#getNullSeen(int)} can fail since HotSpot only sets
* the null_seen bit when doing full profiling.
*/
public class ProfilingInfoTest extends GraalCompilerTest {
@@ -182,6 +184,14 @@
Assert.assertNull(typeProfile);
}
+ public ProfilingInfoTest() {
+ // These tests are explicitly testing the profiling behavior of the
+ // interpreter. C1-based profiling differs slightly and when -Xcomp
+ // is present, profiles will be created by C1 compiled code, not the
+ // interpreter.
+ Assume.assumeTrue(!SubprocessUtil.getVMCommandLine().contains("-Xcomp"));
+ }
+
@Test
public void testExceptionSeen() {
// NullPointerException
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SubWordReturnTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+package org.graalvm.compiler.core.test;
+
+import java.util.ArrayList;
+import java.util.List;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+@RunWith(Parameterized.class)
+public class SubWordReturnTest extends GraalCompilerTest {
+
+ private final JavaKind kind;
+ private final int value;
+
+ private final String generatedClassName;
+ private final String generatedClassNameInternal;
+
+ private final String testMethodName;
+
+ /**
+ * The {@link AsmLoader} generates a class looking like this for the types byte, short, int and
+ * char.
+ */
+ static class ByteGetter {
+
+ // private static int intField = 1000000;
+
+ private static byte get() {
+ // GETSTATIC intField
+ // IRETURN
+ return 0;
+ }
+
+ public static int testByteSnippet() {
+ return get();
+ }
+ }
+
+ @Parameters(name = "{0}, {1}")
+ public static List<Object[]> data() {
+ ArrayList<Object[]> ret = new ArrayList<>();
+ for (int i : new int[]{1000000, 1000001, -1000000, -1}) {
+ ret.add(new Object[]{JavaKind.Boolean, i});
+ ret.add(new Object[]{JavaKind.Byte, i});
+ ret.add(new Object[]{JavaKind.Short, i});
+ ret.add(new Object[]{JavaKind.Char, i});
+ }
+ return ret;
+ }
+
+ public SubWordReturnTest(JavaKind kind, int value) {
+ this.kind = kind;
+ this.value = value;
+
+ this.generatedClassName = SubWordReturnTest.class.getName() + "$" + kind.toString() + "Getter";
+ this.generatedClassNameInternal = generatedClassName.replace('.', '/');
+ this.testMethodName = "test" + kind.name() + "Snippet";
+ }
+
+ @Test
+ public void test() throws ClassNotFoundException {
+ Class<?> testClass = new AsmLoader(SubWordReturnTest.class.getClassLoader()).findClass(generatedClassName);
+ ResolvedJavaMethod method = getResolvedJavaMethod(testClass, testMethodName);
+ test(method, null);
+ }
+
+ class AsmLoader extends ClassLoader implements Opcodes {
+
+ Class<?> loaded;
+
+ AsmLoader(ClassLoader parent) {
+ super(parent);
+ }
+
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ if (name.equals(generatedClassName)) {
+ if (loaded == null) {
+ byte[] gen = generateClass();
+ loaded = defineClass(name, gen, 0, gen.length);
+ }
+ return loaded;
+ } else {
+ return super.findClass(name);
+ }
+ }
+
+ private byte[] generateClass() {
+ ClassWriter cw = new ClassWriter(0);
+ cw.visit(52, ACC_SUPER | ACC_PUBLIC, generatedClassNameInternal, null, "java/lang/Object", null);
+
+ FieldVisitor intField = cw.visitField(ACC_PRIVATE | ACC_STATIC, "intField", "I", null, value);
+ intField.visitEnd();
+
+ MethodVisitor get = cw.visitMethod(ACC_PRIVATE | ACC_STATIC, "get", "()" + kind.getTypeChar(), null, null);
+ get.visitCode();
+ get.visitFieldInsn(GETSTATIC, generatedClassNameInternal, "intField", "I");
+ get.visitInsn(IRETURN);
+ get.visitMaxs(1, 0);
+ get.visitEnd();
+
+ MethodVisitor snippet = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, testMethodName, "()I", null, null);
+ snippet.visitCode();
+ snippet.visitMethodInsn(INVOKESTATIC, generatedClassNameInternal, "get", "()" + kind.getTypeChar(), false);
+ snippet.visitInsn(IRETURN);
+ snippet.visitMaxs(1, 0);
+ snippet.visitEnd();
+
+ cw.visitEnd();
+ return cw.toByteArray();
+ }
+ }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnbalancedMonitorsTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnbalancedMonitorsTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -87,7 +87,7 @@
ResolvedJavaMethod method = getResolvedJavaMethod(LOADER.findClass(INNER_CLASS_NAME), name);
try {
OptionValues options = getInitialOptions();
- StructuredGraph graph = new StructuredGraph.Builder(options, getDebugContext(options)).method(method).build();
+ StructuredGraph graph = new StructuredGraph.Builder(options, getDebugContext(options, null, method)).method(method).build();
Plugins plugins = new Plugins(new InvocationPlugins());
GraphBuilderConfiguration graphBuilderConfig = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true).withUnresolvedIsError(true);
OptimisticOptimizations optimisticOpts = OptimisticOptimizations.NONE;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeVirtualizationTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeVirtualizationTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -32,9 +32,20 @@
import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
import org.junit.Test;
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
public class UnsafeVirtualizationTest extends GraalCompilerTest {
- public static class A {
+ public static class Base {
+ /*
+ * This padding ensure that the size of the Base class ends up as a multiple of 8, which
+ * makes the first field of the subclass 8-byte aligned.
+ */
+ double padding;
+ }
+
+ public static class A extends Base {
int f1;
int f2;
}
@@ -56,39 +67,96 @@
AF2Offset = o2;
}
- public static int unsafeSnippet0(int i1, int i2) {
+ public static int unsafeSnippet1(double i1) {
A a = new A();
- UNSAFE.putDouble(a, AF1Offset, i1 + i2);
+ UNSAFE.putDouble(a, AF1Offset, i1);
return UNSAFE.getInt(a, AF1Offset) + UNSAFE.getInt(a, AF2Offset);
}
- public static int unsafeSnippet1(int i1, int i2) {
+ public static long unsafeSnippet2a(int i1) {
+ A a = new A();
+ UNSAFE.putDouble(a, AF1Offset, i1);
+ a.f1 = i1;
+ return UNSAFE.getLong(a, AF1Offset);
+ }
+
+ public static long unsafeSnippet2b(int i1) {
+ A a = new A();
+ UNSAFE.putDouble(a, AF1Offset, i1);
+ a.f2 = i1;
+ return UNSAFE.getLong(a, AF1Offset);
+ }
+
+ public static long unsafeSnippet3a(int i1) {
A a = new A();
- UNSAFE.putDouble(a, AF1Offset, i1 + i2);
- a.f2 = i1;
- return (int) UNSAFE.getDouble(a, AF1Offset);
+ UNSAFE.putDouble(a, AF1Offset, i1);
+ UNSAFE.putInt(a, AF1Offset, i1);
+ return UNSAFE.getLong(a, AF1Offset);
+ }
+
+ public static long unsafeSnippet3b(int i1) {
+ A a = new A();
+ UNSAFE.putDouble(a, AF1Offset, i1);
+ UNSAFE.putInt(a, AF2Offset, i1);
+ return UNSAFE.getLong(a, AF1Offset);
+ }
+
+ public static int unsafeSnippet4(double i1) {
+ A a = new A();
+ UNSAFE.putDouble(a, AF1Offset, i1);
+ UNSAFE.putDouble(a, AF1Offset, i1);
+ return UNSAFE.getInt(a, AF1Offset) + UNSAFE.getInt(a, AF2Offset);
}
@Test
public void testUnsafePEA01() {
- testPartialEscapeReadElimination(parseEager("unsafeSnippet0", AllowAssumptions.NO), false);
- testPartialEscapeReadElimination(parseEager("unsafeSnippet0", AllowAssumptions.NO), true);
+ testPartialEscapeReadElimination("unsafeSnippet1", false, 1.0);
+ testPartialEscapeReadElimination("unsafeSnippet1", true, 1.0);
}
@Test
public void testUnsafePEA02() {
- testPartialEscapeReadElimination(parseEager("unsafeSnippet1", AllowAssumptions.NO), false);
- testPartialEscapeReadElimination(parseEager("unsafeSnippet1", AllowAssumptions.NO), true);
+ testPartialEscapeReadElimination("unsafeSnippet2a", false, 1);
+ testPartialEscapeReadElimination("unsafeSnippet2a", true, 1);
+
+ testPartialEscapeReadElimination("unsafeSnippet2b", false, 1);
+ testPartialEscapeReadElimination("unsafeSnippet2b", true, 1);
}
- public void testPartialEscapeReadElimination(StructuredGraph graph, boolean canonicalizeBefore) {
+ @Test
+ public void testUnsafePEA03() {
+ testPartialEscapeReadElimination("unsafeSnippet3a", false, 1);
+ testPartialEscapeReadElimination("unsafeSnippet3a", true, 1);
+
+ testPartialEscapeReadElimination("unsafeSnippet3b", false, 1);
+ testPartialEscapeReadElimination("unsafeSnippet3b", true, 1);
+ }
+
+ @Test
+ public void testUnsafePEA04() {
+ testPartialEscapeReadElimination("unsafeSnippet4", false, 1.0);
+ testPartialEscapeReadElimination("unsafeSnippet4", true, 1.0);
+ }
+
+ public void testPartialEscapeReadElimination(String snippet, boolean canonicalizeBefore, Object... args) {
+ assert AF1Offset % 8 == 0 : "First of the two int-fields must be 8-byte aligned";
+
+ ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
+ StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
OptionValues options = graph.getOptions();
PhaseContext context = getDefaultHighTierContext();
CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
if (canonicalizeBefore) {
canonicalizer.apply(graph, context);
}
+ Result r = executeExpected(method, null, args);
new PartialEscapePhase(true, true, canonicalizer, null, options).apply(graph, context);
+ try {
+ InstalledCode code = getCode(method, graph);
+ Object result = code.executeVarargs(args);
+ assertEquals(r, new Result(result, null));
+ } catch (Throwable e) {
+ assertFalse(true, e.toString());
+ }
}
-
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java Wed Nov 08 16:03:35 2017 -0500
@@ -77,7 +77,7 @@
@Override
public String toString() {
- return "{" + x + "," + y + "}";
+ return "{" + x + "," + y + "," + z + "}";
}
@Override
@@ -158,11 +158,19 @@
context = getDefaultHighTierContext();
new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
new DeadCodeEliminationPhase().apply(graph);
- new CanonicalizerPhase().apply(graph, context);
+ canonicalizeGraph();
new PartialEscapePhase(iterativeEscapeAnalysis, false, new CanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
+ postEACanonicalizeGraph();
returnNodes = graph.getNodes(ReturnNode.TYPE).snapshot();
} catch (Throwable e) {
throw debug.handle(e);
}
}
+
+ protected void postEACanonicalizeGraph() {
+ }
+
+ protected void canonicalizeGraph() {
+ new CanonicalizerPhase().apply(graph, context);
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PEAAssertionsTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PEAAssertionsTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -27,9 +27,20 @@
import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.code.SourceStackTraceBailoutException;
import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
public class PEAAssertionsTest extends GraalCompilerTest {
+ /**
+ * These tests assume all code paths are reachable so disable profile based dead code removal.
+ */
+ @Override
+ protected HighTierContext getDefaultHighTierContext() {
+ return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+ }
+
public static Object field;
public static void snippet1(int i) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/TrufflePEATest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/TrufflePEATest.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,6 +22,8 @@
*/
package org.graalvm.compiler.core.test.ea;
+import java.lang.reflect.Field;
+
import org.graalvm.compiler.core.common.GraalOptions;
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.nodes.StructuredGraph;
@@ -33,10 +35,9 @@
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
import org.junit.Test;
+
import sun.misc.Unsafe;
-import java.lang.reflect.Field;
-
public class TrufflePEATest extends GraalCompilerTest {
/**
@@ -56,6 +57,7 @@
static class DynamicObject {
int primitiveField0;
int primitiveField1;
+ int primitiveField2;
}
private static final long offsetLong1 = Unsafe.ARRAY_LONG_BASE_OFFSET + Unsafe.ARRAY_LONG_INDEX_SCALE * 1;
@@ -66,7 +68,15 @@
static {
try {
Field primitiveField0 = DynamicObject.class.getDeclaredField("primitiveField0");
- primitiveField0Offset = UNSAFE.objectFieldOffset(primitiveField0);
+ long offset = UNSAFE.objectFieldOffset(primitiveField0);
+ if (offset % 8 == 0) {
+ primitiveField0Offset = offset;
+ } else {
+ Field primitiveField1 = DynamicObject.class.getDeclaredField("primitiveField1");
+ offset = UNSAFE.objectFieldOffset(primitiveField1);
+ assert offset % 8 == 0;
+ primitiveField0Offset = offset;
+ }
} catch (NoSuchFieldException | SecurityException e) {
throw new AssertionError(e);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/UnsafeEATest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/UnsafeEATest.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,14 +22,26 @@
*/
package org.graalvm.compiler.core.test.ea;
-import jdk.vm.ci.meta.JavaConstant;
+import java.nio.ByteBuffer;
+import org.graalvm.compiler.api.directives.GraalDirectives;
+import org.graalvm.compiler.graph.Graph;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.PhiNode;
+import org.graalvm.compiler.nodes.ValuePhiNode;
+import org.graalvm.compiler.nodes.calc.UnpackEndianHalfNode;
+import org.graalvm.compiler.nodes.extended.RawLoadNode;
+import org.graalvm.compiler.nodes.extended.RawStoreNode;
+import org.graalvm.compiler.nodes.extended.UnsafeAccessNode;
+import org.graalvm.compiler.nodes.java.LoadFieldNode;
+import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Assert;
import org.junit.Test;
-import org.graalvm.compiler.nodes.PhiNode;
-import org.graalvm.compiler.nodes.ValuePhiNode;
-import org.graalvm.compiler.nodes.java.LoadFieldNode;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
public class UnsafeEATest extends EATestBase {
@@ -56,6 +68,64 @@
}
}
+ @Override
+ protected void testEscapeAnalysis(String snippet, JavaConstant expectedConstantResult, boolean iterativeEscapeAnalysis) {
+ // Exercise both a graph containing UnsafeAccessNodes and one which has been possibly been
+ // canonicalized into AccessFieldNodes.
+ testingUnsafe = true;
+ super.testEscapeAnalysis(snippet, expectedConstantResult, iterativeEscapeAnalysis);
+ testingUnsafe = false;
+ super.testEscapeAnalysis(snippet, expectedConstantResult, iterativeEscapeAnalysis);
+ if (expectedConstantResult != null) {
+ // Check that a compiled version of this method returns the same value if we expect a
+ // constant result.
+ ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
+ JavaKind[] javaKinds = method.getSignature().toParameterKinds(false);
+ Object[] args = new Object[javaKinds.length];
+ int i = 0;
+ for (JavaKind k : javaKinds) {
+ args[i++] = JavaConstant.defaultForKind(k).asBoxedPrimitive();
+ }
+ Result result = executeExpected(method, null, args);
+ assertTrue(result.returnValue.equals(expectedConstantResult.asBoxedPrimitive()));
+ }
+ }
+
+ @Override
+ protected void canonicalizeGraph() {
+ if (testingUnsafe) {
+ // For testing purposes we'd like to ensure that our raw unsafe operations stay as
+ // unsafe nodes, so force them to appear to have LocationIdentity.any to disable
+ // transformation into field access nodes.
+ for (Node node : graph.getNodes().filter(x -> x instanceof UnsafeAccessNode).snapshot()) {
+ if (node instanceof RawStoreNode) {
+ RawStoreNode store = (RawStoreNode) node;
+ RawStoreNode newStore = graph.add(new RawStoreNode(store.object(), store.offset(), store.value(), store.accessKind(), NamedLocationIdentity.any(),
+ store.needsBarrier(), store.stateAfter(), true));
+ graph.replaceFixedWithFixed(store, newStore);
+ } else if (node instanceof RawLoadNode) {
+ RawLoadNode load = (RawLoadNode) node;
+ RawLoadNode newLoad = graph.add(new RawLoadNode(load.object(), load.offset(), load.accessKind(), NamedLocationIdentity.any(),
+ true));
+ graph.replaceFixedWithFixed(load, newLoad);
+ }
+ }
+ }
+ super.canonicalizeGraph();
+ }
+
+ @Override
+ protected void postEACanonicalizeGraph() {
+ // Simplify any UnpackEndianHalfNode so we end up with constants.
+ Graph.Mark mark = graph.getMark();
+ for (UnpackEndianHalfNode node : graph.getNodes().filter(UnpackEndianHalfNode.class)) {
+ node.lower(getTarget().arch.getByteOrder());
+ }
+ new CanonicalizerPhase().applyIncremental(graph, context, mark);
+ }
+
+ private boolean testingUnsafe;
+
@Test
public void testSimpleInt() {
testEscapeAnalysis("testSimpleIntSnippet", JavaConstant.forInt(101), false);
@@ -90,6 +160,82 @@
}
@Test
+ public void testSimpleDoubleOverwriteWithInt() {
+ testEscapeAnalysis("testSimpleDoubleOverwriteWithIntSnippet", JavaConstant.forInt(10), false);
+ }
+
+ public static int testSimpleDoubleOverwriteWithIntSnippet() {
+ TestClassInt x = new TestClassInt();
+ UNSAFE.putDouble(x, fieldOffset1, 10.1);
+ UNSAFE.putInt(x, fieldOffset1, 10);
+ return UNSAFE.getInt(x, fieldOffset1);
+ }
+
+ @Test
+ public void testSimpleDoubleOverwriteWithSecondInt() {
+ ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder());
+ bb.putDouble(10.1);
+ int value = bb.getInt(4);
+
+ testEscapeAnalysis("testSimpleDoubleOverwriteWithSecondIntSnippet", JavaConstant.forInt(value), false);
+ }
+
+ public static int testSimpleDoubleOverwriteWithSecondIntSnippet() {
+ TestClassInt x = new TestClassInt();
+ UNSAFE.putDouble(x, fieldOffset1, 10.1);
+ UNSAFE.putInt(x, fieldOffset1, 10);
+ return UNSAFE.getInt(x, fieldOffset2);
+ }
+
+ @Test
+ public void testSimpleDoubleOverwriteWithFirstInt() {
+ ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder());
+ bb.putDouble(10.1);
+ int value = bb.getInt(0);
+
+ testEscapeAnalysis("testSimpleDoubleOverwriteWithFirstIntSnippet", JavaConstant.forInt(value), false);
+ }
+
+ public static int testSimpleDoubleOverwriteWithFirstIntSnippet() {
+ TestClassInt x = new TestClassInt();
+ UNSAFE.putDouble(x, fieldOffset1, 10.1);
+ UNSAFE.putInt(x, fieldOffset2, 10);
+ return UNSAFE.getInt(x, fieldOffset1);
+ }
+
+ @Test
+ public void testSimpleLongOverwriteWithSecondInt() {
+ ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder());
+ bb.putLong(0, 0x1122334455667788L);
+ int value = bb.getInt(4);
+
+ testEscapeAnalysis("testSimpleLongOverwriteWithSecondIntSnippet", JavaConstant.forInt(value), false);
+ }
+
+ public static int testSimpleLongOverwriteWithSecondIntSnippet() {
+ TestClassInt x = new TestClassInt();
+ UNSAFE.putLong(x, fieldOffset1, 0x1122334455667788L);
+ UNSAFE.putInt(x, fieldOffset1, 10);
+ return UNSAFE.getInt(x, fieldOffset2);
+ }
+
+ @Test
+ public void testSimpleLongOverwriteWithFirstInt() {
+ ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder());
+ bb.putLong(0, 0x1122334455667788L);
+ int value = bb.getInt(0);
+
+ testEscapeAnalysis("testSimpleLongOverwriteWithFirstIntSnippet", JavaConstant.forInt(value), false);
+ }
+
+ public static int testSimpleLongOverwriteWithFirstIntSnippet() {
+ TestClassInt x = new TestClassInt();
+ UNSAFE.putLong(x, fieldOffset1, 0x1122334455667788L);
+ UNSAFE.putInt(x, fieldOffset2, 10);
+ return UNSAFE.getInt(x, fieldOffset1);
+ }
+
+ @Test
public void testMergedDouble() {
testEscapeAnalysis("testMergedDoubleSnippet", null, false);
Assert.assertEquals(1, returnNodes.size());
@@ -111,6 +257,32 @@
return UNSAFE.getDouble(x, fieldOffset1);
}
+ static class ExtendedTestClassInt extends TestClassInt {
+ public long l;
+ }
+
+ @Test
+ public void testMergedVirtualObjects() {
+ testEscapeAnalysis("testMergedVirtualObjectsSnippet", null, false);
+ }
+
+ public static TestClassInt testMergedVirtualObjectsSnippet(int value) {
+ TestClassInt x;
+ if (value == 1) {
+ x = new TestClassInt();
+ UNSAFE.putDouble(x, fieldOffset1, 10);
+ } else {
+ x = new TestClassInt();
+ UNSAFE.putInt(x, fieldOffset1, 0);
+ }
+ UNSAFE.putInt(x, fieldOffset1, 0);
+ if (value == 2) {
+ UNSAFE.putInt(x, fieldOffset2, 0);
+ }
+ GraalDirectives.deoptimizeAndInvalidate();
+ return x;
+ }
+
@Test
public void testMaterializedDouble() {
test("testMaterializedDoubleSnippet");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/NestedLoopEffectsPhaseComplexityTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/NestedLoopEffectsPhaseComplexityTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -146,7 +146,7 @@
private StructuredGraph parseBytecodes(ResolvedJavaMethod method, HighTierContext context, CanonicalizerPhase canonicalizer) {
OptionValues options = getInitialOptions();
- StructuredGraph newGraph = new StructuredGraph.Builder(options, getDebugContext(options), AllowAssumptions.NO).method(method).build();
+ StructuredGraph newGraph = new StructuredGraph.Builder(options, getDebugContext(options, null, method), AllowAssumptions.NO).method(method).build();
context.getGraphBuilderSuite().apply(newGraph, context);
new DeadCodeEliminationPhase(Optional).apply(newGraph);
canonicalizer.apply(newGraph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompilerOptions.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompilerOptions.java Wed Nov 08 16:03:35 2017 -0500
@@ -47,7 +47,7 @@
public static final EnumOptionKey<ExceptionAction> CompilationFailureAction = new EnumOptionKey<>(ExceptionAction.Diagnose);
@Option(help = "The maximum number of compilation failures or bailouts to handle with the action specified " +
"by CompilationFailureAction or CompilationBailoutAction before changing to a less verbose action.", type = OptionType.User)
- public static final OptionKey<Integer> MaxCompilationProblemsPerAction = new OptionKey<>(5);
+ public static final OptionKey<Integer> MaxCompilationProblemsPerAction = new OptionKey<>(2);
@Option(help = "Alias for CompilationFailureAction=ExitVM.", type = OptionType.User)
public static final OptionKey<Boolean> ExitVMOnException = new OptionKey<>(false);
// @formatter:on
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/DebugInfoBuilder.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/DebugInfoBuilder.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, 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
@@ -132,8 +132,17 @@
slotKinds[pos] = toSlotKind(value);
pos++;
} else {
- assert currentField.values().get(i - 1).getStackKind() == JavaKind.Double || currentField.values().get(i - 1).getStackKind() == JavaKind.Long : vobjNode + " " + i + " " +
- currentField.values().get(i - 1);
+ assert value.getStackKind() == JavaKind.Illegal;
+ ValueNode previousValue = currentField.values().get(i - 1);
+ assert (previousValue != null && previousValue.getStackKind().needsTwoSlots()) : vobjNode + " " + i +
+ " " + previousValue + " " + currentField.values().snapshot();
+ if (previousValue == null || !previousValue.getStackKind().needsTwoSlots()) {
+ // Don't allow the IllegalConstant to leak into the debug info
+ JavaKind entryKind = vobjNode.entryKind(i);
+ values[pos] = JavaConstant.defaultForKind(entryKind.getStackKind());
+ slotKinds[pos] = entryKind.getStackKind();
+ pos++;
+ }
}
}
if (pos != entryCount) {
@@ -164,19 +173,19 @@
if (!type.isArray()) {
ResolvedJavaField[] fields = type.getInstanceFields(true);
int fieldIndex = 0;
- for (int i = 0; i < values.length; i++) {
- ResolvedJavaField field = fields[fieldIndex++];
- JavaKind valKind = slotKinds[i].getStackKind();
+ for (int valueIndex = 0; valueIndex < values.length; valueIndex++, fieldIndex++) {
+ ResolvedJavaField field = fields[fieldIndex];
+ JavaKind valKind = slotKinds[valueIndex].getStackKind();
JavaKind fieldKind = storageKind(field.getType());
- if (fieldKind == JavaKind.Object) {
- assert valKind.isObject() : field + ": " + valKind + " != " + fieldKind;
+ if ((valKind == JavaKind.Double || valKind == JavaKind.Long) && fieldKind == JavaKind.Int) {
+ assert fieldIndex + 1 < fields.length : String.format("Not enough fields for fieldIndex = %d valueIndex = %d %s %s", fieldIndex, valueIndex, Arrays.toString(fields),
+ Arrays.toString(values));
+ assert storageKind(fields[fieldIndex + 1].getType()) == JavaKind.Int : String.format("fieldIndex = %d valueIndex = %d %s %s %s", fieldIndex, valueIndex,
+ storageKind(fields[fieldIndex + 1].getType()), Arrays.toString(fields),
+ Arrays.toString(values));
+ fieldIndex++;
} else {
- if ((valKind == JavaKind.Double || valKind == JavaKind.Long) && fieldKind == JavaKind.Int) {
- assert storageKind(fields[fieldIndex].getType()) == JavaKind.Int;
- fieldIndex++;
- } else {
- assert valKind == fieldKind.getStackKind() : field + ": " + valKind + " != " + fieldKind;
- }
+ assert valKind == fieldKind.getStackKind() : field + ": " + valKind + " != " + fieldKind;
}
}
assert fields.length == fieldIndex : type + ": fields=" + Arrays.toString(fields) + ", field values=" + Arrays.toString(values);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java Wed Nov 08 16:03:35 2017 -0500
@@ -59,6 +59,7 @@
import org.graalvm.compiler.lir.SwitchStrategy;
import org.graalvm.compiler.lir.Variable;
import org.graalvm.compiler.lir.debug.LIRGenerationDebugContext;
+import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
import org.graalvm.compiler.lir.gen.LIRGenerator;
import org.graalvm.compiler.lir.gen.LIRGenerator.Options;
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
@@ -577,9 +578,9 @@
@Override
public void emitInvoke(Invoke x) {
LoweredCallTargetNode callTarget = (LoweredCallTargetNode) x.callTarget();
- CallingConvention invokeCc = gen.getResult().getFrameMapBuilder().getRegisterConfig().getCallingConvention(callTarget.callType(), x.asNode().stamp().javaType(gen.getMetaAccess()),
- callTarget.signature(), gen);
- gen.getResult().getFrameMapBuilder().callsMethod(invokeCc);
+ FrameMapBuilder frameMapBuilder = gen.getResult().getFrameMapBuilder();
+ CallingConvention invokeCc = frameMapBuilder.getRegisterConfig().getCallingConvention(callTarget.callType(), x.asNode().stamp().javaType(gen.getMetaAccess()), callTarget.signature(), gen);
+ frameMapBuilder.callsMethod(invokeCc);
Value[] parameters = visitInvokeArguments(invokeCc, callTarget.arguments());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java Wed Nov 08 16:03:35 2017 -0500
@@ -195,9 +195,12 @@
public InstalledCode createInstalledCode(DebugContext debug, ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compilationResult,
SpeculationLog speculationLog, InstalledCode predefinedInstalledCode, boolean isDefault, Object[] context) {
Object[] debugContext = context != null ? context : new Object[]{getProviders().getCodeCache(), method, compilationResult};
- CodeInstallationTask[] tasks = new CodeInstallationTask[codeInstallationTaskFactories.size()];
- for (int i = 0; i < codeInstallationTaskFactories.size(); i++) {
- tasks[i] = codeInstallationTaskFactories.get(i).create();
+ CodeInstallationTask[] tasks;
+ synchronized (this) {
+ tasks = new CodeInstallationTask[codeInstallationTaskFactories.size()];
+ for (int i = 0; i < codeInstallationTaskFactories.size(); i++) {
+ tasks[i] = codeInstallationTaskFactories.get(i).create();
+ }
}
try (DebugContext.Scope s2 = debug.scope("CodeInstall", debugContext);
DebugContext.Activation a = debug.activate()) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java Wed Nov 08 16:03:35 2017 -0500
@@ -29,9 +29,11 @@
import static org.graalvm.compiler.debug.DebugOptions.Dump;
import static org.graalvm.compiler.debug.DebugOptions.DumpOnError;
import static org.graalvm.compiler.debug.DebugOptions.DumpOnPhaseChange;
+import static org.graalvm.compiler.debug.DebugOptions.DumpPath;
import static org.graalvm.compiler.debug.DebugOptions.ListMetrics;
import static org.graalvm.compiler.debug.DebugOptions.Log;
import static org.graalvm.compiler.debug.DebugOptions.MemUseTrackers;
+import static org.graalvm.compiler.debug.DebugOptions.ShowDumpFiles;
import static org.graalvm.compiler.debug.DebugOptions.Time;
import static org.graalvm.compiler.debug.DebugOptions.Timers;
import static org.graalvm.compiler.debug.DebugOptions.TrackMemUse;
@@ -56,6 +58,7 @@
import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.graphio.GraphOutput;
import org.graalvm.util.EconomicMap;
import org.graalvm.util.EconomicSet;
import org.graalvm.util.Pair;
@@ -98,6 +101,8 @@
CloseableCounter currentMemUseTracker;
Scope lastClosedScope;
Throwable lastExceptionThrown;
+ private IgvDumpChannel sharedChannel;
+ private GraphOutput<?, ?> parentOutput;
/**
* Stores the {@link MetricKey} values.
@@ -111,6 +116,19 @@
return immutable.scopesEnabled;
}
+ public <G, N, M> GraphOutput<G, M> buildOutput(GraphOutput.Builder<G, N, M> builder) throws IOException {
+ if (parentOutput != null) {
+ return builder.build(parentOutput);
+ } else {
+ if (sharedChannel == null) {
+ sharedChannel = new IgvDumpChannel(() -> getDumpPath(".bgv", false), immutable.options);
+ }
+ final GraphOutput<G, M> output = builder.build(sharedChannel);
+ parentOutput = output;
+ return output;
+ }
+ }
+
/**
* The immutable configuration that can be shared between {@link DebugContext} objects.
*/
@@ -323,6 +341,14 @@
String compilableName = compilable instanceof JavaMethod ? ((JavaMethod) compilable).format("%H.%n(%p)%R") : String.valueOf(compilable);
return identifier + ":" + compilableName;
}
+
+ final String getLabel() {
+ if (compilable instanceof JavaMethod) {
+ JavaMethod method = (JavaMethod) compilable;
+ return method.format("%h.%n(%p)%r");
+ }
+ return String.valueOf(compilable);
+ }
}
private final Description description;
@@ -394,6 +420,20 @@
}
}
+ public Path getDumpPath(String extension, boolean directory) {
+ try {
+ String id = description == null ? null : description.identifier;
+ String label = description == null ? null : description.getLabel();
+ Path result = PathUtilities.createUnique(immutable.options, DumpPath, id, label, extension, directory);
+ if (ShowDumpFiles.getValue(immutable.options)) {
+ TTY.println("Dumping debug output to %s", result.toAbsolutePath().toString());
+ }
+ return result;
+ } catch (IOException ex) {
+ throw rethrowSilently(RuntimeException.class, ex);
+ }
+ }
+
/**
* A special dump level that indicates the dumping machinery is enabled but no dumps will be
* produced except through other options.
@@ -2043,4 +2083,9 @@
}
out.println();
}
+
+ @SuppressWarnings({"unused", "unchecked"})
+ private static <E extends Exception> E rethrowSilently(Class<E> type, Throwable ex) throws E {
+ throw (E) ex;
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugHandlersFactory.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugHandlersFactory.java Wed Nov 08 16:03:35 2017 -0500
@@ -35,6 +35,9 @@
/**
* Creates {@link DebugHandler}s based on {@code options}.
+ *
+ * @param options options to control type and name of the channel
+ * @return list of debug handers that have been created
*/
List<DebugHandler> createHandlers(OptionValues options);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java Wed Nov 08 16:03:35 2017 -0500
@@ -128,8 +128,6 @@
public static final OptionKey<Boolean> PrintGraphProbabilities = new OptionKey<>(false);
@Option(help = "Enable dumping to the IdealGraphVisualizer.", type = OptionType.Debug)
public static final OptionKey<Boolean> PrintGraph = new OptionKey<>(true);
- @Option(help = "Dump graphs in binary format instead of XML format.", type = OptionType.Debug)
- public static final OptionKey<Boolean> PrintBinaryGraphs = new OptionKey<>(true);
@Option(help = "Print graphs to files instead of sending them over the network.", type = OptionType.Debug)
public static final OptionKey<Boolean> PrintGraphFile = new OptionKey<>(false);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/IgvDumpChannel.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+package org.graalvm.compiler.debug;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.ClosedByInterruptException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.channels.WritableByteChannel;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.function.Supplier;
+import static org.graalvm.compiler.debug.DebugOptions.PrintBinaryGraphPort;
+import static org.graalvm.compiler.debug.DebugOptions.PrintGraphHost;
+import org.graalvm.compiler.options.OptionValues;
+
+final class IgvDumpChannel implements WritableByteChannel {
+ private final Supplier<Path> pathProvider;
+ private final OptionValues options;
+ private WritableByteChannel sharedChannel;
+ private boolean closed;
+
+ IgvDumpChannel(Supplier<Path> pathProvider, OptionValues options) {
+ this.pathProvider = pathProvider;
+ this.options = options;
+ }
+
+ @Override
+ public int write(ByteBuffer src) throws IOException {
+ return channel().write(src);
+ }
+
+ @Override
+ public boolean isOpen() {
+ return !closed;
+ }
+
+ @Override
+ public void close() throws IOException {
+ }
+
+ void realClose() throws IOException {
+ closed = true;
+ if (sharedChannel != null) {
+ sharedChannel.close();
+ sharedChannel = null;
+ }
+ }
+
+ WritableByteChannel channel() throws IOException {
+ if (closed) {
+ throw new IOException();
+ }
+ if (sharedChannel == null) {
+ if (DebugOptions.PrintGraphFile.getValue(options)) {
+ sharedChannel = createFileChannel(pathProvider);
+ } else {
+ sharedChannel = createNetworkChannel(pathProvider, options);
+ }
+ }
+ return sharedChannel;
+ }
+
+ private static WritableByteChannel createNetworkChannel(Supplier<Path> pathProvider, OptionValues options) throws IOException {
+ String host = PrintGraphHost.getValue(options);
+ int port = PrintBinaryGraphPort.getValue(options);
+ try {
+ WritableByteChannel channel = SocketChannel.open(new InetSocketAddress(host, port));
+ TTY.println("Connected to the IGV on %s:%d", host, port);
+ return channel;
+ } catch (ClosedByInterruptException | InterruptedIOException e) {
+ /*
+ * Interrupts should not count as errors because they may be caused by a cancelled Graal
+ * compilation. ClosedByInterruptException occurs if the SocketChannel could not be
+ * opened. InterruptedIOException occurs if new Socket(..) was interrupted.
+ */
+ return null;
+ } catch (IOException e) {
+ if (!DebugOptions.PrintGraphFile.hasBeenSet(options)) {
+ return createFileChannel(pathProvider);
+ } else {
+ throw new IOException(String.format("Could not connect to the IGV on %s:%d", host, port), e);
+ }
+ }
+ }
+
+ private static WritableByteChannel createFileChannel(Supplier<Path> pathProvider) throws IOException {
+ Path path = pathProvider.get();
+ try {
+ return FileChannel.open(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
+ } catch (IOException e) {
+ throw new IOException(String.format("Failed to open %s to dump IGV graphs", path), e);
+ }
+ }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/PathUtilities.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/PathUtilities.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,12 +22,13 @@
*/
package org.graalvm.compiler.debug;
+import java.io.File;
import java.io.IOException;
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.util.HashMap;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.graalvm.compiler.options.OptionKey;
@@ -39,54 +40,6 @@
public class PathUtilities {
private static final AtomicLong globalTimeStamp = new AtomicLong();
- /**
- * This generates a per thread persistent id to aid mapping related dump files with each other.
- */
- private static final ThreadLocal<PerThreadSequence> threadDumpId = new ThreadLocal<>();
- private static final AtomicInteger dumpId = new AtomicInteger();
-
- static class PerThreadSequence {
- final int threadID;
- HashMap<String, Integer> sequences = new HashMap<>(2);
-
- PerThreadSequence(int threadID) {
- this.threadID = threadID;
- }
-
- String generateID(String extension) {
- Integer box = sequences.get(extension);
- if (box == null) {
- sequences.put(extension, 1);
- return Integer.toString(threadID);
- } else {
- sequences.put(extension, box + 1);
- return Integer.toString(threadID) + '-' + box;
- }
- }
- }
-
- private static String getThreadDumpId(String extension) {
- PerThreadSequence id = threadDumpId.get();
- if (id == null) {
- id = new PerThreadSequence(dumpId.incrementAndGet());
- threadDumpId.set(id);
- }
- return id.generateID(extension);
- }
-
- /**
- * Prepends a period (i.e., {@code '.'}) to an non-null, non-empty string representation a file
- * extension if the string does not already start with a period.
- *
- * @return {@code ext} unmodified if it is null, empty or already starts with a period other
- * {@code "." + ext}
- */
- public static String formatExtension(String ext) {
- if (ext == null || ext.length() == 0) {
- return "";
- }
- return "." + ext;
- }
/**
* Gets a time stamp for the current process. This method will always return the same value for
@@ -100,43 +53,6 @@
}
/**
- * Generates a {@link Path} using the format "%s-%d_%d%s" with the {@code baseNameOption}, a
- * {@link #getGlobalTimeStamp() global timestamp} , {@link #getThreadDumpId a per thread unique
- * id} and an optional {@code extension}.
- *
- * @return the output file path or null if the flag is null
- */
- public static Path getPath(OptionValues options, OptionKey<String> baseNameOption, String extension) throws IOException {
- return getPath(options, baseNameOption, extension, true);
- }
-
- /**
- * Generate a {@link Path} using the format "%s-%d_%s" with the {@code baseNameOption}, a
- * {@link #getGlobalTimeStamp() global timestamp} and an optional {@code extension} .
- *
- * @return the output file path or null if the flag is null
- */
- public static Path getPathGlobal(OptionValues options, OptionKey<String> baseNameOption, String extension) throws IOException {
- return getPath(options, baseNameOption, extension, false);
- }
-
- private static Path getPath(OptionValues options, OptionKey<String> baseNameOption, String extension, boolean includeThreadId) throws IOException {
- if (baseNameOption.getValue(options) == null) {
- return null;
- }
- String ext = formatExtension(extension);
- final String name = includeThreadId
- ? String.format("%s-%d_%s%s", baseNameOption.getValue(options), getGlobalTimeStamp(), getThreadDumpId(ext), ext)
- : String.format("%s-%d%s", baseNameOption.getValue(options), getGlobalTimeStamp(), ext);
- Path result = Paths.get(name);
- if (result.isAbsolute()) {
- return result;
- }
- Path dumpDir = DebugOptions.getDumpDirectory(options);
- return dumpDir.resolve(name).normalize();
- }
-
- /**
* Gets a value based on {@code name} that can be passed to {@link Paths#get(String, String...)}
* without causing an {@link InvalidPathException}.
*
@@ -145,21 +61,80 @@
*/
public static String sanitizeFileName(String name) {
try {
- Paths.get(name);
- return name;
+ Path path = Paths.get(name);
+ if (path.getNameCount() == 0) {
+ return name;
+ }
} catch (InvalidPathException e) {
// fall through
}
StringBuilder buf = new StringBuilder(name.length());
for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i);
- try {
- Paths.get(String.valueOf(c));
- } catch (InvalidPathException e) {
- buf.append('_');
+ if (c != File.separatorChar && c != ' ' && !Character.isISOControl(c)) {
+ try {
+ Paths.get(String.valueOf(c));
+ buf.append(c);
+ continue;
+ } catch (InvalidPathException e) {
+ }
}
- buf.append(c);
+ buf.append('_');
}
return buf.toString();
}
+
+ /**
+ * A maximum file name length supported by most file systems. There is no platform independent
+ * way to get this in Java.
+ */
+ private static final int MAX_FILE_NAME_LENGTH = 255;
+
+ private static final String ELLIPSIS = "...";
+
+ static Path createUnique(OptionValues options, OptionKey<String> baseNameOption, String id, String label, String ext, boolean createDirectory) throws IOException {
+ String uniqueTag = "";
+ int dumpCounter = 1;
+ String prefix;
+ if (id == null) {
+ prefix = baseNameOption.getValue(options);
+ int slash = prefix.lastIndexOf(File.separatorChar);
+ prefix = prefix.substring(slash + 1);
+ } else {
+ prefix = id;
+ }
+ for (;;) {
+ int fileNameLengthWithoutLabel = uniqueTag.length() + ext.length() + prefix.length() + "[]".length();
+ int labelLengthLimit = MAX_FILE_NAME_LENGTH - fileNameLengthWithoutLabel;
+ String fileName;
+ if (labelLengthLimit < ELLIPSIS.length()) {
+ // This means `id` is very long
+ String suffix = uniqueTag + ext;
+ int idLengthLimit = Math.min(MAX_FILE_NAME_LENGTH - suffix.length(), prefix.length());
+ fileName = sanitizeFileName(prefix.substring(0, idLengthLimit) + suffix);
+ } else {
+ if (label == null) {
+ fileName = sanitizeFileName(prefix + uniqueTag + ext);
+ } else {
+ String adjustedLabel = label;
+ if (label.length() > labelLengthLimit) {
+ adjustedLabel = label.substring(0, labelLengthLimit - ELLIPSIS.length()) + ELLIPSIS;
+ }
+ fileName = sanitizeFileName(prefix + '[' + adjustedLabel + ']' + uniqueTag + ext);
+ }
+ }
+ Path dumpDir = DebugOptions.getDumpDirectory(options);
+ Path result = Paths.get(dumpDir.toString(), fileName);
+ try {
+ if (createDirectory) {
+ return Files.createDirectory(result);
+ } else {
+ return Files.createFile(result);
+ }
+ } catch (FileAlreadyExistsException e) {
+ uniqueTag = "_" + dumpCounter++;
+ }
+ }
+ }
+
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/GraphSnippetTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+package org.graalvm.compiler.graph.test.graphio;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import static org.junit.Assert.assertTrue;
+import org.junit.Assume;
+import org.junit.Test;
+
+public class GraphSnippetTest {
+ @Test
+ public void dumpTheFile() throws Exception {
+ Class<?> snippets = null;
+ try {
+ snippets = Class.forName("org.graalvm.graphio.GraphSnippets");
+ } catch (ClassNotFoundException notFound) {
+ Assume.assumeNoException("The snippets class has to be around", notFound);
+ }
+ Method dump = null;
+ try {
+ dump = snippets.getDeclaredMethod("dump", File.class);
+ dump.setAccessible(true);
+ } catch (RuntimeException ex) {
+ Assume.assumeTrue("Only run the test, if the method is accessible", dump != null && dump.isAccessible());
+ }
+ File diamond = File.createTempFile("diamond", ".bgv");
+ dump.invoke(null, diamond);
+ assertTrue("File .bgv created: " + diamond, diamond.length() > 50);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/NodeEncodingTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,311 @@
+/*
+ * 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.
+ */
+package org.graalvm.compiler.graph.test.graphio;
+
+import java.io.ByteArrayOutputStream;
+import java.nio.channels.Channels;
+import java.nio.channels.WritableByteChannel;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import org.graalvm.graphio.GraphOutput;
+import org.graalvm.graphio.GraphStructure;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import org.junit.Before;
+import org.junit.Test;
+
+public final class NodeEncodingTest {
+
+ private ByteArrayOutputStream out;
+
+ @Before
+ public void initOutput() {
+ out = new ByteArrayOutputStream();
+ }
+
+ @Test
+ public void version40TheNodeIsntDumpedWithItsID() throws Exception {
+ runTheNodeIsntDumpedWithItsID(true);
+ }
+
+ @Test
+ public void defaultVersionTheNodeIsntDumpedWithItsID() throws Exception {
+ runTheNodeIsntDumpedWithItsID(false);
+ }
+
+ private void runTheNodeIsntDumpedWithItsID(boolean explicitVersion) throws Exception {
+ WritableByteChannel w = Channels.newChannel(out);
+ MockGraph graph = new MockGraph();
+ MockNodeClass clazz = new MockNodeClass("clazz");
+ MockNode node = new MockNode(clazz, 33); // random value otherwise not found in the stream
+ try (GraphOutput<MockGraph, ?> dump = explicitVersion ? GraphOutput.newBuilder(new MockStructure()).protocolVersion(4, 0).build(w) : GraphOutput.newBuilder(new MockStructure()).build(w)) {
+ dump.beginGroup(graph, "test1", "t1", null, 0, Collections.singletonMap("node", node));
+ dump.endGroup();
+ }
+
+ assertEquals("Node is always requested", 1, node.nodeRequested);
+ assertEquals("Nobody asks for id of a node in version 4.0", 0, node.idTested);
+ assertByte(false, out.toByteArray(), 33);
+ assertEquals("Node class of the node has been requested", 1, node.nodeClassRequested);
+ assertEquals("Node class template name stored", 1, clazz.nameTemplateQueried);
+ assertFalse("No to string ops", node.toStringRequested);
+ }
+
+ @Test
+ public void dumpingNodeInVersion10() throws Exception {
+ runTheNodeIsTreatedAsString(true);
+ }
+
+ private void runTheNodeIsTreatedAsString(boolean explicitVersion) throws Exception {
+ WritableByteChannel w = Channels.newChannel(out);
+ MockGraph graph = new MockGraph();
+ MockNodeClass clazz = new MockNodeClass("clazz");
+ MockNode node = new MockNode(clazz, 33); // random value otherwise not found in the stream
+ try (GraphOutput<MockGraph, ?> dump = explicitVersion ? GraphOutput.newBuilder(new MockStructure()).protocolVersion(1, 0).build(w) : GraphOutput.newBuilder(new MockStructure()).build(w)) {
+ dump.beginGroup(graph, "test1", "t1", null, 0, Collections.singletonMap("node", node));
+ dump.endGroup();
+ }
+
+ assertEquals("Node is always requested", 1, node.nodeRequested);
+ assertEquals("Nobody asks for id of a node in version 1.0", 0, node.idTested);
+ assertByte(false, out.toByteArray(), 33);
+ assertEquals("Node class was needed to find out it is not a NodeClass instance", 1, node.nodeClassRequested);
+ assertEquals("Node class template name wasn't needed however", 0, clazz.nameTemplateQueried);
+ assertTrue("Node sent as a string version 1.0", node.toStringRequested);
+ }
+
+ @Test
+ public void dumpingNodeInVersion15() throws Exception {
+ runTheNodeIsTreatedPoolEntry(true);
+ }
+
+ private void runTheNodeIsTreatedPoolEntry(boolean explicitVersion) throws Exception {
+ WritableByteChannel w = Channels.newChannel(out);
+ MockGraph graph = new MockGraph();
+ MockNodeClass clazz = new MockNodeClass("clazz");
+ MockNode node = new MockNode(clazz, 33); // random value otherwise not found in the stream
+ try (GraphOutput<MockGraph, ?> dump = explicitVersion ? GraphOutput.newBuilder(new MockStructure()).protocolVersion(5, 0).build(w) : GraphOutput.newBuilder(new MockStructure()).build(w)) {
+ dump.beginGroup(graph, "test1", "t1", null, 0, Collections.singletonMap("node", node));
+ dump.endGroup();
+ }
+
+ assertEquals("Node is always requested", 1, node.nodeRequested);
+ assertEquals("Id of our node is requested in version 5.0", 1, node.idTested);
+ assertByte(true, out.toByteArray(), 33);
+ assertTrue("Node class was needed at least once", 1 <= node.nodeClassRequested);
+ assertEquals("Node class template name sent to server", 1, clazz.nameTemplateQueried);
+ assertFalse("Node.toString() isn't needed", node.toStringRequested);
+ }
+
+ @Test
+ public void dumpingNodeTwiceInVersion4() throws Exception {
+ WritableByteChannel w = Channels.newChannel(out);
+ MockGraph graph = new MockGraph();
+ MockNodeClass clazz = new MockNodeClass("clazz");
+ MockNode node = new MockNode(clazz, 33); // random value otherwise not found in the stream
+ try (GraphOutput<MockGraph, ?> dump = GraphOutput.newBuilder(new MockStructure()).protocolVersion(4, 0).build(w)) {
+ Map<String, Object> props = new LinkedHashMap<>();
+ props.put("node1", node);
+ props.put("node2", node);
+ props.put("node3", node);
+ dump.beginGroup(graph, "test1", "t1", null, 0, props);
+ dump.endGroup();
+ }
+
+ assertEquals("Node requested three times", 3, node.nodeRequested);
+ assertEquals("Nobody asks for id of a node in version 4.0", 0, node.idTested);
+ // check there is no encoded string for object #3
+ assertByte(false, out.toByteArray(), 1, 0, 3);
+ assertEquals("Node class of the node has been requested three times", 3, node.nodeClassRequested);
+ assertEquals("Node class template name stored", 1, clazz.nameTemplateQueried);
+ assertFalse("No to string ops", node.toStringRequested);
+ }
+
+ private static void assertByte(boolean shouldBeFound, byte[] arr, int... value) {
+ boolean found = false;
+ int at = 0;
+ for (int i = 0; i < arr.length; i++) {
+ if (arr[i] == value[at]) {
+ if (++at == value.length) {
+ found = true;
+ break;
+ }
+ } else {
+ at = 0;
+ }
+ }
+ if (shouldBeFound == found) {
+ return;
+ }
+ if (shouldBeFound) {
+ fail("Value " + value + " not found in\n" + Arrays.toString(arr));
+ } else {
+ fail("Value " + value + " surprisingly found in\n" + Arrays.toString(arr));
+ }
+ }
+
+ private static final class MockStructure implements GraphStructure<MockGraph, MockNode, MockNodeClass, MockNodeClass> {
+
+ @Override
+ public MockGraph graph(MockGraph currentGraph, Object obj) {
+ return obj instanceof MockGraph ? (MockGraph) obj : null;
+ }
+
+ @Override
+ public Iterable<? extends MockNode> nodes(MockGraph graph) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public int nodesCount(MockGraph graph) {
+ return 0;
+ }
+
+ @Override
+ public int nodeId(MockNode node) {
+ node.idTested++;
+ return node.id;
+ }
+
+ @Override
+ public boolean nodeHasPredecessor(MockNode node) {
+ return false;
+ }
+
+ @Override
+ public void nodeProperties(MockGraph graph, MockNode node, Map<String, ? super Object> properties) {
+ }
+
+ @Override
+ public MockNode node(Object obj) {
+ if (obj instanceof MockNode) {
+ ((MockNode) obj).nodeRequested++;
+ return (MockNode) obj;
+ }
+ return null;
+ }
+
+ @Override
+ public MockNodeClass nodeClass(Object obj) {
+ if (obj instanceof MockNode) {
+ ((MockNode) obj).nodeClassRequested++;
+ }
+ return obj instanceof MockNodeClass ? (MockNodeClass) obj : null;
+ }
+
+ @Override
+ public MockNodeClass classForNode(MockNode n) {
+ n.nodeClassRequested++;
+ return n.clazz;
+ }
+
+ @Override
+ public String nameTemplate(MockNodeClass nodeClass) {
+ nodeClass.nameTemplateQueried++;
+ return "";
+ }
+
+ @Override
+ public Object nodeClassType(MockNodeClass nodeClass) {
+ return nodeClass.getClass();
+ }
+
+ @Override
+ public MockNodeClass portInputs(MockNodeClass nodeClass) {
+ return nodeClass;
+ }
+
+ @Override
+ public MockNodeClass portOutputs(MockNodeClass nodeClass) {
+ return nodeClass;
+ }
+
+ @Override
+ public int portSize(MockNodeClass port) {
+ return 0;
+ }
+
+ @Override
+ public boolean edgeDirect(MockNodeClass port, int index) {
+ return false;
+ }
+
+ @Override
+ public String edgeName(MockNodeClass port, int index) {
+ return null;
+ }
+
+ @Override
+ public Object edgeType(MockNodeClass port, int index) {
+ return null;
+ }
+
+ @Override
+ public Collection<? extends MockNode> edgeNodes(MockGraph graph, MockNode node, MockNodeClass port, int index) {
+ return null;
+ }
+ }
+
+ private static final class MockGraph {
+
+ }
+
+ private static final class MockNode {
+ final MockNodeClass clazz;
+ final int id;
+ int idTested;
+ int nodeClassRequested;
+ int nodeRequested;
+ boolean toStringRequested;
+
+ MockNode(MockNodeClass clazz, int id) {
+ this.clazz = clazz;
+ this.id = id;
+ }
+
+ @Override
+ public String toString() {
+ this.toStringRequested = true;
+ return "MockNode{" + "id=" + id + ", class=" + clazz + '}';
+ }
+ }
+
+ private static final class MockNodeClass {
+ final String name;
+ int nameTemplateQueried;
+
+ MockNodeClass(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return "MockNodeClass{" + "name=" + name + '}';
+ }
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java Wed Nov 08 16:03:35 2017 -0500
@@ -514,30 +514,61 @@
/**
* A node was added to a graph.
*/
- NODE_ADDED;
+ NODE_ADDED,
+
+ /**
+ * A node was removed from the graph.
+ */
+ NODE_REMOVED;
}
/**
* Client interested in one or more node related events.
*/
- public interface NodeEventListener {
+ public abstract static class NodeEventListener {
/**
- * Default handler for events.
+ * A method called when a change event occurs.
+ *
+ * This method dispatches the event to user-defined triggers. The methods that change the
+ * graph (typically in Graph and Node) must call this method to dispatch the event.
*
* @param e an event
* @param node the node related to {@code e}
*/
- default void event(NodeEvent e, Node node) {
+ final void event(NodeEvent e, Node node) {
+ switch (e) {
+ case INPUT_CHANGED:
+ inputChanged(node);
+ break;
+ case ZERO_USAGES:
+ usagesDroppedToZero(node);
+ break;
+ case NODE_ADDED:
+ nodeAdded(node);
+ break;
+ case NODE_REMOVED:
+ nodeRemoved(node);
+ break;
+ }
+ changed(e, node);
}
/**
- * Notifies this listener of a change in a node's inputs.
+ * Notifies this listener about any change event in the graph.
+ *
+ * @param e an event
+ * @param node the node related to {@code e}
+ */
+ public void changed(NodeEvent e, Node node) {
+ }
+
+ /**
+ * Notifies this listener about a change in a node's inputs.
*
* @param node a node who has had one of its inputs changed
*/
- default void inputChanged(Node node) {
- event(NodeEvent.INPUT_CHANGED, node);
+ public void inputChanged(Node node) {
}
/**
@@ -545,8 +576,7 @@
*
* @param node a node whose {@link Node#usages()} just became empty
*/
- default void usagesDroppedToZero(Node node) {
- event(NodeEvent.ZERO_USAGES, node);
+ public void usagesDroppedToZero(Node node) {
}
/**
@@ -554,8 +584,15 @@
*
* @param node a node that was just added to the graph
*/
- default void nodeAdded(Node node) {
- event(NodeEvent.NODE_ADDED, node);
+ public void nodeAdded(Node node) {
+ }
+
+ /**
+ * Notifies this listener of a removed node.
+ *
+ * @param node
+ */
+ public void nodeRemoved(Node node) {
}
}
@@ -583,7 +620,7 @@
}
}
- private static class ChainedNodeEventListener implements NodeEventListener {
+ private static class ChainedNodeEventListener extends NodeEventListener {
NodeEventListener head;
NodeEventListener next;
@@ -595,20 +632,32 @@
@Override
public void nodeAdded(Node node) {
- head.nodeAdded(node);
- next.nodeAdded(node);
+ head.event(NodeEvent.NODE_ADDED, node);
+ next.event(NodeEvent.NODE_ADDED, node);
}
@Override
public void inputChanged(Node node) {
- head.inputChanged(node);
- next.inputChanged(node);
+ head.event(NodeEvent.INPUT_CHANGED, node);
+ next.event(NodeEvent.INPUT_CHANGED, node);
}
@Override
public void usagesDroppedToZero(Node node) {
- head.usagesDroppedToZero(node);
- next.usagesDroppedToZero(node);
+ head.event(NodeEvent.ZERO_USAGES, node);
+ next.event(NodeEvent.ZERO_USAGES, node);
+ }
+
+ @Override
+ public void nodeRemoved(Node node) {
+ head.event(NodeEvent.NODE_REMOVED, node);
+ next.event(NodeEvent.NODE_REMOVED, node);
+ }
+
+ @Override
+ public void changed(NodeEvent e, Node node) {
+ head.event(e, node);
+ next.event(e, node);
}
}
@@ -1023,7 +1072,7 @@
updateNodeCaches(node);
if (nodeEventListener != null) {
- nodeEventListener.nodeAdded(node);
+ nodeEventListener.event(NodeEvent.NODE_ADDED, node);
}
afterRegister(node);
}
@@ -1085,6 +1134,10 @@
nodes[node.id] = null;
nodesDeletedSinceLastCompression++;
+ if (nodeEventListener != null) {
+ nodeEventListener.event(NodeEvent.NODE_ADDED, node);
+ }
+
// nodes aren't removed from the type cache here - they will be removed during iteration
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java Wed Nov 08 16:03:35 2017 -0500
@@ -752,7 +752,7 @@
assert !graph.isFrozen();
NodeEventListener listener = graph.nodeEventListener;
if (listener != null) {
- listener.inputChanged(node);
+ listener.event(Graph.NodeEvent.INPUT_CHANGED, node);
}
}
}
@@ -762,7 +762,7 @@
assert !graph.isFrozen();
NodeEventListener listener = graph.nodeEventListener;
if (listener != null && node.isAlive()) {
- listener.usagesDroppedToZero(node);
+ listener.event(Graph.NodeEvent.ZERO_USAGES, node);
}
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java Wed Nov 08 16:03:35 2017 -0500
@@ -183,8 +183,7 @@
sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess());
}
- Value[] parameters = visitInvokeArguments(gen.getResult().getFrameMapBuilder().getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen),
- node.arguments());
+ Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());
append(new AArch64BreakpointOp(parameters));
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java Wed Nov 08 16:03:35 2017 -0500
@@ -32,7 +32,6 @@
import org.graalvm.compiler.core.amd64.AMD64AddressNode;
import org.graalvm.compiler.core.common.CompressEncoding;
import org.graalvm.compiler.core.common.LIRKind;
-import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.core.common.type.ObjectStamp;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.debug.CounterKey;
@@ -44,6 +43,7 @@
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.CompressionNode;
import org.graalvm.compiler.nodes.CompressionNode.CompressionOp;
+import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.FloatingNode;
import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -93,76 +93,76 @@
}
@Override
- protected boolean improve(DebugContext debug, AMD64AddressNode addr) {
-
- boolean result = false;
-
- while (super.improve(debug, addr)) {
- result = true;
+ protected boolean improve(StructuredGraph graph, DebugContext debug, AMD64AddressNode addr, boolean isBaseNegated, boolean isIndexNegated) {
+ if (super.improve(graph, debug, addr, isBaseNegated, isIndexNegated)) {
+ return true;
}
if (addr.getScale() == Scale.Times1) {
if (addr.getIndex() instanceof CompressionNode) {
- if (improveUncompression(addr, (CompressionNode) addr.getIndex(), addr.getBase())) {
+ if (improveUncompression(addr, (CompressionNode) addr.getIndex(), addr.getBase(), isBaseNegated, isIndexNegated)) {
counterFoldedUncompressDuringAddressLowering.increment(debug);
return true;
}
}
if (addr.getBase() instanceof CompressionNode) {
- if (improveUncompression(addr, (CompressionNode) addr.getBase(), addr.getIndex())) {
+ if (improveUncompression(addr, (CompressionNode) addr.getBase(), addr.getIndex(), isBaseNegated, isIndexNegated)) {
counterFoldedUncompressDuringAddressLowering.increment(debug);
return true;
}
}
}
- return result;
+ return false;
+ }
+
+ @Override
+ protected boolean mightBeOptimized(ValueNode value) {
+ return super.mightBeOptimized(value) || value instanceof CompressionNode;
}
- private boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other) {
- if (compression.getOp() == CompressionOp.Uncompress) {
- CompressEncoding encoding = compression.getEncoding();
- Scale scale = Scale.fromShift(encoding.getShift());
- if (scale == null) {
+ private boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other, boolean isBaseNegated, boolean isIndexNegated) {
+ if (isBaseNegated || isIndexNegated || compression.getOp() != CompressionOp.Uncompress) {
+ return false;
+ }
+
+ CompressEncoding encoding = compression.getEncoding();
+ Scale scale = Scale.fromShift(encoding.getShift());
+ if (scale == null) {
+ return false;
+ }
+
+ if (heapBaseRegister != null && encoding.getBase() == heapBase) {
+ if ((!generatePIC || compression.stamp() instanceof ObjectStamp) && other == null) {
+ // With PIC it is only legal to do for oops since the base value may be
+ // different at runtime.
+ ValueNode base = compression.graph().unique(new HeapBaseNode(heapBaseRegister));
+ addr.setBase(base);
+ } else {
return false;
}
-
- if (heapBaseRegister != null && encoding.getBase() == heapBase) {
- if ((!generatePIC || compression.stamp() instanceof ObjectStamp) && other == null) {
- // With PIC it is only legal to do for oops since the base value may be
- // different at runtime.
- ValueNode base = compression.graph().unique(new HeapBaseNode(heapBaseRegister));
+ } else if (encoding.getBase() != 0 || (generatePIC && compression.stamp() instanceof KlassPointerStamp)) {
+ if (generatePIC) {
+ if (other == null) {
+ ValueNode base = compression.graph().unique(new GraalHotSpotVMConfigNode(config, config.MARKID_NARROW_KLASS_BASE_ADDRESS, JavaKind.Long));
addr.setBase(base);
} else {
return false;
}
- } else if (encoding.getBase() != 0 || (generatePIC && compression.stamp() instanceof KlassPointerStamp)) {
- if (generatePIC) {
- if (other == null) {
- ValueNode base = compression.graph().unique(new GraalHotSpotVMConfigNode(config, config.MARKID_NARROW_KLASS_BASE_ADDRESS, JavaKind.Long));
- addr.setBase(base);
- } else {
- return false;
- }
+ } else {
+ if (updateDisplacement(addr, encoding.getBase(), isBaseNegated)) {
+ addr.setBase(other);
} else {
- long disp = addr.getDisplacement() + encoding.getBase();
- if (NumUtil.isInt(disp)) {
- addr.setDisplacement((int) disp);
- addr.setBase(other);
- } else {
- return false;
- }
+ return false;
}
- } else {
- addr.setBase(other);
}
+ } else {
+ addr.setBase(other);
+ }
- addr.setScale(scale);
- addr.setIndex(compression.getValue());
- return true;
- } else {
- return false;
- }
+ addr.setScale(scale);
+ addr.setIndex(compression.getValue());
+ return true;
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Nov 08 16:03:35 2017 -0500
@@ -39,7 +39,6 @@
import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
import org.graalvm.compiler.core.amd64.AMD64ArithmeticLIRGenerator;
import org.graalvm.compiler.core.amd64.AMD64LIRGenerator;
-import org.graalvm.compiler.core.amd64.AMD64LIRKindTool;
import org.graalvm.compiler.core.amd64.AMD64MoveFactoryBase.BackupSlotProvider;
import org.graalvm.compiler.core.common.CompressEncoding;
import org.graalvm.compiler.core.common.LIRKind;
@@ -116,7 +115,7 @@
}
private AMD64HotSpotLIRGenerator(HotSpotProviders providers, GraalHotSpotVMConfig config, LIRGenerationResult lirGenRes, BackupSlotProvider backupSlotProvider) {
- this(new AMD64LIRKindTool(), new AMD64HotSpotArithmeticLIRGenerator(), new AMD64HotSpotMoveFactory(backupSlotProvider), providers, config, lirGenRes);
+ this(new AMD64HotSpotLIRKindTool(), new AMD64HotSpotArithmeticLIRGenerator(), new AMD64HotSpotMoveFactory(backupSlotProvider), providers, config, lirGenRes);
}
protected AMD64HotSpotLIRGenerator(LIRKindTool lirKindTool, AMD64ArithmeticLIRGenerator arithmeticLIRGen, MoveFactory moveFactory, HotSpotProviders providers, GraalHotSpotVMConfig config,
@@ -363,7 +362,7 @@
Stub stub = getStub();
if (destroysRegisters) {
if (stub != null && stub.preservesRegisters()) {
- Register[] savedRegisters = getResult().getFrameMapBuilder().getRegisterConfig().getAllocatableRegisters().toArray();
+ Register[] savedRegisters = getRegisterConfig().getAllocatableRegisters().toArray();
save = emitSaveAllRegisters(savedRegisters, true);
}
}
@@ -567,28 +566,29 @@
@Override
public Value emitCompress(Value pointer, CompressEncoding encoding, boolean nonNull) {
LIRKind inputKind = pointer.getValueKind(LIRKind.class);
- assert inputKind.getPlatformKind() == AMD64Kind.QWORD;
+ LIRKindTool lirKindTool = getLIRKindTool();
+ assert inputKind.getPlatformKind() == lirKindTool.getObjectKind().getPlatformKind();
if (inputKind.isReference(0)) {
// oop
- Variable result = newVariable(LIRKind.reference(AMD64Kind.DWORD));
- append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull));
+ Variable result = newVariable(lirKindTool.getNarrowOopKind());
+ append(new AMD64Move.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull, getLIRKindTool()));
return result;
} else {
// metaspace pointer
- Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD));
+ Variable result = newVariable(lirKindTool.getNarrowPointerKind());
AllocatableValue base = Value.ILLEGAL;
OptionValues options = getResult().getLIR().getOptions();
if (encoding.hasBase() || GeneratePIC.getValue(options)) {
if (GeneratePIC.getValue(options)) {
- Variable baseAddress = newVariable(LIRKind.value(AMD64Kind.QWORD));
+ Variable baseAddress = newVariable(lirKindTool.getWordKind());
AMD64HotSpotMove.BaseMove move = new AMD64HotSpotMove.BaseMove(baseAddress, config);
append(move);
base = baseAddress;
} else {
- base = emitLoadConstant(LIRKind.value(AMD64Kind.QWORD), JavaConstant.forLong(encoding.getBase()));
+ base = emitLoadConstant(lirKindTool.getWordKind(), JavaConstant.forLong(encoding.getBase()));
}
}
- append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), base, encoding, nonNull));
+ append(new AMD64Move.CompressPointer(result, asAllocatable(pointer), base, encoding, nonNull, getLIRKindTool()));
return result;
}
}
@@ -596,35 +596,37 @@
@Override
public Value emitUncompress(Value pointer, CompressEncoding encoding, boolean nonNull) {
LIRKind inputKind = pointer.getValueKind(LIRKind.class);
- assert inputKind.getPlatformKind() == AMD64Kind.DWORD;
+ LIRKindTool lirKindTool = getLIRKindTool();
+ assert inputKind.getPlatformKind() == lirKindTool.getNarrowOopKind().getPlatformKind();
if (inputKind.isReference(0)) {
// oop
- Variable result = newVariable(LIRKind.reference(AMD64Kind.QWORD));
- append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull));
+ Variable result = newVariable(lirKindTool.getObjectKind());
+ append(new AMD64Move.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull, lirKindTool));
return result;
} else {
// metaspace pointer
- Variable result = newVariable(LIRKind.value(AMD64Kind.QWORD));
+ LIRKind uncompressedKind = lirKindTool.getWordKind();
+ Variable result = newVariable(uncompressedKind);
AllocatableValue base = Value.ILLEGAL;
OptionValues options = getResult().getLIR().getOptions();
if (encoding.hasBase() || GeneratePIC.getValue(options)) {
if (GeneratePIC.getValue(options)) {
- Variable baseAddress = newVariable(LIRKind.value(AMD64Kind.QWORD));
+ Variable baseAddress = newVariable(uncompressedKind);
AMD64HotSpotMove.BaseMove move = new AMD64HotSpotMove.BaseMove(baseAddress, config);
append(move);
base = baseAddress;
} else {
- base = emitLoadConstant(LIRKind.value(AMD64Kind.QWORD), JavaConstant.forLong(encoding.getBase()));
+ base = emitLoadConstant(uncompressedKind, JavaConstant.forLong(encoding.getBase()));
}
}
- append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), base, encoding, nonNull));
+ append(new AMD64Move.UncompressPointer(result, asAllocatable(pointer), base, encoding, nonNull, lirKindTool));
return result;
}
}
@Override
public void emitNullCheck(Value address, LIRFrameState state) {
- if (address.getValueKind().getPlatformKind() == AMD64Kind.DWORD) {
+ if (address.getValueKind().getPlatformKind() == getLIRKindTool().getNarrowOopKind().getPlatformKind()) {
CompressEncoding encoding = config.getOopEncoding();
Value uncompressed;
if (encoding.getShift() <= 3) {
@@ -635,9 +637,9 @@
uncompressed = emitUncompress(address, encoding, false);
}
append(new AMD64Move.NullCheckOp(asAddressValue(uncompressed), state));
- } else {
- super.emitNullCheck(address, state);
+ return;
}
+ super.emitNullCheck(address, state);
}
@Override
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRKindTool.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+package org.graalvm.compiler.hotspot.amd64;
+
+import jdk.vm.ci.amd64.AMD64Kind;
+import org.graalvm.compiler.core.amd64.AMD64LIRKindTool;
+import org.graalvm.compiler.core.common.LIRKind;
+
+public class AMD64HotSpotLIRKindTool extends AMD64LIRKindTool {
+ @Override
+ public LIRKind getNarrowOopKind() {
+ return LIRKind.reference(AMD64Kind.DWORD);
+ }
+
+ @Override
+ public LIRKind getNarrowPointerKind() {
+ return LIRKind.value(AMD64Kind.DWORD);
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotMove.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotMove.java Wed Nov 08 16:03:35 2017 -0500
@@ -24,16 +24,13 @@
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
-import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
import static jdk.vm.ci.code.ValueUtil.asRegister;
import static jdk.vm.ci.code.ValueUtil.isRegister;
import static jdk.vm.ci.code.ValueUtil.isStackSlot;
-import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.amd64.AMD64Address;
-import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
import org.graalvm.compiler.core.common.CompressEncoding;
import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
import org.graalvm.compiler.debug.GraalError;
@@ -41,10 +38,8 @@
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.StandardOp.LoadConstantOp;
import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
-import org.graalvm.compiler.lir.amd64.AMD64Move;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
-import jdk.vm.ci.amd64.AMD64Kind;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
import jdk.vm.ci.hotspot.HotSpotObjectConstant;
@@ -180,91 +175,6 @@
}
}
- public static final class CompressPointer extends AMD64LIRInstruction {
- public static final LIRInstructionClass<CompressPointer> TYPE = LIRInstructionClass.create(CompressPointer.class);
-
- private final CompressEncoding encoding;
- private final boolean nonNull;
-
- @Def({REG, HINT}) protected AllocatableValue result;
- @Use({REG}) protected AllocatableValue input;
- @Alive({REG, ILLEGAL}) protected AllocatableValue baseRegister;
-
- public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) {
- super(TYPE);
- this.result = result;
- this.input = input;
- this.baseRegister = baseRegister;
- this.encoding = encoding;
- this.nonNull = nonNull;
- }
-
- @Override
- public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
- AMD64Move.move(AMD64Kind.QWORD, crb, masm, result, input);
-
- Register resReg = asRegister(result);
- if (encoding.hasBase() || GeneratePIC.getValue(crb.getOptions())) {
- Register baseReg = asRegister(baseRegister);
- if (!nonNull) {
- masm.testq(resReg, resReg);
- masm.cmovq(ConditionFlag.Equal, resReg, baseReg);
- }
- masm.subq(resReg, baseReg);
- }
-
- if (encoding.hasShift()) {
- masm.shrq(resReg, encoding.getShift());
- }
- }
- }
-
- public static final class UncompressPointer extends AMD64LIRInstruction {
- public static final LIRInstructionClass<UncompressPointer> TYPE = LIRInstructionClass.create(UncompressPointer.class);
-
- private final CompressEncoding encoding;
- private final boolean nonNull;
-
- @Def({REG, HINT}) protected AllocatableValue result;
- @Use({REG}) protected AllocatableValue input;
- @Alive({REG, ILLEGAL}) protected AllocatableValue baseRegister;
-
- public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) {
- super(TYPE);
- this.result = result;
- this.input = input;
- this.baseRegister = baseRegister;
- this.encoding = encoding;
- this.nonNull = nonNull;
- }
-
- @Override
- public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
- AMD64Move.move(AMD64Kind.DWORD, crb, masm, result, input);
-
- Register resReg = asRegister(result);
- if (encoding.getShift() != 0) {
- masm.shlq(resReg, encoding.getShift());
- }
-
- if (encoding.hasBase() || GeneratePIC.getValue(crb.getOptions())) {
- if (nonNull) {
- masm.addq(resReg, asRegister(baseRegister));
- } else {
- if (!encoding.hasShift()) {
- // if encoding.shift != 0, the flags are already set by the shlq
- masm.testq(resReg, resReg);
- }
-
- Label done = new Label();
- masm.jccb(ConditionFlag.Equal, done);
- masm.addq(resReg, asRegister(baseRegister));
- masm.bind(done);
- }
- }
- }
- }
-
public static void decodeKlassPointer(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register register, Register scratch, AMD64Address address, GraalHotSpotVMConfig config) {
CompressEncoding encoding = config.getKlassEncoding();
masm.movl(register, address);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Wed Nov 08 16:03:35 2017 -0500
@@ -189,8 +189,7 @@
sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess());
}
- Value[] parameters = visitInvokeArguments(gen.getResult().getFrameMapBuilder().getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen),
- node.arguments());
+ Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());
append(new AMD64BreakpointOp(parameters));
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotMove.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotMove.java Wed Nov 08 16:03:35 2017 -0500
@@ -113,8 +113,7 @@
} else {
register = asRegister(result);
}
- int bytes = result.getPlatformKind().getSizeInBytes();
- loadFromConstantTable(crb, masm, bytes, asRegister(constantTableBase), constant, register, SPARCDelayedControlTransfer.DUMMY);
+ int bytes = loadFromConstantTable(crb, masm, asRegister(constantTableBase), constant, register, SPARCDelayedControlTransfer.DUMMY);
if (isStack) {
masm.st(register, (SPARCAddress) crb.asAddress(result), bytes);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java Wed Nov 08 16:03:35 2017 -0500
@@ -162,8 +162,7 @@
sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess());
}
- Value[] parameters = visitInvokeArguments(gen.getResult().getFrameMapBuilder().getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen),
- node.arguments());
+ Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());
append(new SPARCBreakpointOp(parameters));
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotStrategySwitchOp.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotStrategySwitchOp.java Wed Nov 08 16:03:35 2017 -0500
@@ -77,8 +77,7 @@
boolean canUseShortBranch = masm.hasFeature(CPUFeature.CBCOND) && SPARCControlFlow.isShortBranch(masm, cbCondPosition, hint, target);
Register scratchRegister = asRegister(scratch);
- final int byteCount = constant.isCompressed() ? 4 : 8;
- loadFromConstantTable(crb, masm, byteCount, asRegister(constantTableBase), constant, scratchRegister, SPARCDelayedControlTransfer.DUMMY);
+ loadFromConstantTable(crb, masm, asRegister(constantTableBase), constant, scratchRegister, SPARCDelayedControlTransfer.DUMMY);
if (canUseShortBranch) {
CBCOND.emit(masm, conditionFlag, conditionCode == CC.Xcc, keyRegister, scratchRegister, target);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ArrayCopyIntrinsificationTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ArrayCopyIntrinsificationTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -160,7 +160,7 @@
}
/**
- * Tests {@link ArrayCopySnippets#checkcastArraycopyWork}.
+ * Tests {@link ArrayCopySnippets#arraycopyCheckcastSnippet}.
*/
@Test
public void testArrayStoreException() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -122,7 +122,7 @@
* Tests compilation requested by Truffle.
*/
@Test
- public void testTruffleCompilation() throws IOException, InterruptedException {
+ public void testTruffleCompilation1() throws IOException, InterruptedException {
testHelper(Collections.emptyList(),
Arrays.asList(
"-Dgraal.CompilationFailureAction=ExitVM",
@@ -130,6 +130,22 @@
"org.graalvm.compiler.truffle.test.SLTruffleGraalTestSuite", "test");
}
+ /**
+ * Tests that TruffleCompilationExceptionsAreFatal works as expected.
+ */
+ @Test
+ public void testTruffleCompilation2() throws IOException, InterruptedException {
+ Probe[] probes = {
+ new Probe("Exiting VM due to TruffleCompilationExceptionsAreFatal=true", 1),
+ };
+ testHelper(Arrays.asList(probes),
+ Arrays.asList(
+ "-Dgraal.CompilationFailureAction=Silent",
+ "-Dgraal.TruffleCompilationExceptionsAreFatal=true",
+ "-Dgraal.CrashAt=root test1"),
+ "org.graalvm.compiler.truffle.test.SLTruffleGraalTestSuite", "test");
+ }
+
private static final boolean VERBOSE = Boolean.getBoolean(CompilationWrapperTest.class.getSimpleName() + ".verbose");
private static void testHelper(List<Probe> initialProbes, List<String> extraVmArgs, String... mainClassAndArgs) throws IOException, InterruptedException {
@@ -149,14 +165,17 @@
}
List<Probe> probes = new ArrayList<>(initialProbes);
- Probe diagnosticProbe = new Probe("Graal diagnostic output saved in ", 1);
- probes.add(diagnosticProbe);
- probes.add(new Probe("Forced crash after compiling", Integer.MAX_VALUE) {
- @Override
- String test() {
- return actualOccurrences > 0 ? null : "expected at least 1 occurrence";
- }
- });
+ Probe diagnosticProbe = null;
+ if (!extraVmArgs.contains("-Dgraal.TruffleCompilationExceptionsAreFatal=true")) {
+ diagnosticProbe = new Probe("Graal diagnostic output saved in ", 1);
+ probes.add(diagnosticProbe);
+ probes.add(new Probe("Forced crash after compiling", Integer.MAX_VALUE) {
+ @Override
+ String test() {
+ return actualOccurrences > 0 ? null : "expected at least 1 occurrence";
+ }
+ });
+ }
for (String line : proc.output) {
for (Probe probe : probes) {
@@ -171,38 +190,42 @@
Assert.fail(String.format("Did not find expected occurences of '%s' in output of command: %s%n%s", probe.substring, error, proc));
}
}
+ if (diagnosticProbe != null) {
+ String line = diagnosticProbe.lastMatchingLine;
+ int substringStart = line.indexOf(diagnosticProbe.substring);
+ int substringLength = diagnosticProbe.substring.length();
+ String diagnosticOutputZip = line.substring(substringStart + substringLength).trim();
- String diagnosticOutputZip = diagnosticProbe.lastMatchingLine.substring(diagnosticProbe.substring.length()).trim();
-
- List<String> dumpPathEntries = Arrays.asList(dumpPath.list());
+ List<String> dumpPathEntries = Arrays.asList(dumpPath.list());
- File zip = new File(diagnosticOutputZip).getAbsoluteFile();
- Assert.assertTrue(zip.toString(), zip.exists());
- Assert.assertTrue(zip + " not in " + dumpPathEntries, dumpPathEntries.contains(zip.getName()));
- try {
- int bgv = 0;
- int cfg = 0;
- ZipFile dd = new ZipFile(diagnosticOutputZip);
- List<String> entries = new ArrayList<>();
- for (Enumeration<? extends ZipEntry> e = dd.entries(); e.hasMoreElements();) {
- ZipEntry ze = e.nextElement();
- String name = ze.getName();
- entries.add(name);
- if (name.endsWith(".bgv")) {
- bgv++;
- } else if (name.endsWith(".cfg")) {
- cfg++;
+ File zip = new File(diagnosticOutputZip).getAbsoluteFile();
+ Assert.assertTrue(zip.toString(), zip.exists());
+ Assert.assertTrue(zip + " not in " + dumpPathEntries, dumpPathEntries.contains(zip.getName()));
+ try {
+ int bgv = 0;
+ int cfg = 0;
+ ZipFile dd = new ZipFile(diagnosticOutputZip);
+ List<String> entries = new ArrayList<>();
+ for (Enumeration<? extends ZipEntry> e = dd.entries(); e.hasMoreElements();) {
+ ZipEntry ze = e.nextElement();
+ String name = ze.getName();
+ entries.add(name);
+ if (name.endsWith(".bgv")) {
+ bgv++;
+ } else if (name.endsWith(".cfg")) {
+ cfg++;
+ }
}
- }
- if (bgv == 0) {
- Assert.fail(String.format("Expected at least one .bgv file in %s: %s%n%s", diagnosticOutputZip, entries, proc));
+ if (bgv == 0) {
+ Assert.fail(String.format("Expected at least one .bgv file in %s: %s%n%s", diagnosticOutputZip, entries, proc));
+ }
+ if (cfg == 0) {
+ Assert.fail(String.format("Expected at least one .cfg file in %s: %s", diagnosticOutputZip, entries));
+ }
+ } finally {
+ zip.delete();
+ dumpPath.delete();
}
- if (cfg == 0) {
- Assert.fail(String.format("Expected at least one .cfg file in %s: %s", diagnosticOutputZip, entries));
- }
- } finally {
- zip.delete();
- dumpPath.delete();
}
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ExplicitExceptionTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ExplicitExceptionTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,23 +22,44 @@
*/
package org.graalvm.compiler.hotspot.test;
-import org.junit.Test;
-
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.extended.ForeignCallNode;
import org.graalvm.compiler.options.OptionValues;
+import org.junit.Assume;
+import org.junit.Test;
import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.meta.ProfilingInfo;
import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.TriState;
public class ExplicitExceptionTest extends GraalCompilerTest {
private int expectedForeignCallCount;
+ /**
+ * Determines if profiling info for {@code method} indicates an exception was thrown somewhere
+ * in the method. In the case of the {@code -Xcomp} VM option, interpreter execution can be
+ * skipped altogether and other execution engines (e.g., C1) may not record seen exceptions in a
+ * method profile.
+ */
+ private static boolean exceptionWasSeen(ResolvedJavaMethod method) {
+ ProfilingInfo profilingInfo = method.getProfilingInfo();
+ if (profilingInfo != null) {
+ for (int i = 0; i < profilingInfo.getCodeSize(); i++) {
+ if (profilingInfo.getExceptionSeen(i) == TriState.TRUE) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
@Override
protected InstalledCode getCode(ResolvedJavaMethod method, StructuredGraph graph, boolean forceCompile, boolean installAsDefault, OptionValues options) {
InstalledCode installedCode = super.getCode(method, graph, forceCompile, installAsDefault, options);
+ Assume.assumeTrue(exceptionWasSeen(method));
assertDeepEquals(expectedForeignCallCount, lastCompiledGraph.getNodes().filter(ForeignCallNode.class).count());
return installedCode;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRLockTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRLockTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -24,11 +24,13 @@
import java.lang.management.ManagementFactory;
import java.lang.management.MonitorInfo;
+import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.core.phases.HighTier;
@@ -44,6 +46,7 @@
import jdk.vm.ci.meta.ResolvedJavaMethod;
import org.junit.Assume;
+import org.junit.BeforeClass;
/**
* Test on-stack-replacement with locks.
@@ -51,13 +54,28 @@
public class GraalOSRLockTest extends GraalOSRTestBase {
private static boolean TestInSeparateThread = false;
+ private static final String COMPILE_ONLY_FLAG = "-Xcomp";
- public GraalOSRLockTest() {
+ @BeforeClass
+ public static void checkVMArguments() {
try {
Class.forName("java.lang.management.ManagementFactory");
} catch (ClassNotFoundException ex) {
Assume.assumeNoException("cannot check for monitors without java.management JDK9 module", ex);
}
+ /*
+ * Note: The -Xcomp execution mode of the VM will stop most of the OSR test cases from
+ * working as every method is compiled at level3 (followed by level4 on the second
+ * invocation). The tests in this class are written in a way that they expect a method to be
+ * executed at the invocation BCI with the interpreter and then perform an OSR to an
+ * installed nmethod at a given BCI.
+ *
+ */
+ RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
+ List<String> arguments = runtimeMxBean.getInputArguments();
+ for (String arg : arguments) {
+ Assume.assumeFalse(arg.equals(COMPILE_ONLY_FLAG));
+ }
}
// testing only
@@ -438,7 +456,7 @@
}
GraalDirectives.controlFlowAnchor();
if (!GraalDirectives.inCompiledCode()) {
- throw new Error("Must part of compiled code");
+ throw new Error("Must be part of compiled code");
}
return ret;
}
@@ -449,11 +467,11 @@
ReturnValue ret = ReturnValue.FAILURE;
synchronized (lock) {
synchronized (lock1) {
- for (int i = 1; i < limit; i++) {
+ for (int i = 1; i < 10 * limit; i++) {
GraalDirectives.blackhole(i);
- if (i % 1001 == 0) {
+ if (i % 33 == 0) {
ret = ReturnValue.SUCCESS;
- if (GraalDirectives.inCompiledCode() && i + 33 > (limit)) {
+ if (GraalDirectives.inCompiledCode() && i + 33 > (10 * limit)) {
GraalDirectives.blackhole(ret);
System.gc();
}
@@ -462,7 +480,7 @@
}
GraalDirectives.controlFlowAnchor();
if (!GraalDirectives.inCompiledCode()) {
- throw new Error("Must part of compiled code");
+ throw new Error("Must be part of compiled code already hereeeeee");
} else {
// lock 1 must be free
if (isMonitorLockHeld(lock1)) {
@@ -519,7 +537,7 @@
}
GraalDirectives.controlFlowAnchor();
if (!GraalDirectives.inCompiledCode()) {
- throw new Error("Must part of compiled code");
+ throw new Error("Must be part of compiled code");
}
return ret;
}
@@ -543,7 +561,7 @@
}
GraalDirectives.controlFlowAnchor();
if (!GraalDirectives.inCompiledCode()) {
- throw new Error("Must part of compiled code");
+ throw new Error("Must be part of compiled code");
}
return ret;
}
@@ -568,7 +586,7 @@
}
GraalDirectives.controlFlowAnchor();
if (!GraalDirectives.inCompiledCode()) {
- throw new Error("Must part of compiled code");
+ throw new Error("Must be part of compiled code");
}
return ret;
}
@@ -646,7 +664,7 @@
synchronized (monitor) {
GraalDirectives.controlFlowAnchor();
if (!GraalDirectives.inCompiledCode()) {
- throw new Error("Must part of compiled code");
+ throw new Error("Must be part of compiled code");
}
}
return ret;
@@ -670,7 +688,7 @@
}
GraalDirectives.controlFlowAnchor();
if (!GraalDirectives.inCompiledCode()) {
- throw new Error("Must part of compiled code");
+ throw new Error("Must be part of compiled code");
}
return ret;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTestBase.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTestBase.java Wed Nov 08 16:03:35 2017 -0500
@@ -35,7 +35,9 @@
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.debug.TTY;
import org.graalvm.compiler.hotspot.CompilationTask;
+import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.HotSpotGraalCompiler;
+import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
import org.graalvm.compiler.java.BciBlockMapping;
import org.graalvm.compiler.java.BciBlockMapping.BciBlock;
import org.graalvm.compiler.nodes.StructuredGraph;
@@ -76,6 +78,13 @@
HotSpotCompilationRequest request = new HotSpotCompilationRequest((HotSpotResolvedJavaMethod) method, bci, jvmciEnv);
HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) runtime.getCompiler();
CompilationTask task = new CompilationTask(runtime, compiler, request, true, true, debug.getOptions());
+ if (method instanceof HotSpotResolvedJavaMethod) {
+ HotSpotGraalRuntimeProvider graalRuntime = compiler.getGraalRuntime();
+ GraalHotSpotVMConfig config = graalRuntime.getVMConfig();
+ if (((HotSpotResolvedJavaMethod) method).hasCodeAtLevel(bci, config.compilationLevelFullOptimization)) {
+ return;
+ }
+ }
HotSpotCompilationRequestResult result = task.runCompilation(debug);
if (result.getFailure() != null) {
throw new GraalError(result.getFailureMessage());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierVerificationTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierVerificationTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -37,7 +37,6 @@
import org.graalvm.compiler.hotspot.nodes.SerialWriteBarrier;
import org.graalvm.compiler.hotspot.phases.WriteBarrierAdditionPhase;
import org.graalvm.compiler.hotspot.phases.WriteBarrierVerificationPhase;
-import org.graalvm.compiler.hotspot.replacements.arraycopy.UnsafeArrayCopyNode;
import org.graalvm.compiler.nodes.AbstractBeginNode;
import org.graalvm.compiler.nodes.AbstractMergeNode;
import org.graalvm.compiler.nodes.FieldLocationIdentity;
@@ -629,12 +628,6 @@
System.arraycopy(a, 0, b, 0, a.length);
}
- @Test
- public void test61() {
- GraphPredicate checkForUnsafeArrayCopy = graph -> graph.getNodes().filter(UnsafeArrayCopyNode.class).count() > 0 ? 1 : 0;
- testPredicate("test13Snippet", checkForUnsafeArrayCopy, new int[]{});
- }
-
private interface GraphPredicate {
int apply(StructuredGraph graph);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -280,14 +280,19 @@
}
if (offset == -1) {
try {
- offset = getFieldOffset(name, Integer.class, "OopHandle");
+ offset = getFieldOffset(name, Integer.class, "jobject");
isHandle = true;
} catch (JVMCIError e) {
-
+ try {
+ // JDK-8186777
+ offset = getFieldOffset(name, Integer.class, "OopHandle");
+ isHandle = true;
+ } catch (JVMCIError e2) {
+ }
}
}
if (offset == -1) {
- throw new JVMCIError("cannot get offset of field " + name + " with type oop or OopHandle");
+ throw new JVMCIError("cannot get offset of field " + name + " with type oop, jobject or OopHandle");
}
classMirrorOffset = offset;
classMirrorIsHandle = isHandle;
@@ -648,6 +653,8 @@
public final long heapEndAddress = getFieldValue("CompilerToVM::Data::_heap_end_addr", Long.class, "HeapWord**");
public final long heapTopAddress = getFieldValue("CompilerToVM::Data::_heap_top_addr", Long.class, isJDK8 ? "HeapWord**" : "HeapWord* volatile*");
+ public final boolean cmsIncrementalMode = getFlag("CMSIncrementalMode", Boolean.class, false);
+
public final long inlineCacheMissStub = getFieldValue("CompilerToVM::Data::SharedRuntime_ic_miss_stub", Long.class, "address");
public final long handleWrongMethodStub = getFieldValue("CompilerToVM::Data::SharedRuntime_handle_wrong_method_stub", Long.class, "address");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java Wed Nov 08 16:03:35 2017 -0500
@@ -266,6 +266,8 @@
unsafeArraycopyStub(HotSpotBackend.UNSAFE_ARRAYCOPY, srcAddr, dstAddr, size);
}
+ public static final ForeignCallDescriptor GENERIC_ARRAYCOPY = new ForeignCallDescriptor("generic_arraycopy", int.class, Word.class, int.class, Word.class, int.class, int.class);
+
@NodeIntrinsic(ForeignCallNode.class)
private static native void unsafeArraycopyStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word srcAddr, Word dstAddr, Word size);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java Wed Nov 08 16:03:35 2017 -0500
@@ -284,7 +284,7 @@
public Object mbean() {
if (graalRuntime instanceof HotSpotGraalRuntime) {
- return ((HotSpotGraalRuntime)graalRuntime).mbean();
+ return ((HotSpotGraalRuntime) graalRuntime).getMBean();
}
return null;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java Wed Nov 08 16:03:35 2017 -0500
@@ -26,6 +26,8 @@
import static org.graalvm.compiler.hotspot.HotSpotGraalOptionValues.GRAAL_OPTION_PROPERTY_PREFIX;
import java.io.PrintStream;
+import java.util.Map;
+import java.util.Collections;
import org.graalvm.compiler.debug.MethodFilter;
import org.graalvm.compiler.options.Option;
@@ -190,4 +192,11 @@
}
return level;
}
+
+ public Map<String, Object> mbeans() {
+ HotSpotGraalCompiler compiler = createCompiler(HotSpotJVMCIRuntime.runtime());
+ String name = "org.graalvm.compiler.hotspot:type=Options";
+ Object bean = ((HotSpotGraalRuntime) compiler.getGraalRuntime()).getMBean();
+ return Collections.singletonMap(name, bean);
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalMBean.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalMBean.java Wed Nov 08 16:03:35 2017 -0500
@@ -283,10 +283,8 @@
@Override
public javax.management.MBeanInfo getMBeanInfo() {
List<javax.management.MBeanAttributeInfo> attrs = new ArrayList<>();
- if (registered != null) {
- for (OptionDescriptor descr : allOptionDescriptors()) {
- attrs.add(new javax.management.MBeanAttributeInfo(descr.getName(), descr.getType().getName(), descr.getHelp(), true, true, false));
- }
+ for (OptionDescriptor descr : allOptionDescriptors()) {
+ attrs.add(new javax.management.MBeanAttributeInfo(descr.getName(), descr.getType().getName(), descr.getHelp(), true, true, false));
}
javax.management.MBeanOperationInfo[] ops = {
new javax.management.MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new javax.management.MBeanParameterInfo[]{
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java Wed Nov 08 16:03:35 2017 -0500
@@ -317,7 +317,7 @@
return compilationProblemsPerAction;
}
- final Object mbean() {
+ Object getMBean() {
return mBean;
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java Wed Nov 08 16:03:35 2017 -0500
@@ -28,8 +28,8 @@
import static org.graalvm.compiler.core.common.GraalOptions.OmitHotExceptionStacktrace;
import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl.OSR_MIGRATION_END;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_KLASS_LOCATION;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_MIRROR_HANDLE_LOCATION;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_MIRROR_LOCATION;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_MIRROR_HANDLE_LOCATION;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.COMPRESSED_HUB_LOCATION;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.DISPLACED_MARK_WORD_LOCATION;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.HUB_LOCATION;
@@ -41,6 +41,7 @@
import java.lang.ref.Reference;
import org.graalvm.compiler.api.directives.GraalDirectives;
+import org.graalvm.compiler.core.common.CompressEncoding;
import org.graalvm.compiler.core.common.GraalOptions;
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
@@ -90,10 +91,8 @@
import org.graalvm.compiler.hotspot.replacements.WriteBarrierSnippets;
import org.graalvm.compiler.hotspot.replacements.aot.ResolveConstantSnippets;
import org.graalvm.compiler.hotspot.replacements.arraycopy.ArrayCopyNode;
-import org.graalvm.compiler.hotspot.replacements.arraycopy.ArrayCopySlowPathNode;
+import org.graalvm.compiler.hotspot.replacements.arraycopy.ArrayCopyWithSlowPathNode;
import org.graalvm.compiler.hotspot.replacements.arraycopy.ArrayCopySnippets;
-import org.graalvm.compiler.hotspot.replacements.arraycopy.ArrayCopyUnrollNode;
-import org.graalvm.compiler.hotspot.replacements.arraycopy.UnsafeArrayCopySnippets;
import org.graalvm.compiler.hotspot.replacements.profiling.ProfileSnippets;
import org.graalvm.compiler.hotspot.word.KlassPointer;
import org.graalvm.compiler.nodes.AbstractBeginNode;
@@ -193,7 +192,7 @@
public DefaultHotSpotLoweringProvider(HotSpotGraalRuntimeProvider runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers,
HotSpotConstantReflectionProvider constantReflection, TargetDescription target) {
- super(metaAccess, foreignCalls, target);
+ super(metaAccess, foreignCalls, target, runtime.getVMConfig().useCompressedOops);
this.runtime = runtime;
this.registers = registers;
this.constantReflection = constantReflection;
@@ -216,7 +215,6 @@
hashCodeSnippets = new HashCodeSnippets.Templates(options, factories, providers, target);
resolveConstantSnippets = new ResolveConstantSnippets.Templates(options, factories, providers, target);
profileSnippets = new ProfileSnippets.Templates(options, factories, providers, target);
- providers.getReplacements().registerSnippetTemplateCache(new UnsafeArrayCopySnippets.Templates(options, factories, providers, target));
}
public MonitorSnippets.Templates getMonitorSnippets() {
@@ -315,10 +313,8 @@
}
} else if (n instanceof ArrayCopyNode) {
arraycopySnippets.lower((ArrayCopyNode) n, tool);
- } else if (n instanceof ArrayCopySlowPathNode) {
- arraycopySnippets.lower((ArrayCopySlowPathNode) n, tool);
- } else if (n instanceof ArrayCopyUnrollNode) {
- arraycopySnippets.lower((ArrayCopyUnrollNode) n, tool);
+ } else if (n instanceof ArrayCopyWithSlowPathNode) {
+ arraycopySnippets.lower((ArrayCopyWithSlowPathNode) n, tool);
} else if (n instanceof G1PreWriteBarrier) {
writeBarrierSnippets.lower((G1PreWriteBarrier) n, registers, tool);
} else if (n instanceof G1PostWriteBarrier) {
@@ -495,20 +491,18 @@
}
}
- @Override
- protected Stamp loadStamp(Stamp stamp, JavaKind kind, boolean compressible) {
- if (kind == JavaKind.Object && compressible && runtime.getVMConfig().useCompressedOops) {
- return HotSpotNarrowOopStamp.compressed((ObjectStamp) stamp, runtime.getVMConfig().getOopEncoding());
- }
- return super.loadStamp(stamp, kind, compressible);
+ private CompressEncoding getOopEncoding() {
+ return runtime.getVMConfig().getOopEncoding();
}
@Override
- protected ValueNode implicitLoadConvert(JavaKind kind, ValueNode value, boolean compressible) {
- if (kind == JavaKind.Object && compressible && runtime.getVMConfig().useCompressedOops) {
- return new HotSpotCompressionNode(CompressionOp.Uncompress, value, runtime.getVMConfig().getOopEncoding());
- }
- return super.implicitLoadConvert(kind, value, compressible);
+ protected Stamp loadCompressedStamp(ObjectStamp stamp) {
+ return HotSpotNarrowOopStamp.compressed(stamp, getOopEncoding());
+ }
+
+ @Override
+ protected ValueNode newCompressionNode(CompressionOp op, ValueNode value) {
+ return new HotSpotCompressionNode(op, value, getOopEncoding());
}
@Override
@@ -519,14 +513,6 @@
}
@Override
- protected ValueNode implicitStoreConvert(JavaKind kind, ValueNode value, boolean compressible) {
- if (kind == JavaKind.Object && compressible && runtime.getVMConfig().useCompressedOops) {
- return new HotSpotCompressionNode(CompressionOp.Compress, value, runtime.getVMConfig().getOopEncoding());
- }
- return super.implicitStoreConvert(kind, value, compressible);
- }
-
- @Override
protected ValueNode createReadArrayComponentHub(StructuredGraph graph, ValueNode arrayHub, FixedNode anchor) {
/*
* Anchor the read of the element klass to the cfg, because it is only valid when arrayClass
@@ -800,4 +786,9 @@
public int arrayLengthOffset() {
return runtime.getVMConfig().arrayOopDescLengthOffset();
}
+
+ @Override
+ protected final JavaKind getStorageKind(ResolvedJavaField field) {
+ return field.getJavaKind();
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Wed Nov 08 16:03:35 2017 -0500
@@ -39,6 +39,7 @@
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.bytecode.BytecodeProvider;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
+import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.nodes.CurrentJavaThreadNode;
@@ -68,6 +69,7 @@
import org.graalvm.compiler.nodes.PiNode;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.AddNode;
+import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
import org.graalvm.compiler.nodes.calc.LeftShiftNode;
import org.graalvm.compiler.nodes.graphbuilderconf.ForeignCallPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
@@ -316,8 +318,8 @@
private static boolean readMetaspaceConstantPoolElement(GraphBuilderContext b, ValueNode constantPoolOop, ValueNode index, JavaKind elementKind, WordTypes wordTypes, GraalHotSpotVMConfig config) {
ValueNode constants = getMetaspaceConstantPool(b, constantPoolOop, wordTypes, config);
int shift = CodeUtil.log2(wordTypes.getWordKind().getByteCount());
- ValueNode scaledIndex = b.add(new LeftShiftNode(index, b.add(ConstantNode.forInt(shift))));
- ValueNode offset = b.add(new AddNode(scaledIndex, b.add(ConstantNode.forInt(config.constantPoolSize))));
+ ValueNode scaledIndex = b.add(new LeftShiftNode(IntegerConvertNode.convert(index, StampFactory.forKind(JavaKind.Long)), b.add(ConstantNode.forInt(shift))));
+ ValueNode offset = b.add(new AddNode(scaledIndex, b.add(ConstantNode.forLong(config.constantPoolSize))));
AddressNode elementAddress = b.add(new OffsetAddressNode(constants, offset));
boolean notCompressible = false;
ValueNode elementValue = WordOperationPlugin.readOp(b, elementKind, elementAddress, NamedLocationIdentity.getArrayLocation(elementKind), BarrierType.NONE, notCompressible);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java Wed Nov 08 16:03:35 2017 -0500
@@ -34,6 +34,7 @@
import static org.graalvm.compiler.hotspot.HotSpotBackend.ENCRYPT;
import static org.graalvm.compiler.hotspot.HotSpotBackend.ENCRYPT_BLOCK;
import static org.graalvm.compiler.hotspot.HotSpotBackend.EXCEPTION_HANDLER;
+import static org.graalvm.compiler.hotspot.HotSpotBackend.GENERIC_ARRAYCOPY;
import static org.graalvm.compiler.hotspot.HotSpotBackend.IC_MISS_HANDLER;
import static org.graalvm.compiler.hotspot.HotSpotBackend.INITIALIZE_KLASS_BY_SYMBOL;
import static org.graalvm.compiler.hotspot.HotSpotBackend.INVOCATION_EVENT;
@@ -85,7 +86,6 @@
import static org.graalvm.compiler.hotspot.stubs.NewInstanceStub.NEW_INSTANCE_C;
import static org.graalvm.compiler.hotspot.stubs.StubUtil.VM_MESSAGE_C;
import static org.graalvm.compiler.hotspot.stubs.UnwindExceptionToCallerStub.EXCEPTION_HANDLER_FOR_RETURN_ADDRESS;
-import static org.graalvm.compiler.nodes.NamedLocationIdentity.any;
import static org.graalvm.compiler.nodes.java.ForeignCallDescriptors.REGISTER_FINALIZER;
import static org.graalvm.compiler.replacements.Log.LOG_OBJECT;
import static org.graalvm.compiler.replacements.Log.LOG_PRIMITIVE;
@@ -97,6 +97,7 @@
import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG10;
import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.SIN;
import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.TAN;
+import static org.graalvm.word.LocationIdentity.any;
import java.util.EnumMap;
@@ -213,7 +214,7 @@
// c_rarg4 - oop ckval (super_klass)
// return: 0 = success, n = number of copied elements xor'd with -1.
ForeignCallDescriptor desc = new ForeignCallDescriptor(name, int.class, Word.class, Word.class, Word.class, Word.class, Word.class);
- LocationIdentity killed = NamedLocationIdentity.getArrayLocation(JavaKind.Object);
+ LocationIdentity killed = NamedLocationIdentity.any();
registerForeignCall(desc, routine, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, killed);
checkcastArraycopyDescriptors[uninit ? 1 : 0] = desc;
}
@@ -333,6 +334,7 @@
registerCheckcastArraycopyDescriptor(true, c.checkcastArraycopyUninit);
registerCheckcastArraycopyDescriptor(false, c.checkcastArraycopy);
+ registerForeignCall(GENERIC_ARRAYCOPY, c.genericArraycopy, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.any());
registerForeignCall(UNSAFE_ARRAYCOPY, c.unsafeArraycopy, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.any());
if (c.useMultiplyToLenIntrinsic()) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicConstantNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicConstantNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -28,6 +28,7 @@
import org.graalvm.word.LocationIdentity;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
import org.graalvm.compiler.nodes.ValueNode;
@@ -35,7 +36,7 @@
import org.graalvm.compiler.nodes.spi.Lowerable;
import org.graalvm.compiler.nodes.spi.LoweringTool;
-@NodeInfo(cycles = CYCLES_4, size = SIZE_16)
+@NodeInfo(cycles = CYCLES_4, size = SIZE_16, allowedUsageTypes = {InputType.Memory})
public class ResolveDynamicConstantNode extends DeoptimizingFixedWithNextNode implements Lowerable, MemoryCheckpoint.Single {
public static final NodeClass<ResolveDynamicConstantNode> TYPE = NodeClass.create(ResolveDynamicConstantNode.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileBranchNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileBranchNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -71,6 +71,15 @@
return branchCondition != null;
}
+ @Override
+ protected boolean canBeMergedWith(ProfileNode p) {
+ if (p instanceof ProfileBranchNode) {
+ ProfileBranchNode that = (ProfileBranchNode) p;
+ return this.method.equals(that.method) && this.bci == that.bci;
+ }
+ return false;
+ }
+
/**
* Gathers all the {@link ProfileBranchNode}s that are inputs to the
* {@linkplain StructuredGraph#getNodes() live nodes} in a given graph.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileInvokeNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileInvokeNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -37,6 +37,15 @@
super(TYPE, method, freqLog, probabilityLog);
}
+ @Override
+ protected boolean canBeMergedWith(ProfileNode p) {
+ if (p instanceof ProfileInvokeNode) {
+ ProfileInvokeNode that = (ProfileInvokeNode) p;
+ return this.method.equals(that.method);
+ }
+ return false;
+ }
+
/**
* Gathers all the {@link ProfileInvokeNode}s that are inputs to the
* {@linkplain StructuredGraph#getNodes() live nodes} in a given graph.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -24,11 +24,17 @@
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED;
+import static org.graalvm.compiler.nodes.util.GraphUtil.removeFixedWithUnusedInputs;
import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.iterators.NodeIterable;
+import org.graalvm.compiler.graph.spi.Simplifiable;
+import org.graalvm.compiler.graph.spi.SimplifierTool;
import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.AbstractMergeNode;
+import org.graalvm.compiler.nodes.ControlSplitNode;
import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
@@ -41,7 +47,7 @@
import jdk.vm.ci.meta.ResolvedJavaMethod;
@NodeInfo(cycles = CYCLES_IGNORED, cyclesRationale = "profiling should be ignored", size = SIZE_IGNORED, sizeRationale = "profiling should be ignored")
-public class ProfileNode extends DeoptimizingFixedWithNextNode implements Lowerable {
+public abstract class ProfileNode extends DeoptimizingFixedWithNextNode implements Simplifiable, Lowerable {
public static class Options {
@Option(help = "Control probabilistic profiling on AMD64", type = OptionType.Expert)//
public static final OptionKey<Boolean> ProbabilisticProfiling = new OptionKey<>(true);
@@ -54,19 +60,21 @@
// Only used if ProbabilisticProfiling == true and may be ignored by lowerer.
@OptionalInput protected ValueNode random;
- // logarithm base 2 of the profile probability
+ // Logarithm base 2 of the profile probability.
protected int probabilityLog;
+ // Step value to add to the profile counter.
+ protected int step;
+
protected ProfileNode(NodeClass<? extends DeoptimizingFixedWithNextNode> c, ResolvedJavaMethod method, int probabilityLog) {
super(c, StampFactory.forVoid());
this.method = method;
this.probabilityLog = probabilityLog;
+ this.step = 1;
}
public ProfileNode(ResolvedJavaMethod method, int probabilityLog) {
- super(TYPE, StampFactory.forVoid());
- this.method = method;
- this.probabilityLog = probabilityLog;
+ this(TYPE, method, probabilityLog);
}
@Override
@@ -92,6 +100,14 @@
this.random = r;
}
+ public int getStep() {
+ return step;
+ }
+
+ public void setStep(int s) {
+ step = s;
+ }
+
/**
* Get the logarithm base 2 of the profile probability.
*/
@@ -106,4 +122,25 @@
public static NodeIterable<ProfileNode> getProfileNodes(StructuredGraph graph) {
return graph.getNodes().filter(ProfileNode.class);
}
+
+ protected abstract boolean canBeMergedWith(ProfileNode p);
+
+ @Override
+ public void simplify(SimplifierTool tool) {
+ for (Node p = predecessor(); p != null; p = p.predecessor()) {
+ // Terminate search when we hit a control split or merge.
+ if (p instanceof ControlSplitNode || p instanceof AbstractMergeNode) {
+ break;
+ }
+ if (p instanceof ProfileNode) {
+ ProfileNode that = (ProfileNode) p;
+ if (this.canBeMergedWith(that)) {
+ that.setStep(this.getStep() + that.getStep());
+ removeFixedWithUnusedInputs(this);
+ tool.addToWorkList(that);
+ break;
+ }
+ }
+ }
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileWithNotificationNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileWithNotificationNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -28,7 +28,7 @@
import jdk.vm.ci.meta.ResolvedJavaMethod;
@NodeInfo
-public class ProfileWithNotificationNode extends ProfileNode {
+public abstract class ProfileWithNotificationNode extends ProfileNode {
public static final NodeClass<ProfileWithNotificationNode> TYPE = NodeClass.create(ProfileWithNotificationNode.class);
protected int freqLog;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,10 +22,16 @@
*/
package org.graalvm.compiler.hotspot.phases;
+import static jdk.vm.ci.meta.SpeculationLog.SpeculationReason;
import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Required;
+import jdk.vm.ci.meta.DeoptimizationAction;
+import jdk.vm.ci.meta.DeoptimizationReason;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
import org.graalvm.compiler.core.common.PermanentBailoutException;
import org.graalvm.compiler.core.common.cfg.Loop;
+import org.graalvm.compiler.core.common.type.ObjectStamp;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.debug.CounterKey;
import org.graalvm.compiler.debug.DebugContext;
@@ -37,13 +43,15 @@
import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodeinfo.Verbosity;
import org.graalvm.compiler.nodes.AbstractBeginNode;
-import org.graalvm.compiler.nodes.AbstractLocalNode;
import org.graalvm.compiler.nodes.EntryMarkerNode;
import org.graalvm.compiler.nodes.EntryProxyNode;
+import org.graalvm.compiler.nodes.FixedGuardNode;
import org.graalvm.compiler.nodes.FixedNode;
import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.LogicNode;
import org.graalvm.compiler.nodes.LoopBeginNode;
import org.graalvm.compiler.nodes.ParameterNode;
+import org.graalvm.compiler.nodes.PiNode;
import org.graalvm.compiler.nodes.StartNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
@@ -53,6 +61,7 @@
import org.graalvm.compiler.nodes.extended.OSRMonitorEnterNode;
import org.graalvm.compiler.nodes.extended.OSRStartNode;
import org.graalvm.compiler.nodes.java.AccessMonitorNode;
+import org.graalvm.compiler.nodes.java.InstanceOfNode;
import org.graalvm.compiler.nodes.java.MonitorEnterNode;
import org.graalvm.compiler.nodes.java.MonitorExitNode;
import org.graalvm.compiler.nodes.java.MonitorIdNode;
@@ -172,15 +181,32 @@
if (value instanceof EntryProxyNode) {
EntryProxyNode proxy = (EntryProxyNode) value;
/*
- * we need to drop the stamp since the types we see during OSR may be too precise
- * (if a branch was not parsed for example).
+ * We need to drop the stamp since the types we see during OSR may be too precise
+ * (if a branch was not parsed for example). In cases when this is possible, we
+ * insert a guard and narrow the OSRLocal stamp at its usages.
*/
- Stamp s = proxy.stamp().unrestricted();
- AbstractLocalNode osrLocal = null;
+ Stamp narrowedStamp = proxy.value().stamp();
+ Stamp unrestrictedStamp = proxy.stamp().unrestricted();
+ ValueNode osrLocal;
if (i >= localsSize) {
- osrLocal = graph.addOrUnique(new OSRLockNode(i - localsSize, s));
+ osrLocal = graph.addOrUnique(new OSRLockNode(i - localsSize, unrestrictedStamp));
} else {
- osrLocal = graph.addOrUnique(new OSRLocalNode(i, s));
+ osrLocal = graph.addOrUnique(new OSRLocalNode(i, unrestrictedStamp));
+ }
+ // Speculate on the OSRLocal stamps that could be more precise.
+ OSRLocalSpeculationReason reason = new OSRLocalSpeculationReason(osrState.bci, narrowedStamp, i);
+ if (graph.getSpeculationLog().maySpeculate(reason) && osrLocal instanceof OSRLocalNode && value.getStackKind().equals(JavaKind.Object) && !narrowedStamp.isUnrestricted()) {
+ // Add guard.
+ LogicNode check = graph.addOrUniqueWithInputs(InstanceOfNode.createHelper((ObjectStamp) narrowedStamp, osrLocal, null, null));
+ JavaConstant constant = graph.getSpeculationLog().speculate(reason);
+ FixedGuardNode guard = graph.add(new FixedGuardNode(check, DeoptimizationReason.OptimizedTypeCheckViolated, DeoptimizationAction.InvalidateRecompile, constant, false));
+ graph.addAfterFixed(osrStart, guard);
+
+ // Replace with a more specific type at usages.
+ // We know that we are at the root,
+ // so we need to replace the proxy in the state.
+ proxy.replaceAtMatchingUsages(osrLocal, n -> n == osrState);
+ osrLocal = graph.addOrUnique(new PiNode(osrLocal, narrowedStamp, guard));
}
proxy.replaceAndDelete(osrLocal);
} else {
@@ -268,4 +294,30 @@
public float codeSizeIncrease() {
return 5.0f;
}
+
+ private static class OSRLocalSpeculationReason implements SpeculationReason {
+ private int bci;
+ private Stamp speculatedStamp;
+ private int localIndex;
+
+ OSRLocalSpeculationReason(int bci, Stamp speculatedStamp, int localIndex) {
+ this.bci = bci;
+ this.speculatedStamp = speculatedStamp;
+ this.localIndex = localIndex;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof OSRLocalSpeculationReason) {
+ OSRLocalSpeculationReason that = (OSRLocalSpeculationReason) obj;
+ return this.bci == that.bci && this.speculatedStamp.equals(that.speculatedStamp) && this.localIndex == that.localIndex;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return (bci << 16) ^ speculatedStamp.hashCode() ^ localIndex;
+ }
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java Wed Nov 08 16:03:35 2017 -0500
@@ -670,6 +670,11 @@
}
@Fold
+ public static boolean useCMSIncrementalMode(@InjectedParameter GraalHotSpotVMConfig config) {
+ return config.cmsIncrementalMode;
+ }
+
+ @Fold
public static boolean useCompressedOops(@InjectedParameter GraalHotSpotVMConfig config) {
return config.useCompressedOops;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HubGetClassNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HubGetClassNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -71,7 +71,7 @@
return null;
} else {
MetaAccessProvider metaAccess = tool.getMetaAccess();
- if (metaAccess != null && hub.isConstant() && !GraalOptions.ImmutableCode.getValue(graph().getOptions())) {
+ if (metaAccess != null && hub.isConstant() && !GraalOptions.ImmutableCode.getValue(tool.getOptions())) {
ResolvedJavaType exactType = tool.getConstantReflection().asJavaType(hub.asConstant());
if (exactType != null) {
return ConstantNode.forConstant(tool.getConstantReflection().asJavaClass(exactType), metaAccess);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/IdentityHashCodeNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/IdentityHashCodeNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -67,7 +67,7 @@
if (object.isConstant()) {
assert object.stamp() instanceof AbstractObjectStamp;
JavaConstant c = (JavaConstant) object.asConstant();
- if (ImmutableCode.getValue(getOptions())) {
+ if (ImmutableCode.getValue(tool.getOptions())) {
return this;
}
JavaConstant identityHashCode = null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySlowPathNode.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.hotspot.replacements.arraycopy;
-
-import jdk.vm.ci.code.BytecodeFrame;
-import jdk.vm.ci.meta.JavaKind;
-
-import static org.graalvm.word.LocationIdentity.any;
-
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.hotspot.word.KlassPointer;
-import org.graalvm.compiler.nodeinfo.InputType;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.NamedLocationIdentity;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.type.StampTool;
-import org.graalvm.compiler.replacements.SnippetTemplate;
-import org.graalvm.compiler.replacements.nodes.BasicArrayCopyNode;
-import org.graalvm.word.LocationIdentity;
-
-@NodeInfo(allowedUsageTypes = InputType.Memory)
-public final class ArrayCopySlowPathNode extends BasicArrayCopyNode {
-
- public static final NodeClass<ArrayCopySlowPathNode> TYPE = NodeClass.create(ArrayCopySlowPathNode.class);
-
- private final SnippetTemplate.SnippetInfo snippet;
-
- /**
- * Extra context for the slow path snippet.
- */
- private final Object argument;
-
- /**
- * AOT compilation requires klass constants to be exposed after the first lowering to be handled
- * automatically. Lowering for {@link ArrayCopySlowPathNode}, with snippet ==
- * {@link ArrayCopySnippets#arraycopyPredictedObjectWork}, requires a klass of Object[]. For
- * other snippets {@link #predictedKlass} is a null constant.
- */
- @Input protected ValueNode predictedKlass;
-
- public ArrayCopySlowPathNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode predictedKlass, JavaKind elementKind,
- SnippetTemplate.SnippetInfo snippet, Object argument) {
- super(TYPE, src, srcPos, dest, destPos, length, elementKind, BytecodeFrame.INVALID_FRAMESTATE_BCI);
- assert StampTool.isPointerNonNull(src) && StampTool.isPointerNonNull(dest) : "must have been null checked";
- this.snippet = snippet;
- this.argument = argument;
- this.predictedKlass = predictedKlass;
- }
-
- @NodeIntrinsic
- public static native void arraycopy(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, KlassPointer predictedKlass,
- @ConstantNodeParameter JavaKind elementKind, @ConstantNodeParameter SnippetTemplate.SnippetInfo snippet, @ConstantNodeParameter Object argument);
-
- public SnippetTemplate.SnippetInfo getSnippet() {
- return snippet;
- }
-
- public Object getArgument() {
- return argument;
- }
-
- @Override
- public LocationIdentity getLocationIdentity() {
- if (elementKind != null) {
- return NamedLocationIdentity.getArrayLocation(elementKind);
- }
- return any();
- }
-
- public void setBci(int bci) {
- this.bci = bci;
- }
-
- public ValueNode getPredictedKlass() {
- return predictedKlass;
- }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySnippets.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySnippets.java Wed Nov 08 16:03:35 2017 -0500
@@ -28,11 +28,12 @@
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayBaseOffset;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayClassElementOffset;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayIndexScale;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperElementTypePrimitiveInPlace;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.loadHub;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readLayoutHelper;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.superCheckOffsetOffset;
-import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FAST_PATH_PROBABILITY;
+import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FREQUENT_PROBABILITY;
+import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.LIKELY_PROBABILITY;
+import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.NOT_FREQUENT_PROBABILITY;
import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.SLOW_PATH_PROBABILITY;
import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability;
@@ -47,10 +48,8 @@
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
-import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
import org.graalvm.compiler.hotspot.word.KlassPointer;
import org.graalvm.compiler.nodes.CallTargetNode;
-import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.DeoptimizeNode;
import org.graalvm.compiler.nodes.Invoke;
import org.graalvm.compiler.nodes.InvokeNode;
@@ -65,8 +64,10 @@
import org.graalvm.compiler.nodes.type.StampTool;
import org.graalvm.compiler.nodes.util.GraphUtil;
import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.replacements.ReplacementsUtil;
import org.graalvm.compiler.replacements.SnippetCounter;
import org.graalvm.compiler.replacements.SnippetCounter.Group;
+import org.graalvm.compiler.replacements.SnippetIntegerHistogram;
import org.graalvm.compiler.replacements.SnippetTemplate;
import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
@@ -79,16 +80,208 @@
import org.graalvm.word.WordFactory;
import jdk.vm.ci.code.TargetDescription;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import jdk.vm.ci.meta.DeoptimizationAction;
import jdk.vm.ci.meta.DeoptimizationReason;
-import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
public class ArrayCopySnippets implements Snippets {
+ private enum ArrayCopyTypeCheck {
+ UNDEFINED_ARRAY_TYPE_CHECK,
+ // we know that both objects are arrays and have the same type
+ NO_ARRAY_TYPE_CHECK,
+ // can be used when we know that one of the objects is a primitive array
+ HUB_BASED_ARRAY_TYPE_CHECK,
+ // must be used when we don't have sufficient information to use one of the others
+ LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK
+ }
+
+ @Snippet
+ public static void arraycopyZeroLengthSnippet(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter ArrayCopyTypeCheck arrayTypeCheck,
+ @ConstantParameter Counters counters) {
+ Object nonNullSrc = GraalDirectives.guardingNonNull(src);
+ Object nonNullDest = GraalDirectives.guardingNonNull(dest);
+ checkArrayTypes(nonNullSrc, nonNullDest, arrayTypeCheck);
+ checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
+ counters.zeroLengthStaticCounter.inc();
+ }
+
+ @Snippet
+ public static void arraycopyExactSnippet(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter ArrayCopyTypeCheck arrayTypeCheck,
+ @ConstantParameter JavaKind elementKind, @ConstantParameter SnippetCounter elementKindCounter, @ConstantParameter SnippetCounter elementKindCopiedCounter,
+ @ConstantParameter Counters counters) {
+ Object nonNullSrc = GraalDirectives.guardingNonNull(src);
+ Object nonNullDest = GraalDirectives.guardingNonNull(dest);
+ checkArrayTypes(nonNullSrc, nonNullDest, arrayTypeCheck);
+ checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
+ incrementLengthCounter(length, counters);
+
+ elementKindCounter.inc();
+ elementKindCopiedCounter.add(length);
+ ArrayCopyCallNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, elementKind);
+ }
+
+ @Snippet
+ public static void arraycopyUnrolledSnippet(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter ArrayCopyTypeCheck arrayTypeCheck,
+ @ConstantParameter JavaKind elementKind, @ConstantParameter int unrolledLength, @ConstantParameter Counters counters) {
+ Object nonNullSrc = GraalDirectives.guardingNonNull(src);
+ Object nonNullDest = GraalDirectives.guardingNonNull(dest);
+ checkArrayTypes(nonNullSrc, nonNullDest, arrayTypeCheck);
+ checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
+ incrementLengthCounter(length, counters);
+
+ unrolledArraycopyWork(nonNullSrc, srcPos, nonNullDest, destPos, unrolledLength, elementKind);
+ }
+
+ @Snippet
+ public static void arraycopyCheckcastSnippet(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter ArrayCopyTypeCheck arrayTypeCheck,
+ @ConstantParameter Counters counters, @ConstantParameter SnippetInfo workSnippet, @ConstantParameter JavaKind elementKind) {
+ Object nonNullSrc = GraalDirectives.guardingNonNull(src);
+ Object nonNullDest = GraalDirectives.guardingNonNull(dest);
+ checkArrayTypes(nonNullSrc, nonNullDest, arrayTypeCheck);
+ checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
+ incrementLengthCounter(length, counters);
+
+ ArrayCopyWithSlowPathNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, workSnippet, elementKind);
+ }
+
+ @Snippet
+ public static void arraycopyGenericSnippet(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter ArrayCopyTypeCheck arrayTypeCheck, @ConstantParameter Counters counters,
+ @ConstantParameter SnippetInfo workSnippet, @ConstantParameter JavaKind elementKind) {
+ Object nonNullSrc = GraalDirectives.guardingNonNull(src);
+ Object nonNullDest = GraalDirectives.guardingNonNull(dest);
+ checkArrayTypes(nonNullSrc, nonNullDest, arrayTypeCheck);
+ checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
+ incrementLengthCounter(length, counters);
+
+ ArrayCopyWithSlowPathNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, workSnippet, elementKind);
+ }
+
+ @Snippet
+ public static void arraycopyNativeSnippet(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter Counters counters) {
+ // all checks are done in the native method, so no need to emit additional checks here
+ incrementLengthCounter(length, counters);
+ counters.systemArraycopyCounter.inc();
+ counters.systemArraycopyCopiedCounter.add(length);
+
+ System.arraycopy(src, srcPos, dest, destPos, length);
+ }
+
+ @Fold
+ static LocationIdentity getArrayLocation(JavaKind kind) {
+ return NamedLocationIdentity.getArrayLocation(kind);
+ }
+
+ private static void unrolledArraycopyWork(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, JavaKind elementKind) {
+ int scale = arrayIndexScale(elementKind);
+ int arrayBaseOffset = arrayBaseOffset(elementKind);
+ LocationIdentity arrayLocation = getArrayLocation(elementKind);
+
+ long sourceOffset = arrayBaseOffset + (long) srcPos * scale;
+ long destOffset = arrayBaseOffset + (long) destPos * scale;
+ long position = 0;
+ long delta = scale;
+ if (probability(NOT_FREQUENT_PROBABILITY, nonNullSrc == nonNullDest && srcPos < destPos)) {
+ // bad aliased case so we need to copy the array from back to front
+ position = (long) (length - 1) * scale;
+ delta = -delta;
+ }
+
+ // the length was already checked before - we can emit unconditional instructions
+ ExplodeLoopNode.explodeLoop();
+ for (int iteration = 0; iteration < length; iteration++) {
+ Object value = RawLoadNode.load(nonNullSrc, sourceOffset + position, elementKind, arrayLocation);
+ RawStoreNode.storeObject(nonNullDest, destOffset + position, value, elementKind, arrayLocation, false);
+ position += delta;
+ }
+ }
+
+ @Snippet(allowPartialIntrinsicArgumentMismatch = true)
+ public static void checkcastArraycopyWithSlowPathWork(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter Counters counters) {
+ if (probability(FREQUENT_PROBABILITY, length > 0)) {
+ Object nonNullSrc = PiNode.asNonNullObject(src);
+ Object nonNullDest = PiNode.asNonNullObject(dest);
+ KlassPointer srcKlass = loadHub(nonNullSrc);
+ KlassPointer destKlass = loadHub(nonNullDest);
+ if (probability(LIKELY_PROBABILITY, srcKlass == destKlass)) {
+ // no storecheck required.
+ counters.objectCheckcastSameTypeCounter.inc();
+ counters.objectCheckcastSameTypeCopiedCounter.add(length);
+ ArrayCopyCallNode.arraycopyObjectKillsAny(nonNullSrc, srcPos, nonNullDest, destPos, length);
+ } else {
+ KlassPointer destElemKlass = destKlass.readKlassPointer(arrayClassElementOffset(INJECTED_VMCONFIG), OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION);
+ Word superCheckOffset = WordFactory.signed(destElemKlass.readInt(superCheckOffsetOffset(INJECTED_VMCONFIG), KLASS_SUPER_CHECK_OFFSET_LOCATION));
+
+ counters.objectCheckcastDifferentTypeCounter.inc();
+ counters.objectCheckcastDifferentTypeCopiedCounter.add(length);
+
+ int copiedElements = CheckcastArrayCopyCallNode.checkcastArraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, superCheckOffset, destElemKlass, false);
+ if (probability(SLOW_PATH_PROBABILITY, copiedElements != 0)) {
+ /*
+ * the stub doesn't throw the ArrayStoreException, but returns the number of
+ * copied elements (xor'd with -1).
+ */
+ copiedElements ^= -1;
+ System.arraycopy(nonNullSrc, srcPos + copiedElements, nonNullDest, destPos + copiedElements, length - copiedElements);
+ }
+ }
+ }
+ }
+
+ @Snippet(allowPartialIntrinsicArgumentMismatch = true)
+ public static void genericArraycopyWithSlowPathWork(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter Counters counters) {
+ if (probability(FREQUENT_PROBABILITY, length > 0)) {
+ counters.genericArraycopyDifferentTypeCounter.inc();
+ counters.genericArraycopyDifferentTypeCopiedCounter.add(length);
+ int copiedElements = GenericArrayCopyCallNode.genericArraycopy(src, srcPos, dest, destPos, length);
+ if (probability(SLOW_PATH_PROBABILITY, copiedElements != 0)) {
+ /*
+ * the stub doesn't throw the ArrayStoreException, but returns the number of copied
+ * elements (xor'd with -1).
+ */
+ copiedElements ^= -1;
+ System.arraycopy(src, srcPos + copiedElements, dest, destPos + copiedElements, length - copiedElements);
+ }
+ }
+ }
+
+ private static void incrementLengthCounter(int length, Counters counters) {
+ counters.lengthHistogram.inc(length);
+ }
+
+ private static void checkLimits(Object src, int srcPos, Object dest, int destPos, int length, Counters counters) {
+ if (probability(SLOW_PATH_PROBABILITY, srcPos < 0) ||
+ probability(SLOW_PATH_PROBABILITY, destPos < 0) ||
+ probability(SLOW_PATH_PROBABILITY, length < 0) ||
+ probability(SLOW_PATH_PROBABILITY, srcPos > ArrayLengthNode.arrayLength(src) - length) ||
+ probability(SLOW_PATH_PROBABILITY, destPos > ArrayLengthNode.arrayLength(dest) - length)) {
+ counters.checkAIOOBECounter.inc();
+ DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+ }
+ counters.checkSuccessCounter.inc();
+ }
+
+ private static void checkArrayTypes(Object nonNullSrc, Object nonNullDest, ArrayCopyTypeCheck arrayTypeCheck) {
+ if (arrayTypeCheck == ArrayCopyTypeCheck.NO_ARRAY_TYPE_CHECK) {
+ // nothing to do
+ } else if (arrayTypeCheck == ArrayCopyTypeCheck.HUB_BASED_ARRAY_TYPE_CHECK) {
+ KlassPointer srcHub = loadHub(nonNullSrc);
+ KlassPointer destHub = loadHub(nonNullDest);
+ if (probability(SLOW_PATH_PROBABILITY, srcHub != destHub)) {
+ DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+ }
+ } else if (arrayTypeCheck == ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK) {
+ KlassPointer srcHub = loadHub(nonNullSrc);
+ KlassPointer destHub = loadHub(nonNullDest);
+ checkArrayType(srcHub);
+ checkArrayType(destHub);
+ } else {
+ ReplacementsUtil.staticAssert(false, "unknown array type check");
+ }
+ }
+
private static int checkArrayType(KlassPointer nonNullHub) {
int layoutHelper = readLayoutHelper(nonNullHub);
if (probability(SLOW_PATH_PROBABILITY, layoutHelper >= 0)) {
@@ -97,528 +290,228 @@
return layoutHelper;
}
- private static void checkLimits(Object src, int srcPos, Object dest, int destPos, int length, Counters counters) {
- if (probability(SLOW_PATH_PROBABILITY, srcPos < 0)) {
- counters.checkAIOOBECounter.inc();
- DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
- }
- if (probability(SLOW_PATH_PROBABILITY, destPos < 0)) {
- counters.checkAIOOBECounter.inc();
- DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
- }
- if (probability(SLOW_PATH_PROBABILITY, length < 0)) {
- counters.checkAIOOBECounter.inc();
- DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
- }
- if (probability(SLOW_PATH_PROBABILITY, srcPos > ArrayLengthNode.arrayLength(src) - length)) {
- counters.checkAIOOBECounter.inc();
- DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
- }
- if (probability(SLOW_PATH_PROBABILITY, destPos > ArrayLengthNode.arrayLength(dest) - length)) {
- counters.checkAIOOBECounter.inc();
- DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
- }
- counters.checkSuccessCounter.inc();
- }
-
- @Snippet
- public static void arraycopyZeroLengthIntrinsic(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter Counters counters) {
- Object nonNullSrc = GraalDirectives.guardingNonNull(src);
- Object nonNullDest = GraalDirectives.guardingNonNull(dest);
- KlassPointer srcHub = loadHub(nonNullSrc);
- KlassPointer destHub = loadHub(nonNullDest);
- checkArrayType(srcHub);
- checkArrayType(destHub);
- checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
- counters.zeroLengthStaticCounter.inc();
- }
-
- @Snippet
- public static void arraycopyExactIntrinsic(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter JavaKind elementKind, @ConstantParameter SnippetCounter counter,
- @ConstantParameter SnippetCounter copiedCounter, @ConstantParameter Counters counters) {
- Object nonNullSrc = GraalDirectives.guardingNonNull(src);
- Object nonNullDest = GraalDirectives.guardingNonNull(dest);
- checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
- counter.inc();
- copiedCounter.add(length);
- ArrayCopyCallNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, elementKind);
- if (length == 0) {
- counters.zeroLengthDynamicCounter.inc();
- } else {
- counters.nonZeroLengthDynamicCounter.inc();
- counters.nonZeroLengthDynamicCopiedCounter.add(length);
- }
- }
-
- /**
- * This intrinsic is useful for the case where we know something statically about one of the
- * inputs but not the other.
- */
- @Snippet
- public static void arraycopyPredictedExactIntrinsic(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter JavaKind elementKind,
- @ConstantParameter SnippetCounter counter, @ConstantParameter SnippetCounter copiedCounter, @ConstantParameter Counters counters) {
- Object nonNullSrc = GraalDirectives.guardingNonNull(src);
- Object nonNullDest = GraalDirectives.guardingNonNull(dest);
- KlassPointer srcHub = loadHub(nonNullSrc);
- KlassPointer destHub = loadHub(nonNullDest);
- if (probability(SLOW_PATH_PROBABILITY, srcHub != destHub)) {
- DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
- }
- checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
- counter.inc();
- copiedCounter.add(length);
- ArrayCopyCallNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, elementKind);
- if (length == 0) {
- counters.zeroLengthDynamicCounter.inc();
- } else {
- counters.nonZeroLengthDynamicCounter.inc();
- counters.nonZeroLengthDynamicCopiedCounter.add(length);
- }
- }
-
- @Snippet
- public static void arraycopyPredictedObjectWork(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, KlassPointer objectArrayKlass,
- @ConstantParameter SnippetCounter counter, @ConstantParameter SnippetCounter copiedCounter, @ConstantParameter Counters counters) {
- if (length > 0) {
- KlassPointer srcHub = loadHub(PiNode.asNonNullObject(nonNullSrc));
- KlassPointer destHub = loadHub(PiNode.asNonNullObject(nonNullDest));
- if (probability(FAST_PATH_PROBABILITY, srcHub == destHub || destHub == objectArrayKlass)) {
- counter.inc();
- copiedCounter.add(length);
- counters.predictedObjectArrayCopyFastPathCounter.inc();
- counters.predictedObjectArrayCopyFastPathCopiedCounter.add(length);
- ArrayCopyCallNode.arraycopyObjectKillsAny(nonNullSrc, srcPos, nonNullDest, destPos, length);
- } else {
- counters.predictedObjectArrayCopySlowPathCounter.inc();
- counters.predictedObjectArrayCopySlowPathCopiedCounter.add(length);
- System.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length);
- }
- }
- }
-
- /**
- * This is the basic template for the full arraycopy checks, including a check that the
- * underlying type is really an array type.
- */
- @Snippet
- public static void arraycopySlowPathIntrinsic(Object src, int srcPos, Object dest, int destPos, int length, KlassPointer predictedKlass, @ConstantParameter JavaKind elementKind,
- @ConstantParameter SnippetInfo slowPath, @ConstantParameter Object slowPathArgument, @ConstantParameter Counters counters) {
- Object nonNullSrc = GraalDirectives.guardingNonNull(src);
- Object nonNullDest = GraalDirectives.guardingNonNull(dest);
- KlassPointer srcHub = loadHub(nonNullSrc);
- KlassPointer destHub = loadHub(nonNullDest);
- checkArrayType(srcHub);
- checkArrayType(destHub);
- checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
- if (length == 0) {
- counters.zeroLengthDynamicCounter.inc();
- } else {
- counters.nonZeroLengthDynamicCounter.inc();
- counters.nonZeroLengthDynamicCopiedCounter.add(length);
- }
- ArrayCopySlowPathNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, predictedKlass, elementKind, slowPath, slowPathArgument);
- }
-
- /**
- * Snippet for unrolled arraycopy.
- */
- @Snippet
- public static void arraycopyUnrolledIntrinsic(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter int unrolledLength, @ConstantParameter JavaKind elementKind,
- @ConstantParameter Counters counters) {
- Object nonNullSrc = GraalDirectives.guardingNonNull(src);
- Object nonNullDest = GraalDirectives.guardingNonNull(dest);
- checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
- if (length == 0) {
- counters.zeroLengthDynamicCounter.inc();
- } else {
- counters.nonZeroLengthDynamicCounter.inc();
- counters.nonZeroLengthDynamicCopiedCounter.add(length);
- }
- ArrayCopyUnrollNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, unrolledLength, elementKind);
- }
-
- @Snippet
- public static void checkcastArraycopyWork(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, @ConstantParameter Counters counters) {
- if (length > 0) {
- KlassPointer destKlass = loadHub(nonNullDest);
- KlassPointer srcKlass = loadHub(nonNullSrc);
- if (probability(SLOW_PATH_PROBABILITY, srcKlass == destKlass)) {
- // no storecheck required.
- counters.objectCheckcastSameTypeCounter.inc();
- counters.objectCheckcastSameTypeCopiedCounter.add(length);
- ArrayCopyCallNode.arraycopyObjectKillsAny(nonNullSrc, srcPos, nonNullDest, destPos, length);
- } else {
- KlassPointer destElemKlass = destKlass.readKlassPointer(arrayClassElementOffset(INJECTED_VMCONFIG), OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION);
- Word superCheckOffset = WordFactory.signed(destElemKlass.readInt(superCheckOffsetOffset(INJECTED_VMCONFIG), KLASS_SUPER_CHECK_OFFSET_LOCATION));
- counters.objectCheckcastCounter.inc();
- counters.objectCheckcastCopiedCounter.add(length);
- int copiedElements = CheckcastArrayCopyCallNode.checkcastArraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, superCheckOffset, destElemKlass, false);
- if (copiedElements != 0) {
- /*
- * the checkcast stub doesn't throw the ArrayStoreException, but returns the
- * number of copied elements (xor'd with -1).
- */
- copiedElements ^= -1;
- System.arraycopy(nonNullSrc, srcPos + copiedElements, nonNullDest, destPos + copiedElements, length - copiedElements);
- }
- }
- }
- }
-
- @Snippet
- public static void arraycopyGeneric(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter Counters counters) {
- Object nonNullSrc = GraalDirectives.guardingNonNull(src);
- Object nonNullDest = GraalDirectives.guardingNonNull(dest);
- KlassPointer srcHub = loadHub(nonNullSrc);
- KlassPointer destHub = loadHub(nonNullDest);
- if (probability(FAST_PATH_PROBABILITY, srcHub.equal(destHub)) && probability(FAST_PATH_PROBABILITY, nonNullSrc != nonNullDest)) {
- int layoutHelper = checkArrayType(srcHub);
- final boolean isObjectArray = ((layoutHelper & layoutHelperElementTypePrimitiveInPlace(INJECTED_VMCONFIG)) == 0);
- checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
- if (probability(FAST_PATH_PROBABILITY, isObjectArray)) {
- counters.genericObjectExactCallCounter.inc();
- counters.genericObjectExactCallCopiedCounter.add(length);
- ArrayCopyCallNode.disjointArraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, JavaKind.Object);
- } else {
- counters.genericPrimitiveCallCounter.inc();
- counters.genericPrimitiveCallCopiedCounter.add(length);
- UnsafeArrayCopyNode.arraycopyPrimitive(nonNullSrc, srcPos, nonNullDest, destPos, length, layoutHelper);
- }
- } else {
- counters.systemArraycopyCounter.inc();
- counters.systemArraycopyCopiedCounter.add(length);
- System.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length);
- }
- }
-
- @Fold
- static LocationIdentity getArrayLocation(JavaKind kind) {
- return NamedLocationIdentity.getArrayLocation(kind);
- }
-
- @Snippet
- public static void arraycopyUnrolledWork(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, @ConstantParameter int length, @ConstantParameter JavaKind elementKind) {
- final int scale = arrayIndexScale(elementKind);
- int arrayBaseOffset = arrayBaseOffset(elementKind);
- LocationIdentity arrayLocation = getArrayLocation(elementKind);
- if (nonNullSrc == nonNullDest && srcPos < destPos) { // bad aliased case
- long start = (long) (length - 1) * scale;
- long i = start;
- ExplodeLoopNode.explodeLoop();
- for (int iteration = 0; iteration < length; iteration++) {
- if (i >= 0) {
- Object a = RawLoadNode.load(nonNullSrc, arrayBaseOffset + i + (long) srcPos * scale, elementKind, arrayLocation);
- RawStoreNode.storeObject(nonNullDest, arrayBaseOffset + i + (long) destPos * scale, a, elementKind, arrayLocation, false);
- i -= scale;
- }
- }
- } else {
- long end = (long) length * scale;
- long i = 0;
- ExplodeLoopNode.explodeLoop();
- for (int iteration = 0; iteration < length; iteration++) {
- if (i < end) {
- Object a = RawLoadNode.load(nonNullSrc, arrayBaseOffset + i + (long) srcPos * scale, elementKind, arrayLocation);
- RawStoreNode.storeObject(nonNullDest, arrayBaseOffset + i + (long) destPos * scale, a, elementKind, arrayLocation, false);
- i += scale;
- }
- }
- }
- }
-
static class Counters {
final SnippetCounter checkSuccessCounter;
final SnippetCounter checkAIOOBECounter;
- final SnippetCounter objectCheckcastCounter;
- final SnippetCounter objectCheckcastSameTypeCounter;
- final SnippetCounter predictedObjectArrayCopySlowPathCounter;
- final SnippetCounter predictedObjectArrayCopyFastPathCounter;
+ final SnippetCounter zeroLengthStaticCounter;
+ final SnippetIntegerHistogram lengthHistogram;
- final SnippetCounter genericPrimitiveCallCounter;
- final SnippetCounter genericObjectExactCallCounter;
final SnippetCounter systemArraycopyCounter;
-
- final SnippetCounter zeroLengthStaticCounter;
- final SnippetCounter zeroLengthDynamicCounter;
- final SnippetCounter nonZeroLengthDynamicCounter;
-
- final SnippetCounter nonZeroLengthDynamicCopiedCounter;
- final SnippetCounter genericPrimitiveCallCopiedCounter;
- final SnippetCounter genericObjectExactCallCopiedCounter;
final SnippetCounter systemArraycopyCopiedCounter;
- final SnippetCounter objectCheckcastCopiedCounter;
+ final SnippetCounter genericArraycopyDifferentTypeCopiedCounter;
+ final SnippetCounter genericArraycopyDifferentTypeCounter;
+
final SnippetCounter objectCheckcastSameTypeCopiedCounter;
- final SnippetCounter predictedObjectArrayCopySlowPathCopiedCounter;
- final SnippetCounter predictedObjectArrayCopyFastPathCopiedCounter;
+ final SnippetCounter objectCheckcastSameTypeCounter;
+ final SnippetCounter objectCheckcastDifferentTypeCopiedCounter;
+ final SnippetCounter objectCheckcastDifferentTypeCounter;
final EnumMap<JavaKind, SnippetCounter> arraycopyCallCounters = new EnumMap<>(JavaKind.class);
- final EnumMap<JavaKind, SnippetCounter> arraycopyCounters = new EnumMap<>(JavaKind.class);
-
final EnumMap<JavaKind, SnippetCounter> arraycopyCallCopiedCounters = new EnumMap<>(JavaKind.class);
- final EnumMap<JavaKind, SnippetCounter> arraycopyCopiedCounters = new EnumMap<>(JavaKind.class);
Counters(SnippetCounter.Group.Factory factory) {
final Group checkCounters = factory.createSnippetCounterGroup("System.arraycopy checkInputs");
- final Group counters = factory.createSnippetCounterGroup("System.arraycopy");
- final Group copiedCounters = factory.createSnippetCounterGroup("System.arraycopy copied elements");
- final Group lengthCounters = factory.createSnippetCounterGroup("System.arraycopy 0-length checks");
+ final Group callCounters = factory.createSnippetCounterGroup("System.arraycopy calls");
+ final Group copiedElementsCounters = factory.createSnippetCounterGroup("System.arraycopy copied elements");
+ final Group lengthCounters = factory.createSnippetCounterGroup("System.arraycopy with 0-length");
checkSuccessCounter = new SnippetCounter(checkCounters, "checkSuccess", "checkSuccess");
checkAIOOBECounter = new SnippetCounter(checkCounters, "checkAIOOBE", "checkAIOOBE");
- objectCheckcastCounter = new SnippetCounter(counters, "Object[]{non-exact}", "arraycopy for non-exact Object[] arrays");
- objectCheckcastSameTypeCounter = new SnippetCounter(counters, "Object[]{same-type}", "arraycopy call for src.klass == dest.klass Object[] arrays");
- predictedObjectArrayCopySlowPathCounter = new SnippetCounter(counters, "Object[]{slow-path}", "used System.arraycopy slow path for predicted Object[] arrays");
- predictedObjectArrayCopyFastPathCounter = new SnippetCounter(counters, "Object[]{fast-path}", "used oop_arraycopy for predicted Object[] arrays");
- genericPrimitiveCallCounter = new SnippetCounter(counters, "genericPrimitive", "generic arraycopy snippet for primitive arrays");
- genericObjectExactCallCounter = new SnippetCounter(counters, "genericObjectExact", "generic arraycopy snippet for special object arrays");
- systemArraycopyCounter = new SnippetCounter(counters, "genericObject", "call to System.arraycopy");
+ zeroLengthStaticCounter = new SnippetCounter(lengthCounters, "0-length copy static", "calls where the length is statically 0");
+ lengthHistogram = new SnippetIntegerHistogram(lengthCounters, 2, "length", "length");
- zeroLengthStaticCounter = new SnippetCounter(lengthCounters, "0-lengthcopy static", "arraycopy where the length is statically 0");
- zeroLengthDynamicCounter = new SnippetCounter(lengthCounters, "0-lengthcopy dynamically", "arraycopy where the length is dynamically 0");
- nonZeroLengthDynamicCounter = new SnippetCounter(lengthCounters, "non-0-lengthcopy dynamically", "arraycopy where the length is dynamically not zero");
+ systemArraycopyCounter = new SnippetCounter(callCounters, "native System.arraycopy", "JNI-based System.arraycopy call");
+ systemArraycopyCopiedCounter = new SnippetCounter(copiedElementsCounters, "native System.arraycopy", "JNI-based System.arraycopy call");
+
+ genericArraycopyDifferentTypeCounter = new SnippetCounter(callCounters, "generic[] stub", "generic arraycopy stub");
+ genericArraycopyDifferentTypeCopiedCounter = new SnippetCounter(copiedElementsCounters, "generic[] stub", "generic arraycopy stub");
- nonZeroLengthDynamicCopiedCounter = new SnippetCounter(copiedCounters, "non-0-lengthcopy dynamically", "arraycopy where the length is dynamically not zero");
- genericPrimitiveCallCopiedCounter = new SnippetCounter(copiedCounters, "genericPrimitive", "generic arraycopy snippet for primitive arrays");
- genericObjectExactCallCopiedCounter = new SnippetCounter(copiedCounters, "genericObjectExact", "generic arraycopy snippet for special object arrays");
- systemArraycopyCopiedCounter = new SnippetCounter(copiedCounters, "genericObject", "call to System.arraycopy");
+ objectCheckcastSameTypeCounter = new SnippetCounter(callCounters, "checkcast object[] (same-type)", "checkcast object[] stub but src.klass == dest.klass Object[] arrays");
+ objectCheckcastSameTypeCopiedCounter = new SnippetCounter(copiedElementsCounters, "checkcast object[] (same-type)", "checkcast object[] stub but src.klass == dest.klass Object[] arrays");
+ objectCheckcastDifferentTypeCounter = new SnippetCounter(callCounters, "checkcast object[] (store-check)", "checkcast object[] stub with store check");
+ objectCheckcastDifferentTypeCopiedCounter = new SnippetCounter(copiedElementsCounters, "checkcast object[] (store-check)", "checkcast object[] stub with store check");
- objectCheckcastCopiedCounter = new SnippetCounter(copiedCounters, "Object[]{non-exact}", "arraycopy for non-exact Object[] arrays");
- objectCheckcastSameTypeCopiedCounter = new SnippetCounter(copiedCounters, "Object[]{same-type}", "arraycopy call for src.klass == dest.klass Object[] arrays");
- predictedObjectArrayCopySlowPathCopiedCounter = new SnippetCounter(copiedCounters, "Object[]{slow-path}",
- "used System.arraycopy slow path for predicted Object[] arrays");
- predictedObjectArrayCopyFastPathCopiedCounter = new SnippetCounter(copiedCounters, "Object[]{fast-path}", "used oop_arraycopy for predicted Object[] arrays");
- createArraycopyCounter(JavaKind.Byte, counters, copiedCounters);
- createArraycopyCounter(JavaKind.Boolean, counters, copiedCounters);
- createArraycopyCounter(JavaKind.Char, counters, copiedCounters);
- createArraycopyCounter(JavaKind.Short, counters, copiedCounters);
- createArraycopyCounter(JavaKind.Int, counters, copiedCounters);
- createArraycopyCounter(JavaKind.Long, counters, copiedCounters);
- createArraycopyCounter(JavaKind.Float, counters, copiedCounters);
- createArraycopyCounter(JavaKind.Double, counters, copiedCounters);
- createArraycopyCounter(JavaKind.Object, counters, copiedCounters);
+ createArraycopyCounter(JavaKind.Byte, callCounters, copiedElementsCounters);
+ createArraycopyCounter(JavaKind.Boolean, callCounters, copiedElementsCounters);
+ createArraycopyCounter(JavaKind.Char, callCounters, copiedElementsCounters);
+ createArraycopyCounter(JavaKind.Short, callCounters, copiedElementsCounters);
+ createArraycopyCounter(JavaKind.Int, callCounters, copiedElementsCounters);
+ createArraycopyCounter(JavaKind.Long, callCounters, copiedElementsCounters);
+ createArraycopyCounter(JavaKind.Float, callCounters, copiedElementsCounters);
+ createArraycopyCounter(JavaKind.Double, callCounters, copiedElementsCounters);
+ createArraycopyCounter(JavaKind.Object, callCounters, copiedElementsCounters);
}
void createArraycopyCounter(JavaKind kind, Group counters, Group copiedCounters) {
- arraycopyCallCounters.put(kind, new SnippetCounter(counters, kind + "[]{stub}", "arraycopy call for " + kind + "[] arrays"));
- arraycopyCounters.put(kind, new SnippetCounter(counters, kind + "[]{inline}", "inline arraycopy for " + kind + "[] arrays"));
-
- arraycopyCallCopiedCounters.put(kind, new SnippetCounter(copiedCounters, kind + "[]{stub}", "arraycopy call for " + kind + "[] arrays"));
- arraycopyCopiedCounters.put(kind, new SnippetCounter(copiedCounters, kind + "[]{inline}", "inline arraycopy for " + kind + "[] arrays"));
+ arraycopyCallCounters.put(kind, new SnippetCounter(counters, kind + "[] stub", "arraycopy call for " + kind + "[] arrays"));
+ arraycopyCallCopiedCounters.put(kind, new SnippetCounter(copiedCounters, kind + "[] stub", "arraycopy call for " + kind + "[] arrays"));
}
}
public static class Templates extends SnippetTemplate.AbstractTemplates {
+ private final SnippetInfo arraycopyGenericSnippet = snippet("arraycopyGenericSnippet");
+ private final SnippetInfo arraycopyUnrolledSnippet = snippet("arraycopyUnrolledSnippet");
+ private final SnippetInfo arraycopyExactSnippet = snippet("arraycopyExactSnippet");
+ private final SnippetInfo arraycopyZeroLengthSnippet = snippet("arraycopyZeroLengthSnippet");
+ private final SnippetInfo arraycopyCheckcastSnippet = snippet("arraycopyCheckcastSnippet");
+ private final SnippetInfo arraycopyNativeSnippet = snippet("arraycopyNativeSnippet");
+
+ private final SnippetInfo checkcastArraycopyWithSlowPathWork = snippet("checkcastArraycopyWithSlowPathWork");
+ private final SnippetInfo genericArraycopyWithSlowPathWork = snippet("genericArraycopyWithSlowPathWork");
+
+ private ResolvedJavaMethod originalArraycopy;
+ private final Counters counters;
public Templates(OptionValues options, Iterable<DebugHandlersFactory> factories, SnippetCounter.Group.Factory factory, HotSpotProviders providers, TargetDescription target) {
super(options, factories, providers, providers.getSnippetReflection(), target);
this.counters = new Counters(factory);
}
- private ResolvedJavaMethod originalArraycopy() throws GraalError {
- if (originalArraycopy == null) {
- Method method;
- try {
- method = System.class.getDeclaredMethod("arraycopy", Object.class, int.class, Object.class, int.class, int.class);
- } catch (NoSuchMethodException | SecurityException e) {
- throw new GraalError(e);
- }
- originalArraycopy = providers.getMetaAccess().lookupJavaMethod(method);
- }
- return originalArraycopy;
- }
-
- private ResolvedJavaMethod originalArraycopy;
-
- private final SnippetInfo checkcastArraycopyWorkSnippet = snippet("checkcastArraycopyWork");
- private final SnippetInfo arraycopyGenericSnippet = snippet("arraycopyGeneric");
-
- private final SnippetInfo arraycopySlowPathIntrinsicSnippet = snippet("arraycopySlowPathIntrinsic");
- private final SnippetInfo arraycopyUnrolledIntrinsicSnippet = snippet("arraycopyUnrolledIntrinsic");
- private final SnippetInfo arraycopyExactIntrinsicSnippet = snippet("arraycopyExactIntrinsic");
- private final SnippetInfo arraycopyZeroLengthIntrinsicSnippet = snippet("arraycopyZeroLengthIntrinsic");
- private final SnippetInfo arraycopyPredictedExactIntrinsicSnippet = snippet("arraycopyPredictedExactIntrinsic");
- private final SnippetInfo arraycopyPredictedObjectWorkSnippet = snippet("arraycopyPredictedObjectWork");
-
- private final SnippetInfo arraycopyUnrolledWorkSnippet = snippet("arraycopyUnrolledWork");
-
- private final Counters counters;
-
protected SnippetInfo snippet(String methodName) {
SnippetInfo info = snippet(ArrayCopySnippets.class, methodName, LocationIdentity.any());
info.setOriginalMethod(originalArraycopy());
return info;
}
- public static JavaKind selectComponentKind(BasicArrayCopyNode arraycopy) {
- return selectComponentKind(arraycopy, true);
- }
+ public void lower(ArrayCopyNode arraycopy, LoweringTool tool) {
+ JavaKind elementKind = selectComponentKind(arraycopy);
+ SnippetInfo snippetInfo;
+ ArrayCopyTypeCheck arrayTypeCheck;
- public static JavaKind selectComponentKind(BasicArrayCopyNode arraycopy, boolean exact) {
ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp());
ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp());
+ if (!canBeArray(srcType) || !canBeArray(destType)) {
+ // at least one of the objects is definitely not an array - use the native call
+ // right away as the copying will fail anyways
+ snippetInfo = arraycopyNativeSnippet;
+ arrayTypeCheck = ArrayCopyTypeCheck.UNDEFINED_ARRAY_TYPE_CHECK;
+ } else {
+ ResolvedJavaType srcComponentType = srcType == null ? null : srcType.getComponentType();
+ ResolvedJavaType destComponentType = destType == null ? null : destType.getComponentType();
- if (srcType == null || !srcType.isArray() || destType == null || !destType.isArray()) {
- if (!exact) {
- JavaKind component = getComponentKind(srcType);
- if (component != null) {
- return component;
+ if (arraycopy.isExact()) {
+ // there is a sufficient type match - we don't need any additional type checks
+ snippetInfo = arraycopyExactSnippet;
+ arrayTypeCheck = ArrayCopyTypeCheck.NO_ARRAY_TYPE_CHECK;
+ } else if (srcComponentType == null && destComponentType == null) {
+ // we don't know anything about the types - use the generic copying
+ snippetInfo = arraycopyGenericSnippet;
+ arrayTypeCheck = ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK;
+ } else if (srcComponentType != null && destComponentType != null) {
+ if (!srcComponentType.isPrimitive() && !destComponentType.isPrimitive()) {
+ // it depends on the array content if the copy succeeds - we need
+ // a type check for every store
+ snippetInfo = arraycopyCheckcastSnippet;
+ arrayTypeCheck = ArrayCopyTypeCheck.NO_ARRAY_TYPE_CHECK;
+ } else {
+ // one object is an object array, the other one is a primitive array.
+ // this copy will always fail - use the native call right away
+ assert !srcComponentType.equals(destComponentType) : "must be handled by arraycopy.isExact()";
+ snippetInfo = arraycopyNativeSnippet;
+ arrayTypeCheck = ArrayCopyTypeCheck.UNDEFINED_ARRAY_TYPE_CHECK;
}
- return getComponentKind(destType);
- }
- return null;
- }
- if (exact) {
- if (!destType.getComponentType().isAssignableFrom(srcType.getComponentType())) {
- return null;
- }
- if (!arraycopy.isExact()) {
- return null;
+ } else {
+ ResolvedJavaType nonNullComponentType = srcComponentType != null ? srcComponentType : destComponentType;
+ if (nonNullComponentType.isPrimitive()) {
+ // one involved object is a primitive array - we can safely assume that we
+ // are copying primitive arrays
+ snippetInfo = arraycopyExactSnippet;
+ arrayTypeCheck = ArrayCopyTypeCheck.HUB_BASED_ARRAY_TYPE_CHECK;
+ elementKind = nonNullComponentType.getJavaKind();
+ } else {
+ // one involved object is an object array - we can safely assume that we are
+ // copying object arrays that might require a store check
+ snippetInfo = arraycopyCheckcastSnippet;
+ arrayTypeCheck = ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK;
+ }
}
}
- return srcType.getComponentType().getJavaKind();
- }
- private static JavaKind getComponentKind(ResolvedJavaType type) {
- if (type != null && type.isArray()) {
- return type.getComponentType().getJavaKind();
- }
- return null;
- }
-
- private static boolean shouldUnroll(ValueNode length) {
- return length.isConstant() && length.asJavaConstant().asInt() <= 8 && length.asJavaConstant().asInt() != 0;
- }
-
- public void lower(ArrayCopyNode arraycopy, LoweringTool tool) {
- JavaKind componentKind = selectComponentKind(arraycopy);
- SnippetInfo snippetInfo = null;
- SnippetInfo slowPathSnippetInfo = null;
- Object slowPathArgument = null;
-
+ // a few special cases that are easier to handle when all other variables already have a
+ // value
if (arraycopy.getLength().isConstant() && arraycopy.getLength().asJavaConstant().asLong() == 0) {
- snippetInfo = arraycopyZeroLengthIntrinsicSnippet;
- } else if (arraycopy.isExact()) {
- snippetInfo = arraycopyExactIntrinsicSnippet;
- if (shouldUnroll(arraycopy.getLength())) {
- snippetInfo = arraycopyUnrolledIntrinsicSnippet;
- }
- } else {
- if (componentKind == JavaKind.Object) {
- ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp());
- ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp());
- ResolvedJavaType srcComponentType = srcType == null ? null : srcType.getComponentType();
- ResolvedJavaType destComponentType = destType == null ? null : destType.getComponentType();
- if (srcComponentType != null && destComponentType != null && !srcComponentType.isPrimitive() && !destComponentType.isPrimitive()) {
- snippetInfo = arraycopySlowPathIntrinsicSnippet;
- slowPathSnippetInfo = checkcastArraycopyWorkSnippet;
- slowPathArgument = LocationIdentity.any();
- /*
- * Because this snippet has to use Sysytem.arraycopy as a slow path, we must
- * pretend to kill any() so clear the componentKind.
- */
- componentKind = null;
- }
- }
- if (componentKind == null && snippetInfo == null) {
- JavaKind predictedKind = selectComponentKind(arraycopy, false);
- if (predictedKind != null) {
- /*
- * At least one array is of a known type requiring no store checks, so
- * assume the other is of the same type. Generally this is working around
- * deficiencies in our propagation of type information.
- */
- componentKind = predictedKind;
- if (predictedKind == JavaKind.Object) {
- snippetInfo = arraycopySlowPathIntrinsicSnippet;
- slowPathSnippetInfo = arraycopyPredictedObjectWorkSnippet;
- slowPathArgument = predictedKind;
- componentKind = null;
- } else {
- snippetInfo = arraycopyPredictedExactIntrinsicSnippet;
- }
- }
- }
- if (snippetInfo == null) {
- snippetInfo = arraycopyGenericSnippet;
- }
+ snippetInfo = arraycopyZeroLengthSnippet;
+ } else if (snippetInfo == arraycopyExactSnippet && shouldUnroll(arraycopy.getLength())) {
+ snippetInfo = arraycopyUnrolledSnippet;
}
+
+ // create the snippet
Arguments args = new Arguments(snippetInfo, arraycopy.graph().getGuardsStage(), tool.getLoweringStage());
args.add("src", arraycopy.getSource());
args.add("srcPos", arraycopy.getSourcePosition());
args.add("dest", arraycopy.getDestination());
args.add("destPos", arraycopy.getDestinationPosition());
args.add("length", arraycopy.getLength());
- if (snippetInfo == arraycopyUnrolledIntrinsicSnippet) {
+ if (snippetInfo != arraycopyNativeSnippet) {
+ assert arrayTypeCheck != ArrayCopyTypeCheck.UNDEFINED_ARRAY_TYPE_CHECK;
+ args.addConst("arrayTypeCheck", arrayTypeCheck);
+ }
+ if (snippetInfo == arraycopyUnrolledSnippet) {
+ args.addConst("elementKind", elementKind != null ? elementKind : JavaKind.Illegal);
args.addConst("unrolledLength", arraycopy.getLength().asJavaConstant().asInt());
- args.addConst("elementKind", componentKind != null ? componentKind : JavaKind.Illegal);
- } else if (snippetInfo == arraycopySlowPathIntrinsicSnippet) {
- ValueNode predictedKlass = null;
- if (slowPathArgument == arraycopyPredictedObjectWorkSnippet) {
- HotSpotResolvedObjectType arrayClass = (HotSpotResolvedObjectType) tool.getMetaAccess().lookupJavaType(Object[].class);
- predictedKlass = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), arrayClass.klass(), tool.getMetaAccess(), arraycopy.graph());
- } else {
- predictedKlass = ConstantNode.forConstant(KlassPointerStamp.klassAlwaysNull(), JavaConstant.NULL_POINTER, tool.getMetaAccess(), arraycopy.graph());
- }
- args.add("predictedKlass", predictedKlass);
- args.addConst("elementKind", componentKind != null ? componentKind : JavaKind.Illegal);
- args.addConst("slowPath", slowPathSnippetInfo);
- assert slowPathArgument != null;
- args.addConst("slowPathArgument", slowPathArgument);
- } else if (snippetInfo == arraycopyExactIntrinsicSnippet || snippetInfo == arraycopyPredictedExactIntrinsicSnippet) {
- assert componentKind != null;
- args.addConst("elementKind", componentKind);
- args.addConst("counter", counters.arraycopyCallCounters.get(componentKind));
- args.addConst("copiedCounter", counters.arraycopyCallCopiedCounters.get(componentKind));
+ }
+ if (snippetInfo == arraycopyExactSnippet) {
+ assert elementKind != null;
+ args.addConst("elementKind", elementKind);
+ args.addConst("elementKindCounter", counters.arraycopyCallCounters.get(elementKind));
+ args.addConst("elementKindCopiedCounter", counters.arraycopyCallCopiedCounters.get(elementKind));
+ }
+ args.addConst("counters", counters);
+ if (snippetInfo == arraycopyCheckcastSnippet) {
+ args.addConst("workSnippet", checkcastArraycopyWithSlowPathWork);
+ args.addConst("elementKind", JavaKind.Illegal);
+ }
+ if (snippetInfo == arraycopyGenericSnippet) {
+ args.addConst("workSnippet", genericArraycopyWithSlowPathWork);
+ args.addConst("elementKind", JavaKind.Illegal);
}
+
+ instantiate(args, arraycopy);
+ }
+
+ public void lower(ArrayCopyWithSlowPathNode arraycopy, LoweringTool tool) {
+ StructuredGraph graph = arraycopy.graph();
+ if (!graph.getGuardsStage().areFrameStatesAtDeopts()) {
+ // if an arraycopy contains a slow path, we can't lower it right away
+ return;
+ }
+
+ SnippetInfo snippetInfo = arraycopy.getSnippet();
+ Arguments args = new Arguments(snippetInfo, graph.getGuardsStage(), tool.getLoweringStage());
+ args.add("src", arraycopy.getSource());
+ args.add("srcPos", arraycopy.getSourcePosition());
+ args.add("dest", arraycopy.getDestination());
+ args.add("destPos", arraycopy.getDestinationPosition());
+ args.add("length", arraycopy.getLength());
args.addConst("counters", counters);
instantiate(args, arraycopy);
}
- public void lower(ArrayCopySlowPathNode arraycopy, LoweringTool tool) {
- StructuredGraph graph = arraycopy.graph();
- if (!graph.getGuardsStage().areFrameStatesAtDeopts()) {
- // Can't be lowered yet
- return;
- }
- SnippetInfo snippetInfo = arraycopy.getSnippet();
- Arguments args = new Arguments(snippetInfo, graph.getGuardsStage(), tool.getLoweringStage());
- args.add("nonNullSrc", arraycopy.getSource());
- args.add("srcPos", arraycopy.getSourcePosition());
- args.add("nonNullDest", arraycopy.getDestination());
- args.add("destPos", arraycopy.getDestinationPosition());
- if (snippetInfo == arraycopyUnrolledWorkSnippet) {
- args.addConst("length", ((Integer) arraycopy.getArgument()).intValue());
- args.addConst("elementKind", arraycopy.getElementKind());
- } else {
- args.add("length", arraycopy.getLength());
- }
- if (snippetInfo == arraycopyPredictedObjectWorkSnippet) {
- args.add("objectArrayKlass", arraycopy.getPredictedKlass());
- args.addConst("counter", counters.arraycopyCallCounters.get(JavaKind.Object));
- args.addConst("copiedCounter", counters.arraycopyCallCopiedCounters.get(JavaKind.Object));
- args.addConst("counters", counters);
- }
- instantiate(args, arraycopy);
+ private static boolean canBeArray(ResolvedJavaType type) {
+ return type == null || type.isJavaLangObject() || type.isArray();
}
- public void lower(ArrayCopyUnrollNode arraycopy, LoweringTool tool) {
- StructuredGraph graph = arraycopy.graph();
- if (!graph.getGuardsStage().areFrameStatesAtDeopts()) {
- // Can't be lowered yet
- return;
+ public static JavaKind selectComponentKind(BasicArrayCopyNode arraycopy) {
+ ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp());
+ ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp());
+
+ if (srcType == null || !srcType.isArray() || destType == null || !destType.isArray()) {
+ return null;
}
- SnippetInfo snippetInfo = arraycopyUnrolledWorkSnippet;
- Arguments args = new Arguments(snippetInfo, graph.getGuardsStage(), tool.getLoweringStage());
- args.add("nonNullSrc", arraycopy.getSource());
- args.add("srcPos", arraycopy.getSourcePosition());
- args.add("nonNullDest", arraycopy.getDestination());
- args.add("destPos", arraycopy.getDestinationPosition());
- args.addConst("length", arraycopy.getUnrollLength());
- args.addConst("elementKind", arraycopy.getElementKind());
- template(graph.getDebug(), args).instantiate(providers.getMetaAccess(), arraycopy, SnippetTemplate.DEFAULT_REPLACER, args);
+ if (!destType.getComponentType().isAssignableFrom(srcType.getComponentType())) {
+ return null;
+ }
+ if (!arraycopy.isExact()) {
+ return null;
+ }
+ return srcType.getComponentType().getJavaKind();
+ }
+
+ private static boolean shouldUnroll(ValueNode length) {
+ return length.isConstant() && length.asJavaConstant().asInt() <= 8 && length.asJavaConstant().asInt() != 0;
}
/**
@@ -650,8 +543,8 @@
newInvoke.setStateAfter(arraycopy.stateAfter());
}
graph.replaceFixedWithFixed((InvokeNode) invoke.asNode(), newInvoke);
- } else if (originalNode instanceof ArrayCopySlowPathNode) {
- ArrayCopySlowPathNode slowPath = (ArrayCopySlowPathNode) replacements.get(originalNode);
+ } else if (originalNode instanceof ArrayCopyWithSlowPathNode) {
+ ArrayCopyWithSlowPathNode slowPath = (ArrayCopyWithSlowPathNode) replacements.get(originalNode);
assert arraycopy.stateAfter() != null : arraycopy;
assert slowPath.stateAfter() == arraycopy.stateAfter();
slowPath.setBci(arraycopy.getBci());
@@ -659,5 +552,18 @@
}
GraphUtil.killCFG(arraycopy);
}
+
+ private ResolvedJavaMethod originalArraycopy() throws GraalError {
+ if (originalArraycopy == null) {
+ Method method;
+ try {
+ method = System.class.getDeclaredMethod("arraycopy", Object.class, int.class, Object.class, int.class, int.class);
+ } catch (NoSuchMethodException | SecurityException e) {
+ throw new GraalError(e);
+ }
+ originalArraycopy = providers.getMetaAccess().lookupJavaMethod(method);
+ }
+ return originalArraycopy;
+ }
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyUnrollNode.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.hotspot.replacements.arraycopy;
-
-import jdk.vm.ci.meta.JavaKind;
-
-import static org.graalvm.word.LocationIdentity.any;
-
-import org.graalvm.compiler.core.common.type.StampFactory;
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.nodeinfo.InputType;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.NamedLocationIdentity;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.extended.ArrayRangeWriteNode;
-import org.graalvm.compiler.nodes.memory.MemoryAccess;
-import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
-import org.graalvm.compiler.nodes.memory.MemoryNode;
-import org.graalvm.compiler.nodes.spi.Lowerable;
-import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.word.LocationIdentity;
-
-@NodeInfo(allowedUsageTypes = InputType.Memory)
-public class ArrayCopyUnrollNode extends ArrayRangeWriteNode implements MemoryCheckpoint.Single, Lowerable, MemoryAccess {
-
- public static final NodeClass<ArrayCopyUnrollNode> TYPE = NodeClass.create(ArrayCopyUnrollNode.class);
-
- @Input protected ValueNode src;
- @Input protected ValueNode srcPos;
- @Input protected ValueNode dest;
- @Input protected ValueNode destPos;
- @Input protected ValueNode length;
-
- private JavaKind elementKind;
-
- private int unrolledLength;
-
- @OptionalInput(InputType.Memory) private MemoryNode lastLocationAccess;
-
- public ArrayCopyUnrollNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, int unrolledLength, JavaKind elementKind) {
- super(TYPE, StampFactory.forKind(JavaKind.Void));
- this.src = src;
- this.srcPos = srcPos;
- this.dest = dest;
- this.destPos = destPos;
- this.length = length;
- this.unrolledLength = unrolledLength;
- assert elementKind != null && elementKind != JavaKind.Illegal;
- this.elementKind = elementKind;
- }
-
- public ValueNode getSource() {
- return src;
- }
-
- public ValueNode getSourcePosition() {
- return srcPos;
- }
-
- public ValueNode getDestination() {
- return dest;
- }
-
- public ValueNode getDestinationPosition() {
- return destPos;
- }
-
- @Override
- public ValueNode getLength() {
- return length;
- }
-
- @Override
- public ValueNode getArray() {
- return dest;
- }
-
- @Override
- public ValueNode getIndex() {
- return destPos;
- }
-
- @Override
- public boolean isObjectArray() {
- return elementKind == JavaKind.Object;
- }
-
- @Override
- public boolean isInitialization() {
- return false;
- }
-
- @NodeIntrinsic
- public static native void arraycopy(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, @ConstantNodeParameter int unrolledLength,
- @ConstantNodeParameter JavaKind elementKind);
-
- public int getUnrollLength() {
- return unrolledLength;
- }
-
- public JavaKind getElementKind() {
- return elementKind;
- }
-
- @Override
- public LocationIdentity getLocationIdentity() {
- if (elementKind != null) {
- return NamedLocationIdentity.getArrayLocation(elementKind);
- }
- return any();
- }
-
- @Override
- public void lower(LoweringTool tool) {
- tool.getLowerer().lower(this, tool);
- }
-
- @Override
- public MemoryNode getLastLocationAccess() {
- return lastLocationAccess;
- }
-
- @Override
- public void setLastLocationAccess(MemoryNode lla) {
- updateUsagesInterface(lastLocationAccess, lla);
- lastLocationAccess = lla;
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyWithSlowPathNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.hotspot.replacements.arraycopy;
+
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.type.StampTool;
+import org.graalvm.compiler.replacements.SnippetTemplate;
+import org.graalvm.compiler.replacements.nodes.BasicArrayCopyNode;
+
+import jdk.vm.ci.code.BytecodeFrame;
+import jdk.vm.ci.meta.JavaKind;
+
+@NodeInfo(allowedUsageTypes = InputType.Memory)
+public final class ArrayCopyWithSlowPathNode extends BasicArrayCopyNode {
+
+ public static final NodeClass<ArrayCopyWithSlowPathNode> TYPE = NodeClass.create(ArrayCopyWithSlowPathNode.class);
+
+ private final SnippetTemplate.SnippetInfo snippet;
+
+ public ArrayCopyWithSlowPathNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, SnippetTemplate.SnippetInfo snippet, JavaKind elementKind) {
+ super(TYPE, src, srcPos, dest, destPos, length, elementKind, BytecodeFrame.INVALID_FRAMESTATE_BCI);
+ assert StampTool.isPointerNonNull(src) && StampTool.isPointerNonNull(dest) : "must have been null checked";
+ this.snippet = snippet;
+ }
+
+ @NodeIntrinsic
+ public static native void arraycopy(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, @ConstantNodeParameter SnippetTemplate.SnippetInfo snippet,
+ @ConstantNodeParameter JavaKind elementKind);
+
+ public SnippetTemplate.SnippetInfo getSnippet() {
+ return snippet;
+ }
+
+ public void setBci(int bci) {
+ this.bci = bci;
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -23,12 +23,13 @@
//JaCoCo Exclude
package org.graalvm.compiler.hotspot.replacements.arraycopy;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale;
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_UNKNOWN;
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale;
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
+import org.graalvm.compiler.core.common.type.PrimitiveStamp;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
@@ -114,8 +115,9 @@
graph().addBeforeFixed(this, basePtr);
int shift = CodeUtil.log2(getArrayIndexScale(JavaKind.Object));
- ValueNode scaledIndex = graph().unique(new LeftShiftNode(pos, ConstantNode.forInt(shift, graph())));
- ValueNode offset = graph().unique(new AddNode(scaledIndex, ConstantNode.forInt(getArrayBaseOffset(JavaKind.Object), graph())));
+ ValueNode extendedPos = IntegerConvertNode.convert(pos, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph());
+ ValueNode scaledIndex = graph().unique(new LeftShiftNode(extendedPos, ConstantNode.forInt(shift, graph())));
+ ValueNode offset = graph().unique(new AddNode(scaledIndex, ConstantNode.forIntegerBits(PrimitiveStamp.getBits(scaledIndex.stamp()), getArrayBaseOffset(JavaKind.Object), graph())));
return graph().unique(new OffsetAddressNode(basePtr, offset));
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/GenericArrayCopyCallNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+//JaCoCo Exclude
+package org.graalvm.compiler.hotspot.replacements.arraycopy;
+
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN;
+import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_UNKNOWN;
+
+import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.hotspot.HotSpotBackend;
+import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
+import org.graalvm.compiler.hotspot.nodes.GetObjectAddressNode;
+import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
+import org.graalvm.compiler.nodes.extended.ForeignCallNode;
+import org.graalvm.compiler.nodes.memory.AbstractMemoryCheckpoint;
+import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
+import org.graalvm.compiler.nodes.spi.Lowerable;
+import org.graalvm.compiler.nodes.spi.LoweringTool;
+import org.graalvm.word.LocationIdentity;
+
+import jdk.vm.ci.meta.JavaKind;
+
+@NodeInfo(allowedUsageTypes = {InputType.Memory, InputType.Value}, cycles = CYCLES_UNKNOWN, size = SIZE_UNKNOWN)
+public final class GenericArrayCopyCallNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single {
+
+ public static final NodeClass<GenericArrayCopyCallNode> TYPE = NodeClass.create(GenericArrayCopyCallNode.class);
+ @Input ValueNode src;
+ @Input ValueNode srcPos;
+ @Input ValueNode dest;
+ @Input ValueNode destPos;
+ @Input ValueNode length;
+
+ protected final HotSpotGraalRuntimeProvider runtime;
+
+ protected GenericArrayCopyCallNode(@InjectedNodeParameter HotSpotGraalRuntimeProvider runtime, ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length) {
+ super(TYPE, StampFactory.forKind(JavaKind.Int));
+ this.src = src;
+ this.srcPos = srcPos;
+ this.dest = dest;
+ this.destPos = destPos;
+ this.length = length;
+ this.runtime = runtime;
+ }
+
+ public ValueNode getSource() {
+ return src;
+ }
+
+ public ValueNode getSourcePosition() {
+ return srcPos;
+ }
+
+ public ValueNode getDestination() {
+ return dest;
+ }
+
+ public ValueNode getDestinationPosition() {
+ return destPos;
+ }
+
+ public ValueNode getLength() {
+ return length;
+ }
+
+ @Override
+ public void lower(LoweringTool tool) {
+ if (graph().getGuardsStage().areFrameStatesAtDeopts()) {
+ StructuredGraph graph = graph();
+ ValueNode srcAddr = objectAddress(getSource());
+ ValueNode destAddr = objectAddress(getDestination());
+ ForeignCallNode call = graph.add(new ForeignCallNode(runtime.getHostBackend().getForeignCalls(), HotSpotBackend.GENERIC_ARRAYCOPY, srcAddr, srcPos, destAddr, destPos, length));
+ call.setStateAfter(stateAfter());
+ graph.replaceFixedWithFixed(this, call);
+ }
+ }
+
+ private ValueNode objectAddress(ValueNode obj) {
+ GetObjectAddressNode result = graph().add(new GetObjectAddressNode(obj));
+ graph().addBeforeFixed(this, result);
+ return result;
+ }
+
+ private ValueNode wordValue(ValueNode value) {
+ if (value.stamp().getStackKind() != runtime.getTarget().wordJavaKind) {
+ return IntegerConvertNode.convert(value, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph());
+ }
+ return value;
+ }
+
+ @Override
+ public LocationIdentity getLocationIdentity() {
+ return LocationIdentity.any();
+ }
+
+ @NodeIntrinsic
+ public static native int genericArraycopy(Object src, int srcPos, Object dest, int destPos, int length);
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/UnsafeArrayCopyNode.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.hotspot.replacements.arraycopy;
-
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_256;
-import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
-import static org.graalvm.word.LocationIdentity.any;
-
-import org.graalvm.compiler.core.common.type.StampFactory;
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.nodeinfo.InputType;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.NamedLocationIdentity;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.extended.ArrayRangeWriteNode;
-import org.graalvm.compiler.nodes.memory.MemoryAccess;
-import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
-import org.graalvm.compiler.nodes.memory.MemoryNode;
-import org.graalvm.compiler.nodes.spi.Lowerable;
-import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
-import org.graalvm.word.LocationIdentity;
-
-import jdk.vm.ci.meta.JavaKind;
-
-@NodeInfo(allowedUsageTypes = {InputType.Memory}, cycles = CYCLES_256, size = SIZE_64)
-public final class UnsafeArrayCopyNode extends ArrayRangeWriteNode implements Lowerable, MemoryCheckpoint.Single, MemoryAccess {
-
- public static final NodeClass<UnsafeArrayCopyNode> TYPE = NodeClass.create(UnsafeArrayCopyNode.class);
- @Input ValueNode src;
- @Input ValueNode srcPos;
- @Input ValueNode dest;
- @Input ValueNode destPos;
- @Input ValueNode length;
- @OptionalInput ValueNode layoutHelper;
-
- @OptionalInput(InputType.Memory) MemoryNode lastLocationAccess;
-
- protected JavaKind elementKind;
-
- public UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode layoutHelper, JavaKind elementKind) {
- super(TYPE, StampFactory.forVoid());
- assert layoutHelper == null || elementKind == null;
- this.src = src;
- this.srcPos = srcPos;
- this.dest = dest;
- this.destPos = destPos;
- this.length = length;
- this.layoutHelper = layoutHelper;
- this.elementKind = elementKind;
- }
-
- public UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, JavaKind elementKind) {
- this(src, srcPos, dest, destPos, length, null, elementKind);
- }
-
- public UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode layoutHelper) {
- this(src, srcPos, dest, destPos, length, layoutHelper, null);
- }
-
- @Override
- public ValueNode getArray() {
- return dest;
- }
-
- @Override
- public ValueNode getIndex() {
- return destPos;
- }
-
- @Override
- public ValueNode getLength() {
- return length;
- }
-
- @Override
- public boolean isObjectArray() {
- return elementKind == JavaKind.Object;
- }
-
- @Override
- public boolean isInitialization() {
- return false;
- }
-
- public JavaKind getElementKind() {
- return elementKind;
- }
-
- @Override
- public void lower(LoweringTool tool) {
- if (graph().getGuardsStage().areFrameStatesAtDeopts()) {
- UnsafeArrayCopySnippets.Templates templates = tool.getReplacements().getSnippetTemplateCache(UnsafeArrayCopySnippets.Templates.class);
- templates.lower(this, tool);
- }
- }
-
- public void addSnippetArguments(Arguments args) {
- args.add("src", src);
- args.add("srcPos", srcPos);
- args.add("dest", dest);
- args.add("destPos", destPos);
- args.add("length", length);
- if (layoutHelper != null) {
- args.add("layoutHelper", layoutHelper);
- }
- }
-
- @Override
- public LocationIdentity getLocationIdentity() {
- if (elementKind != null) {
- return NamedLocationIdentity.getArrayLocation(elementKind);
- }
- return any();
- }
-
- @Override
- public MemoryNode getLastLocationAccess() {
- return lastLocationAccess;
- }
-
- @Override
- public void setLastLocationAccess(MemoryNode lla) {
- updateUsagesInterface(lastLocationAccess, lla);
- lastLocationAccess = lla;
- }
-
- @NodeIntrinsic
- public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length, @ConstantNodeParameter JavaKind elementKind);
-
- @NodeIntrinsic
- public static native void arraycopyPrimitive(Object src, int srcPos, Object dest, int destPos, int length, int layoutHelper);
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/UnsafeArrayCopySnippets.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,324 +0,0 @@
-/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.hotspot.replacements.arraycopy;
-
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale;
-import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayBaseOffset;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayIndexScale;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperHeaderSizeMask;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperHeaderSizeShift;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperLog2ElementSizeMask;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperLog2ElementSizeShift;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.runtime;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.wordSize;
-import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.NOT_FREQUENT_PROBABILITY;
-import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability;
-import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER;
-import static org.graalvm.word.LocationIdentity.any;
-
-import org.graalvm.compiler.api.replacements.Fold;
-import org.graalvm.compiler.api.replacements.Snippet;
-import org.graalvm.compiler.core.common.NumUtil;
-import org.graalvm.compiler.debug.DebugHandlersFactory;
-import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
-import org.graalvm.compiler.hotspot.phases.WriteBarrierAdditionPhase;
-import org.graalvm.compiler.nodes.NamedLocationIdentity;
-import org.graalvm.compiler.nodes.extended.RawLoadNode;
-import org.graalvm.compiler.nodes.extended.RawStoreNode;
-import org.graalvm.compiler.nodes.extended.UnsafeCopyNode;
-import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.replacements.SnippetTemplate;
-import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates;
-import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
-import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
-import org.graalvm.compiler.replacements.Snippets;
-import org.graalvm.compiler.word.ObjectAccess;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.UnsignedWord;
-import org.graalvm.word.WordFactory;
-
-import jdk.vm.ci.code.TargetDescription;
-import jdk.vm.ci.meta.JavaKind;
-
-/**
- * As opposed to {@link ArrayCopySnippets}, these Snippets do <b>not</b> perform store checks.
- */
-public class UnsafeArrayCopySnippets implements Snippets {
-
- private static final boolean supportsUnalignedMemoryAccess = runtime().getHostJVMCIBackend().getTarget().arch.supportsUnalignedMemoryAccess();
-
- private static final JavaKind VECTOR_KIND = JavaKind.Long;
- private static final long VECTOR_SIZE = getArrayIndexScale(VECTOR_KIND);
-
- private static void vectorizedCopy(Object src, int srcPos, Object dest, int destPos, int length, JavaKind baseKind, LocationIdentity locationIdentity) {
- int arrayBaseOffset = arrayBaseOffset(baseKind);
- int elementSize = arrayIndexScale(baseKind);
- long byteLength = (long) length * elementSize;
- long srcOffset = (long) srcPos * elementSize;
- long destOffset = (long) destPos * elementSize;
-
- long preLoopBytes;
- long mainLoopBytes;
- long postLoopBytes;
-
- // We can easily vectorize the loop if both offsets have the same alignment.
- if (byteLength >= VECTOR_SIZE && (srcOffset % VECTOR_SIZE) == (destOffset % VECTOR_SIZE)) {
- preLoopBytes = NumUtil.roundUp(arrayBaseOffset + srcOffset, VECTOR_SIZE) - (arrayBaseOffset + srcOffset);
- postLoopBytes = (byteLength - preLoopBytes) % VECTOR_SIZE;
- mainLoopBytes = byteLength - preLoopBytes - postLoopBytes;
- } else {
- // Does the architecture support unaligned memory accesses?
- if (supportsUnalignedMemoryAccess) {
- preLoopBytes = byteLength % VECTOR_SIZE;
- mainLoopBytes = byteLength - preLoopBytes;
- postLoopBytes = 0;
- } else {
- // No. Let's do element-wise copying.
- preLoopBytes = byteLength;
- mainLoopBytes = 0;
- postLoopBytes = 0;
- }
- }
-
- if (probability(NOT_FREQUENT_PROBABILITY, src == dest) && probability(NOT_FREQUENT_PROBABILITY, srcPos < destPos)) {
- // bad aliased case
- srcOffset += byteLength;
- destOffset += byteLength;
-
- // Post-loop
- for (long i = 0; i < postLoopBytes; i += elementSize) {
- srcOffset -= elementSize;
- destOffset -= elementSize;
- UnsafeCopyNode.copy(src, arrayBaseOffset + srcOffset, dest, arrayBaseOffset + destOffset, baseKind, locationIdentity);
- }
- // Main-loop
- for (long i = 0; i < mainLoopBytes; i += VECTOR_SIZE) {
- srcOffset -= VECTOR_SIZE;
- destOffset -= VECTOR_SIZE;
- UnsafeCopyNode.copy(src, arrayBaseOffset + srcOffset, dest, arrayBaseOffset + destOffset, VECTOR_KIND, locationIdentity);
- }
- // Pre-loop
- for (long i = 0; i < preLoopBytes; i += elementSize) {
- srcOffset -= elementSize;
- destOffset -= elementSize;
- UnsafeCopyNode.copy(src, arrayBaseOffset + srcOffset, dest, arrayBaseOffset + destOffset, baseKind, locationIdentity);
- }
- } else {
- // Pre-loop
- for (long i = 0; i < preLoopBytes; i += elementSize) {
- UnsafeCopyNode.copy(src, arrayBaseOffset + srcOffset, dest, arrayBaseOffset + destOffset, baseKind, locationIdentity);
- srcOffset += elementSize;
- destOffset += elementSize;
- }
- // Main-loop
- for (long i = 0; i < mainLoopBytes; i += VECTOR_SIZE) {
- UnsafeCopyNode.copy(src, arrayBaseOffset + srcOffset, dest, arrayBaseOffset + destOffset, VECTOR_KIND, locationIdentity);
- srcOffset += VECTOR_SIZE;
- destOffset += VECTOR_SIZE;
- }
- // Post-loop
- for (long i = 0; i < postLoopBytes; i += elementSize) {
- UnsafeCopyNode.copy(src, arrayBaseOffset + srcOffset, dest, arrayBaseOffset + destOffset, baseKind, locationIdentity);
- srcOffset += elementSize;
- destOffset += elementSize;
- }
- }
- }
-
- @Fold
- static LocationIdentity getArrayLocation(JavaKind kind) {
- return NamedLocationIdentity.getArrayLocation(kind);
- }
-
- @Snippet
- public static void arraycopyByte(byte[] src, int srcPos, byte[] dest, int destPos, int length) {
- JavaKind kind = JavaKind.Byte;
- vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
- }
-
- @Snippet
- public static void arraycopyBoolean(boolean[] src, int srcPos, boolean[] dest, int destPos, int length) {
- JavaKind kind = JavaKind.Boolean;
- vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
- }
-
- @Snippet
- public static void arraycopyChar(char[] src, int srcPos, char[] dest, int destPos, int length) {
- JavaKind kind = JavaKind.Char;
- vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
- }
-
- @Snippet
- public static void arraycopyShort(short[] src, int srcPos, short[] dest, int destPos, int length) {
- JavaKind kind = JavaKind.Short;
- vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
- }
-
- @Snippet
- public static void arraycopyInt(int[] src, int srcPos, int[] dest, int destPos, int length) {
- JavaKind kind = JavaKind.Int;
- vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
- }
-
- @Snippet
- public static void arraycopyFloat(float[] src, int srcPos, float[] dest, int destPos, int length) {
- JavaKind kind = JavaKind.Float;
- vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
- }
-
- @Snippet
- public static void arraycopyLong(long[] src, int srcPos, long[] dest, int destPos, int length) {
- JavaKind kind = JavaKind.Long;
- vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
- }
-
- @Snippet
- public static void arraycopyDouble(double[] src, int srcPos, double[] dest, int destPos, int length) {
- JavaKind kind = JavaKind.Double;
- /*
- * TODO atomicity problem on 32-bit architectures: The JVM spec requires double values to be
- * copied atomically, but not long values. For example, on Intel 32-bit this code is not
- * atomic as long as the vector kind remains Kind.Long.
- */
- vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
- }
-
- /**
- * For this kind, Object, we want to avoid write barriers between writes, but instead have them
- * at the end of the snippet. This is done by using {@link RawStoreNode}, and rely on
- * {@link WriteBarrierAdditionPhase} to put write barriers after the {@link UnsafeArrayCopyNode}
- * with kind Object.
- */
- @Snippet
- public static void arraycopyObject(Object[] src, int srcPos, Object[] dest, int destPos, int length) {
- JavaKind kind = JavaKind.Object;
- final int scale = arrayIndexScale(kind);
- int arrayBaseOffset = arrayBaseOffset(kind);
- LocationIdentity arrayLocation = getArrayLocation(kind);
- if (src == dest && srcPos < destPos) { // bad aliased case
- long start = (long) (length - 1) * scale;
- for (long i = start; i >= 0; i -= scale) {
- Object a = RawLoadNode.load(src, arrayBaseOffset + i + (long) srcPos * scale, kind, arrayLocation);
- RawStoreNode.storeObject(dest, arrayBaseOffset + i + (long) destPos * scale, a, kind, getArrayLocation(kind), false);
- }
- } else {
- long end = (long) length * scale;
- for (long i = 0; i < end; i += scale) {
- Object a = RawLoadNode.load(src, arrayBaseOffset + i + (long) srcPos * scale, kind, arrayLocation);
- RawStoreNode.storeObject(dest, arrayBaseOffset + i + (long) destPos * scale, a, kind, getArrayLocation(kind), false);
- }
- }
- }
-
- @Snippet
- public static void arraycopyPrimitive(Object src, int srcPos, Object dest, int destPos, int length, int layoutHelper) {
- int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift(INJECTED_VMCONFIG)) & layoutHelperLog2ElementSizeMask(INJECTED_VMCONFIG);
- int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift(INJECTED_VMCONFIG)) & layoutHelperHeaderSizeMask(INJECTED_VMCONFIG);
-
- UnsignedWord vectorSize = WordFactory.unsigned(VECTOR_SIZE);
- UnsignedWord srcOffset = WordFactory.unsigned(srcPos).shiftLeft(log2ElementSize).add(headerSize);
- UnsignedWord destOffset = WordFactory.unsigned(destPos).shiftLeft(log2ElementSize).add(headerSize);
- UnsignedWord destStart = destOffset;
- UnsignedWord destEnd = destOffset.add(WordFactory.unsigned(length).shiftLeft(log2ElementSize));
-
- UnsignedWord destVectorEnd = null;
- UnsignedWord nonVectorBytes = null;
- UnsignedWord sizeInBytes = WordFactory.unsigned(length).shiftLeft(log2ElementSize);
- if (supportsUnalignedMemoryAccess) {
- nonVectorBytes = sizeInBytes.unsignedRemainder(vectorSize);
- destVectorEnd = destEnd;
- } else {
- boolean inPhase = srcOffset.and((int) VECTOR_SIZE - 1).equal(destOffset.and((int) VECTOR_SIZE - 1));
- boolean hasAtLeastOneVector = sizeInBytes.aboveOrEqual(vectorSize);
- // We must have at least one full vector, otherwise we must copy each byte separately
- if (hasAtLeastOneVector && inPhase) { // If in phase, we can vectorize
- nonVectorBytes = vectorSize.subtract(destStart.unsignedRemainder(vectorSize));
- } else { // fallback is byte-wise
- nonVectorBytes = sizeInBytes;
- }
- destVectorEnd = destEnd.subtract(destEnd.unsignedRemainder(vectorSize));
- }
-
- UnsignedWord destNonVectorEnd = destStart.add(nonVectorBytes);
- while (destOffset.belowThan(destNonVectorEnd)) {
- ObjectAccess.writeByte(dest, destOffset, ObjectAccess.readByte(src, srcOffset, any()), any());
- destOffset = destOffset.add(1);
- srcOffset = srcOffset.add(1);
- }
- // Unsigned destVectorEnd = destEnd.subtract(destEnd.unsignedRemainder(8));
- while (destOffset.belowThan(destVectorEnd)) {
- ObjectAccess.writeWord(dest, destOffset, ObjectAccess.readWord(src, srcOffset, any()), any());
- destOffset = destOffset.add(wordSize());
- srcOffset = srcOffset.add(wordSize());
- }
- // Do the last bytes each when it is required to have absolute alignment.
- while (!supportsUnalignedMemoryAccess && destOffset.belowThan(destEnd)) {
- ObjectAccess.writeByte(dest, destOffset, ObjectAccess.readByte(src, srcOffset, any()), any());
- destOffset = destOffset.add(1);
- srcOffset = srcOffset.add(1);
- }
- }
-
- public static class Templates extends AbstractTemplates {
-
- private final SnippetInfo[] arraycopySnippets;
- private final SnippetInfo genericPrimitiveSnippet;
-
- public Templates(OptionValues options, Iterable<DebugHandlersFactory> factories, HotSpotProviders providers, TargetDescription target) {
- super(options, factories, providers, providers.getSnippetReflection(), target);
-
- arraycopySnippets = new SnippetInfo[JavaKind.values().length];
- arraycopySnippets[JavaKind.Boolean.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyBoolean");
- arraycopySnippets[JavaKind.Byte.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyByte");
- arraycopySnippets[JavaKind.Short.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyShort");
- arraycopySnippets[JavaKind.Char.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyChar");
- arraycopySnippets[JavaKind.Int.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyInt");
- arraycopySnippets[JavaKind.Long.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyLong");
- arraycopySnippets[JavaKind.Float.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyFloat");
- arraycopySnippets[JavaKind.Double.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyDouble");
- arraycopySnippets[JavaKind.Object.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyObject");
-
- genericPrimitiveSnippet = snippet(UnsafeArrayCopySnippets.class, "arraycopyPrimitive");
- }
-
- public void lower(UnsafeArrayCopyNode node, LoweringTool tool) {
- JavaKind elementKind = node.getElementKind();
- SnippetInfo snippet;
- if (elementKind == null) {
- // primitive array of unknown kind
- snippet = genericPrimitiveSnippet;
- } else {
- snippet = arraycopySnippets[elementKind.ordinal()];
- assert snippet != null : "arraycopy snippet for " + elementKind.name() + " not found";
- }
-
- Arguments args = new Arguments(snippet, node.graph().getGuardsStage(), tool.getLoweringStage());
- node.addSnippetArguments(args);
-
- SnippetTemplate template = template(node.getDebug(), args);
- template.instantiate(providers.getMetaAccess(), node, DEFAULT_REPLACER, args);
- }
- }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/profiling/ProbabilisticProfileSnippets.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/profiling/ProbabilisticProfileSnippets.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -54,6 +54,7 @@
import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
import org.graalvm.compiler.replacements.Snippets;
+import jdk.vm.ci.code.CodeUtil;
import jdk.vm.ci.code.TargetDescription;
public class ProbabilisticProfileSnippets implements Snippets {
@@ -64,22 +65,22 @@
}
@Snippet
- public static int notificationMask(int freqLog, int probLog) {
- int probabilityMask = (1 << probLog) - 1;
+ public static int notificationMask(int freqLog, int probLog, int stepLog) {
int frequencyMask = (1 << freqLog) - 1;
- return frequencyMask & ~probabilityMask;
+ int stepMask = (1 << (stepLog + probLog)) - 1;
+ return frequencyMask & ~stepMask;
}
@NodeIntrinsic(ForeignCallNode.class)
public static native void methodInvocationEvent(@ConstantNodeParameter ForeignCallDescriptor descriptor, MethodCountersPointer counters);
@Snippet
- public static void profileMethodEntryWithProbability(MethodCountersPointer counters, int random, @ConstantParameter int freqLog, @ConstantParameter int probLog) {
+ public static void profileMethodEntryWithProbability(MethodCountersPointer counters, int random, int step, int stepLog, @ConstantParameter int freqLog, @ConstantParameter int probLog) {
if (probability(1.0 / (1 << probLog), shouldProfile(probLog, random))) {
- int counterValue = counters.readInt(config(INJECTED_VMCONFIG).invocationCounterOffset) + (config(INJECTED_VMCONFIG).invocationCounterIncrement << probLog);
+ int counterValue = counters.readInt(config(INJECTED_VMCONFIG).invocationCounterOffset) + ((config(INJECTED_VMCONFIG).invocationCounterIncrement * step) << probLog);
counters.writeInt(config(INJECTED_VMCONFIG).invocationCounterOffset, counterValue);
if (freqLog >= 0) {
- int mask = notificationMask(freqLog, probLog);
+ int mask = notificationMask(freqLog, probLog, stepLog);
if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
methodInvocationEvent(HotSpotBackend.INVOCATION_EVENT, counters);
}
@@ -91,11 +92,12 @@
public static native void methodBackedgeEvent(@ConstantNodeParameter ForeignCallDescriptor descriptor, MethodCountersPointer counters, int bci, int targetBci);
@Snippet
- public static void profileBackedgeWithProbability(MethodCountersPointer counters, int random, @ConstantParameter int freqLog, @ConstantParameter int probLog, int bci, int targetBci) {
+ public static void profileBackedgeWithProbability(MethodCountersPointer counters, int random, int step, int stepLog, @ConstantParameter int freqLog, @ConstantParameter int probLog, int bci,
+ int targetBci) {
if (probability(1.0 / (1 << probLog), shouldProfile(probLog, random))) {
- int counterValue = counters.readInt(config(INJECTED_VMCONFIG).backedgeCounterOffset) + (config(INJECTED_VMCONFIG).invocationCounterIncrement << probLog);
+ int counterValue = counters.readInt(config(INJECTED_VMCONFIG).backedgeCounterOffset) + ((config(INJECTED_VMCONFIG).invocationCounterIncrement * step) << probLog);
counters.writeInt(config(INJECTED_VMCONFIG).backedgeCounterOffset, counterValue);
- int mask = notificationMask(freqLog, probLog);
+ int mask = notificationMask(freqLog, probLog, stepLog);
if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
methodBackedgeEvent(HotSpotBackend.BACKEDGE_EVENT, counters, bci, targetBci);
}
@@ -103,10 +105,11 @@
}
@Snippet
- public static void profileConditionalBackedgeWithProbability(MethodCountersPointer counters, int random, @ConstantParameter int freqLog, @ConstantParameter int probLog, boolean branchCondition,
+ public static void profileConditionalBackedgeWithProbability(MethodCountersPointer counters, int random, int step, int stepLog, @ConstantParameter int freqLog,
+ @ConstantParameter int probLog, boolean branchCondition,
int bci, int targetBci) {
if (branchCondition) {
- profileBackedgeWithProbability(counters, random, freqLog, probLog, bci, targetBci);
+ profileBackedgeWithProbability(counters, random, step, stepLog, freqLog, probLog, bci, targetBci);
}
}
@@ -124,6 +127,8 @@
StructuredGraph graph = profileNode.graph();
LoadMethodCountersNode counters = graph.unique(new LoadMethodCountersNode(profileNode.getProfiledMethod()));
+ ConstantNode step = ConstantNode.forInt(profileNode.getStep(), graph);
+ ConstantNode stepLog = ConstantNode.forInt(CodeUtil.log2(profileNode.getStep()), graph);
if (profileNode instanceof ProfileBranchNode) {
// Backedge event
@@ -132,8 +137,11 @@
Arguments args = new Arguments(snippet, graph.getGuardsStage(), tool.getLoweringStage());
ConstantNode bci = ConstantNode.forInt(profileBranchNode.bci(), graph);
ConstantNode targetBci = ConstantNode.forInt(profileBranchNode.targetBci(), graph);
+
args.add("counters", counters);
args.add("random", profileBranchNode.getRandom());
+ args.add("step", step);
+ args.add("stepLog", stepLog);
args.addConst("freqLog", profileBranchNode.getNotificationFreqLog());
args.addConst("probLog", profileBranchNode.getProbabilityLog());
if (profileBranchNode.hasCondition()) {
@@ -148,8 +156,11 @@
ProfileInvokeNode profileInvokeNode = (ProfileInvokeNode) profileNode;
// Method invocation event
Arguments args = new Arguments(profileMethodEntryWithProbability, graph.getGuardsStage(), tool.getLoweringStage());
+
args.add("counters", counters);
args.add("random", profileInvokeNode.getRandom());
+ args.add("step", step);
+ args.add("stepLog", stepLog);
args.addConst("freqLog", profileInvokeNode.getNotificationFreqLog());
args.addConst("probLog", profileInvokeNode.getProbabilityLog());
SnippetTemplate template = template(graph.getDebug(), args);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/profiling/ProfileSnippets.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/profiling/ProfileSnippets.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -54,6 +54,7 @@
import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
import org.graalvm.compiler.replacements.Snippets;
+import jdk.vm.ci.code.CodeUtil;
import jdk.vm.ci.code.TargetDescription;
public class ProfileSnippets implements Snippets {
@@ -61,12 +62,19 @@
public static native void methodInvocationEvent(@ConstantNodeParameter ForeignCallDescriptor descriptor, MethodCountersPointer counters);
@Snippet
- public static void profileMethodEntry(MethodCountersPointer counters, @ConstantParameter int freqLog) {
- int counterValue = counters.readInt(config(INJECTED_VMCONFIG).invocationCounterOffset) + config(INJECTED_VMCONFIG).invocationCounterIncrement;
+ protected static int notificationMask(int freqLog, int stepLog) {
+ int stepMask = (1 << stepLog) - 1;
+ int frequencyMask = (1 << freqLog) - 1;
+ return frequencyMask & ~stepMask;
+ }
+
+ @Snippet
+ public static void profileMethodEntry(MethodCountersPointer counters, int step, int stepLog, @ConstantParameter int freqLog) {
+ int counterValue = counters.readInt(config(INJECTED_VMCONFIG).invocationCounterOffset) + config(INJECTED_VMCONFIG).invocationCounterIncrement * step;
counters.writeInt(config(INJECTED_VMCONFIG).invocationCounterOffset, counterValue);
if (freqLog >= 0) {
- final int frequencyMask = (1 << freqLog) - 1;
- if (probability(SLOW_PATH_PROBABILITY, (counterValue & (frequencyMask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
+ final int mask = notificationMask(freqLog, stepLog);
+ if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
methodInvocationEvent(HotSpotBackend.INVOCATION_EVENT, counters);
}
}
@@ -76,19 +84,19 @@
public static native void methodBackedgeEvent(@ConstantNodeParameter ForeignCallDescriptor descriptor, MethodCountersPointer counters, int bci, int targetBci);
@Snippet
- public static void profileBackedge(MethodCountersPointer counters, @ConstantParameter int freqLog, int bci, int targetBci) {
- int counterValue = counters.readInt(config(INJECTED_VMCONFIG).backedgeCounterOffset) + config(INJECTED_VMCONFIG).invocationCounterIncrement;
+ public static void profileBackedge(MethodCountersPointer counters, int step, int stepLog, @ConstantParameter int freqLog, int bci, int targetBci) {
+ int counterValue = counters.readInt(config(INJECTED_VMCONFIG).backedgeCounterOffset) + config(INJECTED_VMCONFIG).invocationCounterIncrement * step;
counters.writeInt(config(INJECTED_VMCONFIG).backedgeCounterOffset, counterValue);
- final int frequencyMask = (1 << freqLog) - 1;
- if (probability(SLOW_PATH_PROBABILITY, (counterValue & (frequencyMask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
+ final int mask = notificationMask(freqLog, stepLog);
+ if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
methodBackedgeEvent(HotSpotBackend.BACKEDGE_EVENT, counters, bci, targetBci);
}
}
@Snippet
- public static void profileConditionalBackedge(MethodCountersPointer counters, @ConstantParameter int freqLog, boolean branchCondition, int bci, int targetBci) {
+ public static void profileConditionalBackedge(MethodCountersPointer counters, int step, int stepLog, @ConstantParameter int freqLog, boolean branchCondition, int bci, int targetBci) {
if (branchCondition) {
- profileBackedge(counters, freqLog, bci, targetBci);
+ profileBackedge(counters, step, stepLog, freqLog, bci, targetBci);
}
}
@@ -104,6 +112,8 @@
public void lower(ProfileNode profileNode, LoweringTool tool) {
StructuredGraph graph = profileNode.graph();
LoadMethodCountersNode counters = graph.unique(new LoadMethodCountersNode(profileNode.getProfiledMethod()));
+ ConstantNode step = ConstantNode.forInt(profileNode.getStep(), graph);
+ ConstantNode stepLog = ConstantNode.forInt(CodeUtil.log2(profileNode.getStep()), graph);
if (profileNode instanceof ProfileBranchNode) {
// Backedge event
@@ -113,6 +123,8 @@
ConstantNode bci = ConstantNode.forInt(profileBranchNode.bci(), graph);
ConstantNode targetBci = ConstantNode.forInt(profileBranchNode.targetBci(), graph);
args.add("counters", counters);
+ args.add("step", step);
+ args.add("stepLog", stepLog);
args.addConst("freqLog", profileBranchNode.getNotificationFreqLog());
if (profileBranchNode.hasCondition()) {
args.add("branchCondition", profileBranchNode.branchCondition());
@@ -127,6 +139,8 @@
// Method invocation event
Arguments args = new Arguments(profileMethodEntry, graph.getGuardsStage(), tool.getLoweringStage());
args.add("counters", counters);
+ args.add("step", step);
+ args.add("stepLog", stepLog);
args.addConst("freqLog", profileInvokeNode.getNotificationFreqLog());
SnippetTemplate template = template(graph.getDebug(), args);
template.instantiate(providers.getMetaAccess(), profileNode, DEFAULT_REPLACER, args);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewArrayStub.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewArrayStub.java Wed Nov 08 16:03:35 2017 -0500
@@ -33,6 +33,7 @@
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperLog2ElementSizeShift;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readLayoutHelper;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useCMSIncrementalMode;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.wordSize;
import static org.graalvm.compiler.hotspot.replacements.NewObjectSnippets.MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH;
import static org.graalvm.compiler.hotspot.replacements.NewObjectSnippets.formatArray;
@@ -122,7 +123,7 @@
// check that array length is small enough for fast path.
Word thread = registerAsWord(threadRegister);
boolean inlineContiguousAllocationSupported = GraalHotSpotVMConfigNode.inlineContiguousAllocationSupported();
- if (inlineContiguousAllocationSupported && length >= 0 && length <= MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH) {
+ if (inlineContiguousAllocationSupported && !useCMSIncrementalMode(INJECTED_VMCONFIG) && length >= 0 && length <= MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH) {
Word memory = refillAllocate(thread, intArrayHub, sizeInBytes, logging(options));
if (memory.notEqual(0)) {
if (logging(options)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewInstanceStub.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewInstanceStub.java Wed Nov 08 16:03:35 2017 -0500
@@ -53,6 +53,7 @@
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.tlabRefillWasteLimitOffset;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.tlabSlowAllocationsOffset;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.tlabStats;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useCMSIncrementalMode;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useG1GC;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useTLAB;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.wordSize;
@@ -147,7 +148,7 @@
*/
Word thread = registerAsWord(threadRegister);
boolean inlineContiguousAllocationSupported = GraalHotSpotVMConfigNode.inlineContiguousAllocationSupported();
- if (!forceSlowPath(options) && inlineContiguousAllocationSupported) {
+ if (!forceSlowPath(options) && inlineContiguousAllocationSupported && !useCMSIncrementalMode(INJECTED_VMCONFIG)) {
if (isInstanceKlassFullyInitialized(hub)) {
int sizeInBytes = readLayoutHelper(hub);
Word memory = refillAllocate(thread, intArrayHub, sizeInBytes, logging(options));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Wed Nov 08 16:03:35 2017 -0500
@@ -342,7 +342,7 @@
import org.graalvm.compiler.nodes.calc.AndNode;
import org.graalvm.compiler.nodes.calc.CompareNode;
import org.graalvm.compiler.nodes.calc.ConditionalNode;
-import org.graalvm.compiler.nodes.calc.DivNode;
+import org.graalvm.compiler.nodes.calc.FloatDivNode;
import org.graalvm.compiler.nodes.calc.FloatConvertNode;
import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
import org.graalvm.compiler.nodes.calc.IntegerEqualsNode;
@@ -374,7 +374,6 @@
import org.graalvm.compiler.nodes.extended.StateSplitProxyNode;
import org.graalvm.compiler.nodes.extended.ValueAnchorNode;
import org.graalvm.compiler.nodes.graphbuilderconf.ClassInitializationPlugin;
-import org.graalvm.compiler.nodes.graphbuilderconf.InvokeDynamicPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.BytecodeExceptionMode;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
@@ -383,6 +382,7 @@
import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.InvocationPluginReceiver;
+import org.graalvm.compiler.nodes.graphbuilderconf.InvokeDynamicPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.ProfilingPlugin;
import org.graalvm.compiler.nodes.java.ArrayLengthNode;
@@ -435,6 +435,7 @@
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.Signature;
import jdk.vm.ci.meta.TriState;
+import org.graalvm.compiler.core.common.type.IntegerStamp;
/**
* The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph.
@@ -1036,7 +1037,7 @@
deopt.updateNodeSourcePosition(() -> createBytecodePosition());
}
- private AbstractBeginNode handleException(ValueNode exceptionObject, int bci) {
+ private AbstractBeginNode handleException(ValueNode exceptionObject, int bci, boolean deoptimizeOnly) {
assert bci == BytecodeFrame.BEFORE_BCI || bci == bci() : "invalid bci";
debug.log("Creating exception dispatch edges at %d, exception object=%s, exception seen=%s", bci, exceptionObject, (profilingInfo == null ? "" : profilingInfo.getExceptionSeen(bci)));
@@ -1058,8 +1059,12 @@
this.controlFlowSplit = true;
FixedWithNextNode finishedDispatch = finishInstruction(dispatchBegin, dispatchState);
- createHandleExceptionTarget(finishedDispatch, bci, dispatchState);
-
+ if (deoptimizeOnly) {
+ DeoptimizeNode deoptimizeNode = graph.add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter));
+ dispatchBegin.setNext(BeginNode.begin(deoptimizeNode));
+ } else {
+ createHandleExceptionTarget(finishedDispatch, bci, dispatchState);
+ }
return dispatchBegin;
}
@@ -1111,7 +1116,7 @@
}
protected ValueNode genFloatDiv(ValueNode x, ValueNode y) {
- return DivNode.create(x, y);
+ return FloatDivNode.create(x, y);
}
protected ValueNode genFloatRem(ValueNode x, ValueNode y) {
@@ -1215,7 +1220,7 @@
ValueNode exception = frameState.pop(JavaKind.Object);
FixedGuardNode nullCheck = append(new FixedGuardNode(graph.addOrUniqueWithInputs(IsNullNode.create(exception)), NullCheckException, InvalidateReprofile, true));
ValueNode nonNullException = graph.maybeAddOrUnique(PiNode.create(exception, exception.stamp().join(objectNonNull()), nullCheck));
- lastInstr.setNext(handleException(nonNullException, bci()));
+ lastInstr.setNext(handleException(nonNullException, bci(), false));
}
protected LogicNode createInstanceOf(TypeReference type, ValueNode object) {
@@ -1275,12 +1280,12 @@
}
BytecodeExceptionNode exception = graph.add(new BytecodeExceptionNode(metaAccess, NullPointerException.class));
AbstractBeginNode falseSucc = graph.add(new BeginNode());
- ValueNode nonNullReceiver = graph.addOrUnique(PiNode.create(receiver, objectNonNull(), falseSucc));
+ ValueNode nonNullReceiver = graph.addOrUniqueWithInputs(PiNode.create(receiver, objectNonNull(), falseSucc));
append(new IfNode(graph.addOrUniqueWithInputs(IsNullNode.create(receiver)), exception, falseSucc, SLOW_PATH_PROBABILITY));
lastInstr = falseSucc;
exception.setStateAfter(createFrameState(bci(), exception));
- exception.setNext(handleException(exception, bci()));
+ exception.setNext(handleException(exception, bci(), false));
EXPLICIT_EXCEPTIONS.increment(debug);
return nonNullReceiver;
}
@@ -1292,7 +1297,7 @@
lastInstr = trueSucc;
exception.setStateAfter(createFrameState(bci(), exception));
- exception.setNext(handleException(exception, bci()));
+ exception.setNext(handleException(exception, bci(), false));
}
protected ValueNode genArrayLength(ValueNode x) {
@@ -1532,8 +1537,8 @@
@Override
public void handleReplacedInvoke(CallTargetNode callTarget, JavaKind resultType) {
BytecodeParser intrinsicCallSiteParser = getNonIntrinsicAncestor();
- boolean withExceptionEdge = intrinsicCallSiteParser == null ? !omitInvokeExceptionEdge(null) : !intrinsicCallSiteParser.omitInvokeExceptionEdge(null);
- createNonInlinedInvoke(withExceptionEdge, bci(), callTarget, resultType);
+ ExceptionEdgeAction exceptionEdgeAction = intrinsicCallSiteParser == null ? getActionForInvokeExceptionEdge(null) : intrinsicCallSiteParser.getActionForInvokeExceptionEdge(null);
+ createNonInlinedInvoke(exceptionEdgeAction, bci(), callTarget, resultType);
}
protected Invoke appendInvoke(InvokeKind initialInvokeKind, ResolvedJavaMethod initialTargetMethod, ValueNode[] args) {
@@ -1603,7 +1608,7 @@
int invokeBci = bci();
JavaTypeProfile profile = getProfileForInvoke(invokeKind);
- boolean withExceptionEdge = !omitInvokeExceptionEdge(inlineInfo);
+ ExceptionEdgeAction edgeAction = getActionForInvokeExceptionEdge(inlineInfo);
boolean partialIntrinsicExit = false;
if (intrinsicContext != null && intrinsicContext.isCallToOriginal(targetMethod)) {
partialIntrinsicExit = true;
@@ -1614,7 +1619,7 @@
// must use the same context as the call to the intrinsic.
invokeBci = intrinsicCallSiteParser.bci();
profile = intrinsicCallSiteParser.getProfileForInvoke(invokeKind);
- withExceptionEdge = !intrinsicCallSiteParser.omitInvokeExceptionEdge(inlineInfo);
+ edgeAction = intrinsicCallSiteParser.getActionForInvokeExceptionEdge(inlineInfo);
} else {
// We are parsing the intrinsic for the root compilation or for inlining,
// This call is a partial intrinsic exit, and we do not have profile information
@@ -1624,7 +1629,7 @@
assert intrinsicContext.isPostParseInlined();
invokeBci = BytecodeFrame.UNKNOWN_BCI;
profile = null;
- withExceptionEdge = graph.method().getAnnotation(Snippet.class) == null;
+ edgeAction = graph.method().getAnnotation(Snippet.class) == null ? ExceptionEdgeAction.INCLUDE_AND_HANDLE : ExceptionEdgeAction.OMIT;
}
if (originalMethod.isStatic()) {
@@ -1637,10 +1642,10 @@
Signature sig = originalMethod.getSignature();
returnType = sig.getReturnType(method.getDeclaringClass());
resultType = sig.getReturnKind();
- assert checkPartialIntrinsicExit(intrinsicCallSiteParser == null ? null : intrinsicCallSiteParser.currentInvoke.args, args);
+ assert intrinsicContext.allowPartialIntrinsicArgumentMismatch() || checkPartialIntrinsicExit(intrinsicCallSiteParser == null ? null : intrinsicCallSiteParser.currentInvoke.args, args);
targetMethod = originalMethod;
}
- Invoke invoke = createNonInlinedInvoke(withExceptionEdge, invokeBci, args, targetMethod, invokeKind, resultType, returnType, profile);
+ Invoke invoke = createNonInlinedInvoke(edgeAction, invokeBci, args, targetMethod, invokeKind, resultType, returnType, profile);
if (partialIntrinsicExit) {
// This invoke must never be later inlined as it might select the intrinsic graph.
// Until there is a mechanism to guarantee that any late inlining will not select
@@ -1698,14 +1703,14 @@
} else {
for (int i = 0; i < recursiveArgs.length; i++) {
ValueNode arg = GraphUtil.unproxify(recursiveArgs[i]);
- assert arg instanceof ParameterNode && ((ParameterNode) arg).index() == i : String.format("argument %d of call denoting partial intrinsic exit should be a %s with index %d, not %s", i,
- ParameterNode.class.getSimpleName(), i, arg);
+ assert arg instanceof ParameterNode && ((ParameterNode) arg).index() == i : String.format("argument %d of call denoting partial intrinsic exit should be a %s with index %d, not %s",
+ i, ParameterNode.class.getSimpleName(), i, arg);
}
}
return true;
}
- protected Invoke createNonInlinedInvoke(boolean withExceptionEdge, int invokeBci, ValueNode[] invokeArgs, ResolvedJavaMethod targetMethod,
+ protected Invoke createNonInlinedInvoke(ExceptionEdgeAction exceptionEdge, int invokeBci, ValueNode[] invokeArgs, ResolvedJavaMethod targetMethod,
InvokeKind invokeKind, JavaKind resultType, JavaType returnType, JavaTypeProfile profile) {
StampPair returnStamp = graphBuilderConfig.getPlugins().getOverridingStamp(this, returnType, false);
@@ -1714,7 +1719,7 @@
}
MethodCallTargetNode callTarget = graph.add(createMethodCallTarget(invokeKind, targetMethod, invokeArgs, returnStamp, profile));
- Invoke invoke = createNonInlinedInvoke(withExceptionEdge, invokeBci, callTarget, resultType);
+ Invoke invoke = createNonInlinedInvoke(exceptionEdge, invokeBci, callTarget, resultType);
for (InlineInvokePlugin plugin : graphBuilderConfig.getPlugins().getInlineInvokePlugins()) {
plugin.notifyNotInlined(this, targetMethod, invoke);
@@ -1723,11 +1728,11 @@
return invoke;
}
- protected Invoke createNonInlinedInvoke(boolean withExceptionEdge, int invokeBci, CallTargetNode callTarget, JavaKind resultType) {
- if (!withExceptionEdge) {
+ protected Invoke createNonInlinedInvoke(ExceptionEdgeAction exceptionEdge, int invokeBci, CallTargetNode callTarget, JavaKind resultType) {
+ if (exceptionEdge == ExceptionEdgeAction.OMIT) {
return createInvoke(invokeBci, callTarget, resultType);
} else {
- Invoke invoke = createInvokeWithException(invokeBci, callTarget, resultType);
+ Invoke invoke = createInvokeWithException(invokeBci, callTarget, resultType, exceptionEdge);
AbstractBeginNode beginNode = graph.add(KillingBeginNode.create(LocationIdentity.any()));
invoke.setNext(beginNode);
lastInstr = beginNode;
@@ -1736,20 +1741,29 @@
}
/**
- * If the method returns true, the invocation of the given {@link MethodCallTargetNode call
- * target} does not need an exception edge.
+ * Describes what should be done with the exception edge of an invocation. The edge can be
+ * omitted or included. An included edge can handle the exception or transfer execution to the
+ * interpreter for handling (deoptimize).
*/
- protected boolean omitInvokeExceptionEdge(InlineInfo lastInlineInfo) {
+ protected enum ExceptionEdgeAction {
+ OMIT,
+ INCLUDE_AND_HANDLE,
+ INCLUDE_AND_DEOPTIMIZE
+ }
+
+ protected ExceptionEdgeAction getActionForInvokeExceptionEdge(InlineInfo lastInlineInfo) {
if (lastInlineInfo == InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION) {
- return false;
+ return ExceptionEdgeAction.INCLUDE_AND_HANDLE;
} else if (lastInlineInfo == InlineInfo.DO_NOT_INLINE_NO_EXCEPTION) {
- return true;
+ return ExceptionEdgeAction.OMIT;
+ } else if (lastInlineInfo == InlineInfo.DO_NOT_INLINE_DEOPTIMIZE_ON_EXCEPTION) {
+ return ExceptionEdgeAction.INCLUDE_AND_DEOPTIMIZE;
} else if (graphBuilderConfig.getBytecodeExceptionMode() == BytecodeExceptionMode.CheckAll) {
- return false;
+ return ExceptionEdgeAction.INCLUDE_AND_HANDLE;
} else if (graphBuilderConfig.getBytecodeExceptionMode() == BytecodeExceptionMode.ExplicitOnly) {
- return false;
+ return ExceptionEdgeAction.INCLUDE_AND_HANDLE;
} else if (graphBuilderConfig.getBytecodeExceptionMode() == BytecodeExceptionMode.OmitAll) {
- return true;
+ return ExceptionEdgeAction.OMIT;
} else {
assert graphBuilderConfig.getBytecodeExceptionMode() == BytecodeExceptionMode.Profile;
// be conservative if information was not recorded (could result in endless
@@ -1759,12 +1773,12 @@
if (profilingInfo != null) {
TriState exceptionSeen = profilingInfo.getExceptionSeen(bci());
if (exceptionSeen == TriState.FALSE) {
- return true;
+ return ExceptionEdgeAction.OMIT;
}
}
}
}
- return false;
+ return ExceptionEdgeAction.INCLUDE_AND_HANDLE;
}
}
@@ -1887,7 +1901,7 @@
if (newProfile != profile) {
if (newProfile.getTypes().length == 0) {
// All profiled types select the intrinsic so
- // emit a fixed guard instead of a if-then-else.
+ // emit a fixed guard instead of an if-then-else.
lastInstr = append(new FixedGuardNode(compare, TypeCheckedInliningViolated, InvalidateReprofile, false));
return new IntrinsicGuard(currentLastInstr, intrinsicReceiver, mark, null, null);
}
@@ -1966,7 +1980,7 @@
}
lastInstr = intrinsicGuard.nonIntrinsicBranch;
- createNonInlinedInvoke(omitInvokeExceptionEdge(null), bci(), args, targetMethod, invokeKind, resultType, returnType, intrinsicGuard.profile);
+ createNonInlinedInvoke(getActionForInvokeExceptionEdge(null), bci(), args, targetMethod, invokeKind, resultType, returnType, intrinsicGuard.profile);
EndNode nonIntrinsicEnd = append(new EndNode());
AbstractMergeNode mergeNode = graph.add(new MergeNode());
@@ -2303,7 +2317,7 @@
if (calleeBeforeUnwindNode != null) {
ValueNode calleeUnwindValue = parser.getUnwindValue();
assert calleeUnwindValue != null;
- calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci()));
+ calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci(), false));
}
}
}
@@ -2319,7 +2333,7 @@
return invoke;
}
- protected InvokeWithExceptionNode createInvokeWithException(int invokeBci, CallTargetNode callTarget, JavaKind resultType) {
+ protected InvokeWithExceptionNode createInvokeWithException(int invokeBci, CallTargetNode callTarget, JavaKind resultType, ExceptionEdgeAction exceptionEdgeAction) {
if (currentBlock != null && stream.nextBCI() > currentBlock.endBci) {
/*
* Clear non-live locals early so that the exception handler entry gets the cleared
@@ -2328,7 +2342,7 @@
frameState.clearNonLiveLocals(currentBlock, liveness, false);
}
- AbstractBeginNode exceptionEdge = handleException(null, bci());
+ AbstractBeginNode exceptionEdge = handleException(null, bci(), exceptionEdgeAction == ExceptionEdgeAction.INCLUDE_AND_DEOPTIMIZE);
InvokeWithExceptionNode invoke = append(new InvokeWithExceptionNode(callTarget, exceptionEdge, invokeBci));
frameState.pushReturn(resultType, invoke);
invoke.setStateAfter(createFrameState(stream.nextBCI(), invoke));
@@ -2359,20 +2373,43 @@
}
}
+ ValueNode realReturnVal = processReturnValue(returnVal, returnKind);
+
frameState.setRethrowException(false);
frameState.clearStack();
- beforeReturn(returnVal, returnKind);
+ beforeReturn(realReturnVal, returnKind);
if (parent == null) {
- append(new ReturnNode(returnVal));
+ append(new ReturnNode(realReturnVal));
} else {
if (returnDataList == null) {
returnDataList = new ArrayList<>();
}
- returnDataList.add(new ReturnToCallerData(returnVal, lastInstr));
+ returnDataList.add(new ReturnToCallerData(realReturnVal, lastInstr));
lastInstr = null;
}
}
+ private ValueNode processReturnValue(ValueNode value, JavaKind kind) {
+ JavaKind returnKind = method.getSignature().getReturnKind();
+ if (kind != returnKind) {
+ // sub-word integer
+ assert returnKind.isNumericInteger() && returnKind.getStackKind() == JavaKind.Int;
+ IntegerStamp stamp = (IntegerStamp) value.stamp();
+
+ // the bytecode verifier doesn't check that the value is in the correct range
+ if (stamp.lowerBound() < returnKind.getMinValue() || returnKind.getMaxValue() < stamp.upperBound()) {
+ ValueNode narrow = append(genNarrow(value, returnKind.getBitCount()));
+ if (returnKind.isUnsigned()) {
+ return append(genZeroExtend(narrow, 32));
+ } else {
+ return append(genSignExtend(narrow, 32));
+ }
+ }
+ }
+
+ return value;
+ }
+
private void beforeReturn(ValueNode x, JavaKind kind) {
if (graph.method() != null && graph.method().isJavaLangObjectInit()) {
/*
@@ -2794,6 +2831,8 @@
}
private void createExceptionDispatch(ExceptionDispatchBlock block) {
+ lastInstr = finishInstruction(lastInstr, frameState);
+
assert frameState.stackSize() == 1 : frameState;
if (block.handler.isCatchAll()) {
assert block.getSuccessorCount() == 1;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java Wed Nov 08 16:03:35 2017 -0500
@@ -207,7 +207,7 @@
receiver = new ParameterNode(javaIndex, receiverStamp);
}
- locals[javaIndex] = graph.addOrUnique(receiver);
+ locals[javaIndex] = graph.addOrUniqueWithInputs(receiver);
javaIndex = 1;
index = 1;
}
@@ -241,7 +241,7 @@
param = new ParameterNode(index, stamp);
}
- locals[javaIndex] = graph.addOrUnique(param);
+ locals[javaIndex] = graph.addOrUniqueWithInputs(param);
javaIndex++;
if (kind.needsTwoSlots()) {
locals[javaIndex] = TWO_SLOT_MARKER;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/ConditionalElimination02.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/ConditionalElimination02.java Wed Nov 08 16:03:35 2017 -0500
@@ -29,6 +29,9 @@
import org.junit.Test;
import org.graalvm.compiler.jtt.JTTTest;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
public class ConditionalElimination02 extends JTTTest {
@@ -59,6 +62,14 @@
return -1;
}
+ /**
+ * These tests assume all code paths are reachable so disable profile based dead code removal.
+ */
+ @Override
+ protected HighTierContext getDefaultHighTierContext() {
+ return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+ }
+
@Test
public void run0() throws Throwable {
runTest(EnumSet.of(DeoptimizationReason.NullCheckException), "test", new A(5), false, false);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/Fold_Double04.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+package org.graalvm.compiler.jtt.optimize;
+
+import org.junit.Test;
+
+import org.graalvm.compiler.jtt.JTTTest;
+
+/*
+ * Tests constant folding of double operations.
+ */
+public class Fold_Double04 extends JTTTest {
+
+ // Contrived check whether both arguments are the same kind of zero
+ public static boolean test(double x, double y) {
+ if (x == 0) {
+ if (1 / x == Double.NEGATIVE_INFINITY) {
+ return 1 / y == Double.NEGATIVE_INFINITY;
+ } else {
+ return 1 / y == Double.POSITIVE_INFINITY;
+ }
+ }
+ return false;
+ }
+
+ @Test
+ public void run0() throws Throwable {
+ runTest("test", -0d, -0d);
+ }
+
+ @Test
+ public void run1() throws Throwable {
+ runTest("test", -0d, 0d);
+ }
+
+ @Test
+ public void run2() throws Throwable {
+ runTest("test", 0d, -0d);
+ }
+
+ @Test
+ public void run3() throws Throwable {
+ runTest("test", 0d, 0d);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/Fold_Float03.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+package org.graalvm.compiler.jtt.optimize;
+
+import org.junit.Test;
+
+import org.graalvm.compiler.jtt.JTTTest;
+
+/*
+ * Tests constant folding of float operations.
+ */
+public class Fold_Float03 extends JTTTest {
+
+ // Contrived check whether both arguments are the same kind of zero
+ public static boolean test(float x, float y) {
+ if (x == 0) {
+ if (1 / x == Float.NEGATIVE_INFINITY) {
+ return 1 / y == Float.NEGATIVE_INFINITY;
+ } else {
+ return 1 / y == Float.POSITIVE_INFINITY;
+ }
+ }
+ return false;
+ }
+
+ @Test
+ public void run0() throws Throwable {
+ runTest("test", -0f, -0f);
+ }
+
+ @Test
+ public void run1() throws Throwable {
+ runTest("test", -0f, 0f);
+ }
+
+ @Test
+ public void run2() throws Throwable {
+ runTest("test", 0f, -0f);
+ }
+
+ @Test
+ public void run3() throws Throwable {
+ runTest("test", 0f, 0f);
+ }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayEqualsOp.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayEqualsOp.java Wed Nov 08 16:03:35 2017 -0500
@@ -37,6 +37,7 @@
import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.Opcode;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
@@ -132,12 +133,19 @@
masm.leaq(array2, new AMD64Address(asRegister(array2Value), arrayBaseOffset));
// Get array length in bytes.
- masm.imull(length, asRegister(lengthValue), arrayIndexScale);
+ masm.movl(length, asRegister(lengthValue));
+
+ if (arrayIndexScale > 1) {
+ masm.shll(length, NumUtil.log2Ceil(arrayIndexScale)); // scale length
+ }
+
masm.movl(result, length); // copy
if (supportsAVX2(crb.target)) {
emitAVXCompare(crb, masm, result, array1, array2, length, trueLabel, falseLabel);
} else if (supportsSSE41(crb.target)) {
+ // this code is used for AVX as well because our backend correctly ensures that
+ // VEX-prefixed instructions are emitted if AVX is supported
emitSSE41Compare(crb, masm, result, array1, array2, length, trueLabel, falseLabel);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ControlFlow.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ControlFlow.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,21 +22,21 @@
*/
package org.graalvm.compiler.lir.amd64;
+import static jdk.vm.ci.code.ValueUtil.asRegister;
+import static jdk.vm.ci.code.ValueUtil.isRegister;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.CONST;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
-import static jdk.vm.ci.code.ValueUtil.asRegister;
-import static jdk.vm.ci.code.ValueUtil.isRegister;
import org.graalvm.compiler.asm.Label;
-import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.asm.amd64.AMD64Address;
import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
import org.graalvm.compiler.code.CompilationResult.JumpTable;
+import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.core.common.calc.Condition;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.lir.LIRInstructionClass;
@@ -312,6 +312,42 @@
}
}
+ @Opcode("SETcc")
+ public static final class CondSetOp extends AMD64LIRInstruction {
+ public static final LIRInstructionClass<CondSetOp> TYPE = LIRInstructionClass.create(CondSetOp.class);
+ @Def({REG, HINT}) protected Value result;
+ private final ConditionFlag condition;
+
+ public CondSetOp(Variable result, Condition condition) {
+ super(TYPE);
+ this.result = result;
+ this.condition = intCond(condition);
+ }
+
+ @Override
+ public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+ setcc(masm, result, condition);
+ }
+ }
+
+ @Opcode("SETcc")
+ public static final class FloatCondSetOp extends AMD64LIRInstruction {
+ public static final LIRInstructionClass<FloatCondSetOp> TYPE = LIRInstructionClass.create(FloatCondSetOp.class);
+ @Def({REG, HINT}) protected Value result;
+ private final ConditionFlag condition;
+
+ public FloatCondSetOp(Variable result, Condition condition) {
+ super(TYPE);
+ this.result = result;
+ this.condition = floatCond(condition);
+ }
+
+ @Override
+ public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+ setcc(masm, result, condition);
+ }
+ }
+
@Opcode("CMOVE")
public static final class CondMoveOp extends AMD64LIRInstruction {
public static final LIRInstructionClass<CondMoveOp> TYPE = LIRInstructionClass.create(CondMoveOp.class);
@@ -418,6 +454,21 @@
}
}
+ private static void setcc(AMD64MacroAssembler masm, Value result, ConditionFlag cond) {
+ switch ((AMD64Kind) result.getPlatformKind()) {
+ case BYTE:
+ case WORD:
+ case DWORD:
+ masm.setl(cond, asRegister(result));
+ break;
+ case QWORD:
+ masm.setq(cond, asRegister(result));
+ break;
+ default:
+ throw GraalError.shouldNotReachHere();
+ }
+ }
+
private static ConditionFlag intCond(Condition cond) {
switch (cond) {
case EQ:
@@ -464,6 +515,10 @@
}
}
+ public static boolean trueOnUnordered(Condition condition) {
+ return trueOnUnordered(floatCond(condition));
+ }
+
private static boolean trueOnUnordered(ConditionFlag condition) {
switch (condition) {
case AboveEqual:
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,8 +22,11 @@
*/
package org.graalvm.compiler.lir.amd64;
+import static org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag.Equal;
+import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.UNINITIALIZED;
@@ -35,12 +38,16 @@
import static jdk.vm.ci.code.ValueUtil.isRegister;
import static jdk.vm.ci.code.ValueUtil.isStackSlot;
+import org.graalvm.compiler.asm.Label;
+import org.graalvm.compiler.core.common.CompressEncoding;
+import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.asm.amd64.AMD64Address;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize;
import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
+import org.graalvm.compiler.core.common.spi.LIRKindTool;
import org.graalvm.compiler.core.common.type.DataPointerConstant;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.lir.LIRFrameState;
@@ -740,4 +747,110 @@
throw GraalError.shouldNotReachHere("Unknown result Kind: " + result.getPlatformKind());
}
}
+
+ public abstract static class Pointer extends AMD64LIRInstruction {
+ protected final LIRKindTool lirKindTool;
+ protected final CompressEncoding encoding;
+ protected final boolean nonNull;
+
+ @Def({REG, HINT}) private AllocatableValue result;
+ @Use({REG}) private AllocatableValue input;
+ @Alive({REG, ILLEGAL}) private AllocatableValue baseRegister;
+
+ protected Pointer(LIRInstructionClass<? extends Pointer> type, AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull,
+ LIRKindTool lirKindTool) {
+ super(type);
+ this.result = result;
+ this.input = input;
+ this.baseRegister = baseRegister;
+ this.encoding = encoding;
+ this.nonNull = nonNull;
+ this.lirKindTool = lirKindTool;
+ }
+
+ protected boolean hasBase(CompilationResultBuilder crb) {
+ return GeneratePIC.getValue(crb.getOptions()) || encoding.hasBase();
+ }
+
+ protected final Register getResultRegister() {
+ return asRegister(result);
+ }
+
+ protected final Register getBaseRegister() {
+ return asRegister(baseRegister);
+ }
+
+ protected final int getShift() {
+ return encoding.getShift();
+ }
+
+ protected final void move(LIRKind kind, CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+ AMD64Move.move((AMD64Kind) kind.getPlatformKind(), crb, masm, result, input);
+ }
+ }
+
+ public static final class CompressPointer extends Pointer {
+ public static final LIRInstructionClass<CompressPointer> TYPE = LIRInstructionClass.create(CompressPointer.class);
+
+ public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull, LIRKindTool lirKindTool) {
+ super(TYPE, result, input, baseRegister, encoding, nonNull, lirKindTool);
+ }
+
+ @Override
+ public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+ move(lirKindTool.getObjectKind(), crb, masm);
+
+ Register resReg = getResultRegister();
+ if (hasBase(crb)) {
+ Register baseReg = getBaseRegister();
+ if (!nonNull) {
+ masm.testq(resReg, resReg);
+ masm.cmovq(Equal, resReg, baseReg);
+ }
+ masm.subq(resReg, baseReg);
+ }
+
+ int shift = getShift();
+ if (shift != 0) {
+ masm.shrq(resReg, shift);
+ }
+ }
+ }
+
+ public static final class UncompressPointer extends Pointer {
+ public static final LIRInstructionClass<UncompressPointer> TYPE = LIRInstructionClass.create(UncompressPointer.class);
+
+ public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull, LIRKindTool lirKindTool) {
+ super(TYPE, result, input, baseRegister, encoding, nonNull, lirKindTool);
+ }
+
+ @Override
+ public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+ move(lirKindTool.getNarrowOopKind(), crb, masm);
+
+ Register resReg = getResultRegister();
+ int shift = getShift();
+ if (shift != 0) {
+ masm.shlq(resReg, shift);
+ }
+
+ if (hasBase(crb)) {
+ Register baseReg = getBaseRegister();
+ if (nonNull) {
+ masm.addq(resReg, baseReg);
+ return;
+ }
+
+ if (shift == 0) {
+ // if encoding.shift != 0, the flags are already set by the shlq
+ masm.testq(resReg, resReg);
+ }
+
+ Label done = new Label();
+ masm.jccb(Equal, done);
+ masm.addq(resReg, baseReg);
+ masm.bind(done);
+ }
+ }
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCLoadConstantTableBaseOp.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCLoadConstantTableBaseOp.java Wed Nov 08 16:03:35 2017 -0500
@@ -55,8 +55,8 @@
* this case absolute addressing (without using the base pointer is used). See also:
* CodeInstaller::pd_patch_DataSectionReference
*
- * @see SPARCMove#loadFromConstantTable(CompilationResultBuilder, SPARCMacroAssembler, int,
- * Register, jdk.vm.ci.meta.Constant, Register, SPARCDelayedControlTransfer)
+ * @see SPARCMove#loadFromConstantTable(CompilationResultBuilder, SPARCMacroAssembler, Register,
+ * jdk.vm.ci.meta.Constant, Register, SPARCDelayedControlTransfer)
*/
public class SPARCLoadConstantTableBaseOp extends SPARCLIRInstruction {
public static final LIRInstructionClass<SPARCLoadConstantTableBaseOp> TYPE = LIRInstructionClass.create(SPARCLoadConstantTableBaseOp.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCMove.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCMove.java Wed Nov 08 16:03:35 2017 -0500
@@ -53,6 +53,7 @@
import org.graalvm.compiler.asm.sparc.SPARCAssembler;
import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler;
import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler.ScratchRegister;
+import org.graalvm.compiler.code.DataSection.Data;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.type.DataPointerConstant;
import org.graalvm.compiler.debug.GraalError;
@@ -116,11 +117,11 @@
public static final LIRInstructionClass<LoadConstantFromTable> TYPE = LIRInstructionClass.create(LoadConstantFromTable.class);
public static final SizeEstimate SIZE = SizeEstimate.create(1, 8);
- private Constant constant;
+ private JavaConstant constant;
@Def({REG, STACK}) AllocatableValue result;
@Use({REG}) private AllocatableValue constantTableBase;
- public LoadConstantFromTable(Constant constant, AllocatableValue constantTableBase, AllocatableValue result) {
+ public LoadConstantFromTable(JavaConstant constant, AllocatableValue constantTableBase, AllocatableValue result) {
super(TYPE, SIZE);
this.constant = constant;
this.result = result;
@@ -134,11 +135,11 @@
Register baseRegister = asRegister(constantTableBase);
if (isRegister(result)) {
Register resultRegister = asRegister(result);
- loadFromConstantTable(crb, masm, byteCount, baseRegister, constant, resultRegister, getDelayedControlTransfer());
+ loadFromConstantTable(crb, masm, baseRegister, constant, resultRegister, getDelayedControlTransfer());
} else if (isStackSlot(result)) {
try (ScratchRegister scratch = masm.getScratchRegister()) {
Register scratchRegister = scratch.getRegister();
- loadFromConstantTable(crb, masm, byteCount, baseRegister, constant, scratchRegister, getDelayedControlTransfer());
+ loadFromConstantTable(crb, masm, baseRegister, constant, scratchRegister, getDelayedControlTransfer());
StackSlot slot = asStackSlot(result);
reg2stack(crb, masm, slot, scratchRegister.asValue(), getDelayedControlTransfer());
}
@@ -642,7 +643,6 @@
boolean hasVIS1 = cpuFeatures.contains(CPUFeature.VIS1);
boolean hasVIS3 = cpuFeatures.contains(CPUFeature.VIS3);
Register resultRegister = asRegister(result);
- int byteCount = result.getPlatformKind().getSizeInBytes();
switch (input.getJavaKind().getStackKind()) {
case Int:
if (input.isDefaultForKind()) {
@@ -655,7 +655,7 @@
if (constantTableBase.equals(g0)) {
throw GraalError.shouldNotReachHere();
} else {
- loadFromConstantTable(crb, masm, byteCount, constantTableBase, input, resultRegister, delaySlotLir);
+ loadFromConstantTable(crb, masm, constantTableBase, input, resultRegister, delaySlotLir);
}
}
break;
@@ -667,7 +667,7 @@
delaySlotLir.emitControlTransfer(crb, masm);
masm.or(g0, (int) input.asLong(), resultRegister);
} else {
- loadFromConstantTable(crb, masm, byteCount, constantTableBase, input, resultRegister, delaySlotLir);
+ loadFromConstantTable(crb, masm, constantTableBase, input, resultRegister, delaySlotLir);
}
break;
case Float: {
@@ -683,7 +683,7 @@
masm.movwtos(scratch, resultRegister);
} else {
// First load the address into the scratch register
- loadFromConstantTable(crb, masm, byteCount, constantTableBase, input, resultRegister, delaySlotLir);
+ loadFromConstantTable(crb, masm, constantTableBase, input, resultRegister, delaySlotLir);
}
}
break;
@@ -700,7 +700,7 @@
delaySlotLir.emitControlTransfer(crb, masm);
masm.movxtod(scratch, resultRegister);
} else {
- loadFromConstantTable(crb, masm, byteCount, constantTableBase, input, resultRegister, delaySlotLir);
+ loadFromConstantTable(crb, masm, constantTableBase, input, resultRegister, delaySlotLir);
}
}
break;
@@ -710,7 +710,7 @@
delaySlotLir.emitControlTransfer(crb, masm);
masm.clr(resultRegister);
} else {
- loadFromConstantTable(crb, masm, byteCount, constantTableBase, input, resultRegister, delaySlotLir);
+ loadFromConstantTable(crb, masm, constantTableBase, input, resultRegister, delaySlotLir);
}
break;
default:
@@ -768,25 +768,30 @@
* patterns used for small constant sections (<8k) and large constant sections (>=8k). The
* generated patterns by this method must be understood by
* CodeInstaller::pd_patch_DataSectionReference (jvmciCodeInstaller_sparc.cpp).
+ *
+ * @return the number of bytes loaded from the constant table
*/
- public static void loadFromConstantTable(CompilationResultBuilder crb, SPARCMacroAssembler masm, int byteCount, Register constantTableBase, Constant input, Register dest,
+ public static int loadFromConstantTable(CompilationResultBuilder crb, SPARCMacroAssembler masm, Register constantTableBase, Constant input, Register dest,
SPARCDelayedControlTransfer delaySlotInstruction) {
SPARCAddress address;
ScratchRegister scratch = null;
try {
+ Data data = crb.createDataItem(input);
+ int size = data.getSize();
if (masm.isImmediateConstantLoad()) {
address = new SPARCAddress(constantTableBase, 0);
// Make delayed only, when using immediate constant load.
delaySlotInstruction.emitControlTransfer(crb, masm);
- crb.recordDataReferenceInCode(input, byteCount);
+ crb.recordDataReferenceInCode(data, size);
} else {
scratch = masm.getScratchRegister();
Register sr = scratch.getRegister();
- crb.recordDataReferenceInCode(input, byteCount);
+ crb.recordDataReferenceInCode(data, size);
masm.sethix(0, sr, true);
address = new SPARCAddress(sr, 0);
}
- masm.ld(address, dest, byteCount, false);
+ masm.ld(address, dest, size, false);
+ return size;
} finally {
if (scratch != null) {
scratch.close();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRValueUtil.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRValueUtil.java Wed Nov 08 16:03:35 2017 -0500
@@ -69,6 +69,16 @@
return asConstantValue(value).getJavaConstant();
}
+ public static boolean isIntConstant(Value value, long expected) {
+ if (isJavaConstant(value)) {
+ JavaConstant javaConstant = asJavaConstant(value);
+ if (javaConstant != null && javaConstant.getJavaKind().isNumericInteger()) {
+ return javaConstant.asLong() == expected;
+ }
+ }
+ return false;
+ }
+
public static boolean isStackSlotValue(Value value) {
assert value != null;
return value instanceof StackSlot || value instanceof VirtualStackSlot;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/RedundantMoveElimination.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/RedundantMoveElimination.java Wed Nov 08 16:03:35 2017 -0500
@@ -30,6 +30,7 @@
import java.util.Collections;
import java.util.EnumSet;
+import jdk.vm.ci.code.RegisterConfig;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
import org.graalvm.compiler.debug.CounterKey;
@@ -138,8 +139,8 @@
private void doOptimize(LIR lir) {
DebugContext debug = lir.getDebug();
try (Indent indent = debug.logAndIndent("eliminate redundant moves")) {
-
- callerSaveRegs = frameMap.getRegisterConfig().getCallerSaveRegisters();
+ RegisterConfig registerConfig = frameMap.getRegisterConfig();
+ callerSaveRegs = registerConfig.getCallerSaveRegisters();
initBlockData(lir);
@@ -147,7 +148,7 @@
// Unallocatable registers should never be optimized.
eligibleRegs = new int[numRegs];
Arrays.fill(eligibleRegs, -1);
- for (Register reg : frameMap.getRegisterConfig().getAllocatableRegisters()) {
+ for (Register reg : registerConfig.getAllocatableRegisters()) {
if (reg.number < numRegs) {
eligibleRegs[reg.number] = reg.number;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/SaveCalleeSaveRegisters.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/SaveCalleeSaveRegisters.java Wed Nov 08 16:03:35 2017 -0500
@@ -31,7 +31,6 @@
import org.graalvm.compiler.lir.LIRInstruction;
import org.graalvm.compiler.lir.StandardOp;
import org.graalvm.compiler.lir.Variable;
-import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
import org.graalvm.compiler.lir.gen.LIRGenerationResult;
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
import org.graalvm.compiler.lir.phases.PreAllocationOptimizationPhase;
@@ -48,8 +47,7 @@
@Override
protected void run(TargetDescription target, LIRGenerationResult lirGenRes, PreAllocationOptimizationContext context) {
- FrameMapBuilder frameMapBuilder = lirGenRes.getFrameMapBuilder();
- RegisterArray calleeSaveRegisters = frameMapBuilder.getCodeCache().getRegisterConfig().getCalleeSaveRegisters();
+ RegisterArray calleeSaveRegisters = lirGenRes.getRegisterConfig().getCalleeSaveRegisters();
if (calleeSaveRegisters == null || calleeSaveRegisters.size() == 0) {
return;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilder.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilder.java Wed Nov 08 16:03:35 2017 -0500
@@ -80,10 +80,10 @@
*/
public class CompilationResultBuilder {
- // @formatter:off
- @Option(help = "Include the LIR as comments with the final assembly.", type = OptionType.Debug)
- public static final OptionKey<Boolean> PrintLIRWithAssembly = new OptionKey<>(false);
- // @formatter:on
+ public static class Options {
+ @Option(help = "Include the LIR as comments with the final assembly.", type = OptionType.Debug) //
+ public static final OptionKey<Boolean> PrintLIRWithAssembly = new OptionKey<>(false);
+ }
private static class ExceptionInfo {
@@ -295,13 +295,24 @@
public AbstractAddress recordDataReferenceInCode(Constant constant, int alignment) {
assert constant != null;
debug.log("Constant reference in code: pos = %d, data = %s", asm.position(), constant);
+ Data data = createDataItem(constant);
+ data.updateAlignment(alignment);
+ return recordDataSectionReference(data);
+ }
+
+ public AbstractAddress recordDataReferenceInCode(Data data, int alignment) {
+ assert data != null;
+ data.updateAlignment(alignment);
+ return recordDataSectionReference(data);
+ }
+
+ public Data createDataItem(Constant constant) {
Data data = dataCache.get(constant);
if (data == null) {
data = dataBuilder.createDataItem(constant);
dataCache.put(constant, data);
}
- data.updateAlignment(alignment);
- return recordDataSectionReference(data);
+ return data;
}
public AbstractAddress recordDataReferenceInCode(byte[] data, int alignment) {
@@ -472,7 +483,7 @@
if (block == null) {
return;
}
- boolean emitComment = debug.isDumpEnabled(DebugContext.BASIC_LEVEL) || PrintLIRWithAssembly.getValue(getOptions());
+ boolean emitComment = debug.isDumpEnabled(DebugContext.BASIC_LEVEL) || Options.PrintLIRWithAssembly.getValue(getOptions());
if (emitComment) {
blockComment(String.format("block B%d %s", block.getId(), block.getLoop()));
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/ArithmeticLIRGenerator.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/ArithmeticLIRGenerator.java Wed Nov 08 16:03:35 2017 -0500
@@ -50,8 +50,19 @@
protected abstract Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags);
+ protected abstract Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags);
+
@Override
public final Variable emitAdd(Value aVal, Value bVal, boolean setFlags) {
+ return emitAddOrSub(aVal, bVal, setFlags, true);
+ }
+
+ @Override
+ public final Variable emitSub(Value aVal, Value bVal, boolean setFlags) {
+ return emitAddOrSub(aVal, bVal, setFlags, false);
+ }
+
+ private Variable emitAddOrSub(Value aVal, Value bVal, boolean setFlags, boolean isAdd) {
LIRKind resultKind;
Value a = aVal;
Value b = bVal;
@@ -90,47 +101,7 @@
resultKind = LIRKind.combine(a, b);
}
- return emitAdd(resultKind, a, b, setFlags);
+ return isAdd ? emitAdd(resultKind, a, b, setFlags) : emitSub(resultKind, a, b, setFlags);
}
- protected abstract Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags);
-
- @Override
- public final Variable emitSub(Value aVal, Value bVal, boolean setFlags) {
- LIRKind resultKind;
- Value a = aVal;
- Value b = bVal;
-
- if (isNumericInteger(a.getPlatformKind())) {
- LIRKind aKind = a.getValueKind(LIRKind.class);
- LIRKind bKind = b.getValueKind(LIRKind.class);
- assert a.getPlatformKind() == b.getPlatformKind();
-
- if (aKind.isUnknownReference()) {
- resultKind = aKind;
- } else if (bKind.isUnknownReference()) {
- resultKind = bKind;
- }
-
- if (aKind.isValue() && bKind.isValue()) {
- resultKind = aKind;
- } else if (bKind.isValue()) {
- if (aKind.isDerivedReference()) {
- resultKind = aKind;
- } else {
- AllocatableValue allocatable = getLIRGen().asAllocatable(a);
- resultKind = aKind.makeDerivedReference(allocatable);
- a = allocatable;
- }
- } else if (aKind.isDerivedReference() && bKind.isDerivedReference() && aKind.getDerivedReferenceBase().equals(bKind.getDerivedReferenceBase())) {
- resultKind = LIRKind.value(a.getPlatformKind());
- } else {
- resultKind = aKind.makeUnknownReference();
- }
- } else {
- resultKind = LIRKind.combine(a, b);
- }
-
- return emitSub(resultKind, a, b, setFlags);
- }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerationResult.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerationResult.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,6 +22,7 @@
*/
package org.graalvm.compiler.lir.gen;
+import jdk.vm.ci.code.RegisterConfig;
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.core.common.CompilationIdentifier.Verbosity;
import org.graalvm.compiler.debug.DebugContext;
@@ -123,6 +124,10 @@
return frameMap;
}
+ public final RegisterConfig getRegisterConfig() {
+ return frameMapBuilder.getRegisterConfig();
+ }
+
public LIR getLIR() {
return lir;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerator.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerator.java Wed Nov 08 16:03:35 2017 -0500
@@ -34,6 +34,7 @@
import java.util.ArrayList;
import java.util.List;
+import jdk.vm.ci.code.RegisterConfig;
import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.calc.Condition;
@@ -201,8 +202,13 @@
}
@Override
+ public RegisterConfig getRegisterConfig() {
+ return res.getRegisterConfig();
+ }
+
+ @Override
public RegisterAttributes attributes(Register register) {
- return res.getFrameMapBuilder().getRegisterConfig().getAttributesMap()[register.number];
+ return getRegisterConfig().getAttributesMap()[register.number];
}
@Override
@@ -228,7 +234,7 @@
if (moveFactory.canInlineConstant(constant)) {
return new ConstantValue(toRegisterKind(kind), constant);
} else {
- return emitLoadConstant(kind, constant);
+ return emitLoadConstant(toRegisterKind(kind), constant);
}
}
@@ -289,7 +295,7 @@
*/
@Override
public AllocatableValue resultOperandFor(JavaKind javaKind, ValueKind<?> valueKind) {
- Register reg = res.getFrameMapBuilder().getRegisterConfig().getReturnRegister(javaKind);
+ Register reg = getRegisterConfig().getReturnRegister(javaKind);
assert target().arch.canStoreValue(reg.getRegisterCategory(), valueKind.getPlatformKind()) : reg.getRegisterCategory() + " " + valueKind.getPlatformKind();
return reg.asValue(valueKind);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,6 +22,7 @@
*/
package org.graalvm.compiler.lir.gen;
+import jdk.vm.ci.code.RegisterConfig;
import org.graalvm.compiler.core.common.CompressEncoding;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.calc.Condition;
@@ -109,6 +110,8 @@
LIRGenerationResult getResult();
+ RegisterConfig getRegisterConfig();
+
boolean hasBlockEnd(AbstractBlockBase<?> block);
MoveFactory getMoveFactory();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.test/src/org/graalvm/compiler/loop/test/LoopPartialUnrollTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.test/src/org/graalvm/compiler/loop/test/LoopPartialUnrollTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -214,7 +214,7 @@
}
};
ResolvedJavaMethod method = getResolvedJavaMethod(name);
- OptionValues options = new OptionValues(getInitialOptions(), DefaultLoopPolicies.UnrollMaxIterations, 2);
+ OptionValues options = new OptionValues(getInitialOptions(), DefaultLoopPolicies.Options.UnrollMaxIterations, 2);
StructuredGraph graph = parse(builder(method, StructuredGraph.AllowAssumptions.YES, id, options), getEagerGraphBuilderSuite());
try (DebugContext.Scope buildScope = graph.getDebug().scope(name, method, graph)) {
MidTierContext context = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, null);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/CountedLoopInfo.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/CountedLoopInfo.java Wed Nov 08 16:03:35 2017 -0500
@@ -83,7 +83,11 @@
range = add(graph, range, oneDirection);
}
// round-away-from-zero divison: (range + stride -/+ 1) / stride
- ValueNode denominator = add(graph, sub(graph, range, oneDirection), iv.strideNode());
+ ValueNode denominator = range;
+ if (!oneDirection.stamp().equals(iv.strideNode().stamp())) {
+ ValueNode subedRanged = sub(graph, range, oneDirection);
+ denominator = add(graph, subedRanged, iv.strideNode());
+ }
ValueNode div = divBefore(graph, loop.entryPoint(), denominator, iv.strideNode());
if (assumePositive) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DefaultLoopPolicies.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DefaultLoopPolicies.java Wed Nov 08 16:03:35 2017 -0500
@@ -55,16 +55,19 @@
import jdk.vm.ci.meta.MetaAccessProvider;
public class DefaultLoopPolicies implements LoopPolicies {
- @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> LoopUnswitchMaxIncrease = new OptionKey<>(500);
- @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> LoopUnswitchTrivial = new OptionKey<>(10);
- @Option(help = "", type = OptionType.Expert) public static final OptionKey<Double> LoopUnswitchFrequencyBoost = new OptionKey<>(10.0);
+
+ public static class Options {
+ @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> LoopUnswitchMaxIncrease = new OptionKey<>(500);
+ @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> LoopUnswitchTrivial = new OptionKey<>(10);
+ @Option(help = "", type = OptionType.Expert) public static final OptionKey<Double> LoopUnswitchFrequencyBoost = new OptionKey<>(10.0);
- @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> FullUnrollMaxNodes = new OptionKey<>(300);
- @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> FullUnrollMaxIterations = new OptionKey<>(600);
- @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> ExactFullUnrollMaxNodes = new OptionKey<>(1200);
- @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> ExactPartialUnrollMaxNodes = new OptionKey<>(200);
+ @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> FullUnrollMaxNodes = new OptionKey<>(300);
+ @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> FullUnrollMaxIterations = new OptionKey<>(600);
+ @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> ExactFullUnrollMaxNodes = new OptionKey<>(1200);
+ @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> ExactPartialUnrollMaxNodes = new OptionKey<>(200);
- @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> UnrollMaxIterations = new OptionKey<>(16);
+ @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> UnrollMaxIterations = new OptionKey<>(16);
+ }
@Override
public boolean shouldPeel(LoopEx loop, ControlFlowGraph cfg, MetaAccessProvider metaAccess) {
@@ -87,10 +90,10 @@
OptionValues options = loop.entryPoint().getOptions();
CountedLoopInfo counted = loop.counted();
long maxTrips = counted.constantMaxTripCount();
- int maxNodes = (counted.isExactTripCount() && counted.isConstantExactTripCount()) ? ExactFullUnrollMaxNodes.getValue(options) : FullUnrollMaxNodes.getValue(options);
+ int maxNodes = (counted.isExactTripCount() && counted.isConstantExactTripCount()) ? Options.ExactFullUnrollMaxNodes.getValue(options) : Options.FullUnrollMaxNodes.getValue(options);
maxNodes = Math.min(maxNodes, Math.max(0, MaximumDesiredSize.getValue(options) - loop.loopBegin().graph().getNodeCount()));
int size = Math.max(1, loop.size() - 1 - loop.loopBegin().phis().count());
- if (maxTrips <= FullUnrollMaxIterations.getValue(options) && size * (maxTrips - 1) <= maxNodes) {
+ if (maxTrips <= Options.FullUnrollMaxIterations.getValue(options) && size * (maxTrips - 1) <= maxNodes) {
// check whether we're allowed to unroll this loop
return loop.canDuplicateLoop();
} else {
@@ -106,7 +109,7 @@
return false;
}
OptionValues options = loop.entryPoint().getOptions();
- int maxNodes = ExactPartialUnrollMaxNodes.getValue(options);
+ int maxNodes = Options.ExactPartialUnrollMaxNodes.getValue(options);
maxNodes = Math.min(maxNodes, Math.max(0, MaximumDesiredSize.getValue(options) - loop.loopBegin().graph().getNodeCount()));
int size = Math.max(1, loop.size() - 1 - loop.loopBegin().phis().count());
int unrollFactor = loopBegin.getUnrollFactor();
@@ -118,7 +121,7 @@
}
loopBegin.setLoopOrigFrequency(loopFrequency);
}
- int maxUnroll = UnrollMaxIterations.getValue(options);
+ int maxUnroll = Options.UnrollMaxIterations.getValue(options);
// Now correct size for the next unroll. UnrollMaxIterations == 1 means perform the
// pre/main/post transformation but don't actually unroll the main loop.
size += size;
@@ -190,9 +193,9 @@
CountingClosure stateNodesCount = new CountingClosure();
double loopFrequency = loop.loopBegin().loopFrequency();
OptionValues options = loop.loopBegin().getOptions();
- int maxDiff = LoopUnswitchTrivial.getValue(options) + (int) (LoopUnswitchFrequencyBoost.getValue(options) * (loopFrequency - 1.0 + phis));
+ int maxDiff = Options.LoopUnswitchTrivial.getValue(options) + (int) (Options.LoopUnswitchFrequencyBoost.getValue(options) * (loopFrequency - 1.0 + phis));
- maxDiff = Math.min(maxDiff, LoopUnswitchMaxIncrease.getValue(options));
+ maxDiff = Math.min(maxDiff, Options.LoopUnswitchMaxIncrease.getValue(options));
int remainingGraphSpace = MaximumDesiredSize.getValue(options) - graph.getNodeCount();
maxDiff = Math.min(maxDiff, remainingGraphSpace);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo/src/org/graalvm/compiler/nodeinfo/NodeCycles.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo/src/org/graalvm/compiler/nodeinfo/NodeCycles.java Wed Nov 08 16:03:35 2017 -0500
@@ -68,6 +68,10 @@
this.value = value;
}
+ public boolean isValueKnown() {
+ return this != NodeCycles.CYCLES_UNKNOWN && this != NodeCycles.CYCLES_UNSET;
+ }
+
public static final int IGNORE_CYCLES_CONTRACT_FACTOR = 0xFFFF;
public static NodeCycles compute(NodeCycles base, int opCount) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/IntegerStampTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/IntegerStampTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -552,4 +552,21 @@
return result.longValue();
}
}
+
+ @Test
+ public void testDiv() {
+ testDiv(32, Integer.MIN_VALUE, Integer.MAX_VALUE);
+ testDiv(64, Long.MIN_VALUE, Long.MAX_VALUE);
+ }
+
+ private static void testDiv(int bits, long min, long max) {
+ BinaryOp<?> div = IntegerStamp.OPS.getDiv();
+ assertEquals(IntegerStamp.create(bits, -50, 50), div.foldStamp(IntegerStamp.create(bits, -100, 100), IntegerStamp.create(bits, 2, 5)));
+ assertEquals(IntegerStamp.create(bits, 20, 500), div.foldStamp(IntegerStamp.create(bits, 100, 1000), IntegerStamp.create(bits, 2, 5)));
+ assertEquals(IntegerStamp.create(bits, -500, -20), div.foldStamp(IntegerStamp.create(bits, -1000, -100), IntegerStamp.create(bits, 2, 5)));
+ assertEquals(IntegerStamp.create(bits, min, max), div.foldStamp(IntegerStamp.create(bits, min, max), IntegerStamp.create(bits, 1, max)));
+ assertEquals(IntegerStamp.create(bits, -100, 100), div.foldStamp(IntegerStamp.create(bits, -100, 100), IntegerStamp.create(bits, 1, max)));
+ assertEquals(IntegerStamp.create(bits, 0, 1000), div.foldStamp(IntegerStamp.create(bits, 100, 1000), IntegerStamp.create(bits, 1, max)));
+ assertEquals(IntegerStamp.create(bits, -1000, 0), div.foldStamp(IntegerStamp.create(bits, -1000, -100), IntegerStamp.create(bits, 1, max)));
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/PrimitiveStampBoundaryTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ * 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 org.graalvm.compiler.nodes.test;
+
+import java.util.EnumSet;
+import java.util.HashSet;
+
+import org.graalvm.compiler.core.common.calc.FloatConvert;
+import org.graalvm.compiler.core.common.calc.FloatConvertCategory;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp;
+import org.graalvm.compiler.core.common.type.FloatStamp;
+import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.core.common.type.PrimitiveStamp;
+import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.test.GraalTest;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+
+/**
+ * Exercise the various stamp folding operations by generating ranges from a set of boundary values
+ * and then ensuring that the values that produced those ranges are in the resulting stamp.
+ */
+public class PrimitiveStampBoundaryTest extends GraalTest {
+
+ static long[] longBoundaryValues = {Long.MIN_VALUE, Long.MIN_VALUE + 1, Integer.MIN_VALUE, Integer.MIN_VALUE + 1, -1, 0, 1, Integer.MAX_VALUE - 1, Integer.MAX_VALUE, Long.MAX_VALUE - 1,
+ Long.MAX_VALUE};
+
+ static int[] shiftBoundaryValues = {-128, -1, 0, 1, 4, 8, 16, 31, 63, 128};
+
+ static HashSet<IntegerStamp> shiftStamps;
+ static HashSet<PrimitiveStamp> integerTestStamps;
+ static HashSet<PrimitiveStamp> floatTestStamps;
+
+ static {
+ shiftStamps = new HashSet<>();
+ for (long v1 : shiftBoundaryValues) {
+ for (long v2 : shiftBoundaryValues) {
+ shiftStamps.add(IntegerStamp.create(32, Math.min(v1, v2), Math.max(v1, v2)));
+ }
+ }
+
+ integerTestStamps = new HashSet<>();
+ for (long v1 : longBoundaryValues) {
+ for (long v2 : longBoundaryValues) {
+ if (v2 == (int) v2 && v1 == (int) v1) {
+ integerTestStamps.add(IntegerStamp.create(32, Math.min(v1, v2), Math.max(v1, v2)));
+ }
+ integerTestStamps.add(IntegerStamp.create(64, Math.min(v1, v2), Math.max(v1, v2)));
+ }
+ }
+ }
+
+ static double[] doubleBoundaryValues = {Double.NEGATIVE_INFINITY, Double.MIN_VALUE, Float.NEGATIVE_INFINITY, Float.MIN_VALUE,
+ Long.MIN_VALUE, Long.MIN_VALUE + 1, Integer.MIN_VALUE, Integer.MIN_VALUE + 1, -1, 0, 1,
+ Integer.MAX_VALUE - 1, Integer.MAX_VALUE, Long.MAX_VALUE - 1, Long.MAX_VALUE,
+ Float.MAX_VALUE, Float.POSITIVE_INFINITY, Double.MAX_VALUE, Double.POSITIVE_INFINITY};
+
+ static double[] doubleSpecialValues = {Double.NaN, -0.0, -0.0F, Float.NaN};
+
+ static {
+ floatTestStamps = new HashSet<>();
+
+ for (double d1 : doubleBoundaryValues) {
+ for (double d2 : doubleBoundaryValues) {
+ float f1 = (float) d2;
+ float f2 = (float) d1;
+ if (d2 == f1 && d1 == f2) {
+ generateFloatingStamps(new FloatStamp(32, Math.min(f2, f1), Math.max(f2, f1), true));
+ generateFloatingStamps(new FloatStamp(32, Math.min(f2, f1), Math.max(f2, f1), false));
+ }
+ generateFloatingStamps(new FloatStamp(64, Math.min(d1, d2), Math.max(d1, d2), true));
+ generateFloatingStamps(new FloatStamp(64, Math.min(d1, d2), Math.max(d1, d2), false));
+ }
+ }
+ }
+
+ private static void generateFloatingStamps(FloatStamp floatStamp) {
+ floatTestStamps.add(floatStamp);
+ for (double d : doubleSpecialValues) {
+ FloatStamp newStamp = (FloatStamp) floatStamp.meet(floatStampForConstant(d, floatStamp.getBits()));
+ if (!newStamp.isUnrestricted()) {
+ floatTestStamps.add(newStamp);
+ }
+ }
+ }
+
+ @Test
+ public void testConvertBoundaryValues() {
+ testConvertBoundaryValues(IntegerStamp.OPS.getSignExtend(), 32, 64, integerTestStamps);
+ testConvertBoundaryValues(IntegerStamp.OPS.getZeroExtend(), 32, 64, integerTestStamps);
+ testConvertBoundaryValues(IntegerStamp.OPS.getNarrow(), 64, 32, integerTestStamps);
+ }
+
+ private static void testConvertBoundaryValues(IntegerConvertOp<?> op, int inputBits, int resultBits, HashSet<PrimitiveStamp> stamps) {
+ for (PrimitiveStamp stamp : stamps) {
+ if (inputBits == stamp.getBits()) {
+ Stamp lower = boundaryStamp(stamp, false);
+ Stamp upper = boundaryStamp(stamp, true);
+ checkConvertOperation(op, inputBits, resultBits, op.foldStamp(inputBits, resultBits, stamp), lower);
+ checkConvertOperation(op, inputBits, resultBits, op.foldStamp(inputBits, resultBits, stamp), upper);
+ }
+ }
+ }
+
+ private static void checkConvertOperation(IntegerConvertOp<?> op, int inputBits, int resultBits, Stamp result, Stamp v1stamp) {
+ Stamp folded = op.foldStamp(inputBits, resultBits, v1stamp);
+ assertTrue(folded.asConstant() != null, "should constant fold %s %s %s", op, v1stamp, folded);
+ assertTrue(result.meet(folded).equals(result), "result out of range %s %s %s %s %s", op, v1stamp, folded, result, result.meet(folded));
+ }
+
+ @Test
+ public void testFloatConvertBoundaryValues() {
+ for (FloatConvert op : EnumSet.allOf(FloatConvert.class)) {
+ ArithmeticOpTable.FloatConvertOp floatConvert = IntegerStamp.OPS.getFloatConvert(op);
+ if (floatConvert == null) {
+ continue;
+ }
+ assert op.getCategory() == FloatConvertCategory.IntegerToFloatingPoint : op;
+ testConvertBoundaryValues(floatConvert, op.getInputBits(), integerTestStamps);
+ }
+ for (FloatConvert op : EnumSet.allOf(FloatConvert.class)) {
+ ArithmeticOpTable.FloatConvertOp floatConvert = FloatStamp.OPS.getFloatConvert(op);
+ if (floatConvert == null) {
+ continue;
+ }
+ assert op.getCategory() == FloatConvertCategory.FloatingPointToInteger || op.getCategory() == FloatConvertCategory.FloatingPointToFloatingPoint : op;
+ testConvertBoundaryValues(floatConvert, op.getInputBits(), floatTestStamps);
+ }
+ }
+
+ private static void testConvertBoundaryValues(ArithmeticOpTable.FloatConvertOp op, int bits, HashSet<PrimitiveStamp> stamps) {
+ for (PrimitiveStamp stamp : stamps) {
+ if (bits == stamp.getBits()) {
+ Stamp lower = boundaryStamp(stamp, false);
+ Stamp upper = boundaryStamp(stamp, true);
+ checkConvertOperation(op, op.foldStamp(stamp), lower);
+ checkConvertOperation(op, op.foldStamp(stamp), upper);
+ }
+ }
+ }
+
+ private static void checkConvertOperation(ArithmeticOpTable.FloatConvertOp op, Stamp result, Stamp v1stamp) {
+ Stamp folded = op.foldStamp(v1stamp);
+ assertTrue(folded.asConstant() != null, "should constant fold %s %s %s", op, v1stamp, folded);
+ assertTrue(result.meet(folded).equals(result), "result out of range %s %s %s %s %s", op, v1stamp, folded, result, result.meet(folded));
+ }
+
+ @Test
+ public void testShiftBoundaryValues() {
+ for (ShiftOp<?> op : IntegerStamp.OPS.getShiftOps()) {
+ testShiftBoundaryValues(op, integerTestStamps, shiftStamps);
+ }
+ }
+
+ private static void testShiftBoundaryValues(ShiftOp<?> shiftOp, HashSet<PrimitiveStamp> stamps, HashSet<IntegerStamp> shifts) {
+ for (PrimitiveStamp testStamp : stamps) {
+ if (testStamp instanceof IntegerStamp) {
+ IntegerStamp stamp = (IntegerStamp) testStamp;
+ for (IntegerStamp shiftStamp : shifts) {
+ IntegerStamp foldedStamp = (IntegerStamp) shiftOp.foldStamp(stamp, shiftStamp);
+ checkShiftOperation(stamp.getBits(), shiftOp, foldedStamp, stamp.lowerBound(), shiftStamp.lowerBound());
+ checkShiftOperation(stamp.getBits(), shiftOp, foldedStamp, stamp.lowerBound(), shiftStamp.upperBound());
+ checkShiftOperation(stamp.getBits(), shiftOp, foldedStamp, stamp.upperBound(), shiftStamp.lowerBound());
+ checkShiftOperation(stamp.getBits(), shiftOp, foldedStamp, stamp.upperBound(), shiftStamp.upperBound());
+ }
+ }
+ }
+ }
+
+ private static void checkShiftOperation(int bits, ShiftOp<?> op, IntegerStamp result, long v1, long v2) {
+ IntegerStamp v1stamp = IntegerStamp.create(bits, v1, v1);
+ IntegerStamp v2stamp = IntegerStamp.create(32, v2, v2);
+ IntegerStamp folded = (IntegerStamp) op.foldStamp(v1stamp, v2stamp);
+ Constant constant = op.foldConstant(JavaConstant.forPrimitiveInt(bits, v1), (int) v2);
+ assertTrue(constant != null);
+ assertTrue(folded.asConstant() != null, "should constant fold %s %s %s %s", op, v1stamp, v2stamp, folded);
+ assertTrue(result.meet(folded).equals(result), "result out of range %s %s %s %s %s %s", op, v1stamp, v2stamp, folded, result, result.meet(folded));
+ }
+
+ private static void checkBinaryOperation(ArithmeticOpTable.BinaryOp<?> op, Stamp result, Stamp v1stamp, Stamp v2stamp) {
+ Stamp folded = op.foldStamp(v1stamp, v2stamp);
+ Constant constant = op.foldConstant(v1stamp.asConstant(), v2stamp.asConstant());
+ if (constant != null) {
+ Constant constant2 = folded.asConstant();
+ if (constant2 == null && v1stamp instanceof FloatStamp) {
+ JavaConstant c = (JavaConstant) constant;
+ assertTrue((c.getJavaKind() == JavaKind.Double && Double.isNaN(c.asDouble())) ||
+ (c.getJavaKind() == JavaKind.Float && Float.isNaN(c.asFloat())));
+ } else {
+ assertTrue(constant2 != null, "should constant fold %s %s %s %s", op, v1stamp, v2stamp, folded);
+ if (!constant.equals(constant2)) {
+ op.foldConstant(v1stamp.asConstant(), v2stamp.asConstant());
+ op.foldStamp(v1stamp, v2stamp);
+ }
+ assertTrue(constant.equals(constant2), "should produce same constant %s %s %s %s %s", op, v1stamp, v2stamp, constant, constant2);
+ }
+ assertTrue(result.meet(folded).equals(result), "result out of range %s %s %s %s %s %s", op, v1stamp, v2stamp, folded, result, result.meet(folded));
+ }
+ }
+
+ @Test
+ public void testBinaryBoundaryValues() {
+ for (BinaryOp<?> op : IntegerStamp.OPS.getBinaryOps()) {
+ if (op != null) {
+ testBinaryBoundaryValues(op, integerTestStamps);
+ }
+ }
+ for (BinaryOp<?> op : FloatStamp.OPS.getBinaryOps()) {
+ if (op != null) {
+ testBinaryBoundaryValues(op, floatTestStamps);
+ }
+ }
+ }
+
+ private static Stamp boundaryStamp(Stamp v1, boolean upper) {
+ if (v1 instanceof IntegerStamp) {
+ IntegerStamp istamp = (IntegerStamp) v1;
+ long bound = upper ? istamp.upperBound() : istamp.lowerBound();
+ return IntegerStamp.create(istamp.getBits(), bound, bound);
+ } else if (v1 instanceof FloatStamp) {
+ FloatStamp floatStamp = (FloatStamp) v1;
+ double bound = upper ? floatStamp.upperBound() : floatStamp.lowerBound();
+ int bits = floatStamp.getBits();
+ return floatStampForConstant(bound, bits);
+ } else {
+ throw new InternalError("unexpected stamp type " + v1);
+ }
+ }
+
+ private static FloatStamp floatStampForConstant(double bound, int bits) {
+ if (bits == 32) {
+ float fbound = (float) bound;
+ return new FloatStamp(bits, fbound, fbound, !Float.isNaN(fbound));
+ } else {
+ return new FloatStamp(bits, bound, bound, !Double.isNaN(bound));
+ }
+ }
+
+ private static void testBinaryBoundaryValues(ArithmeticOpTable.BinaryOp<?> op, HashSet<PrimitiveStamp> stamps) {
+ for (PrimitiveStamp v1 : stamps) {
+ for (PrimitiveStamp v2 : stamps) {
+ if (v1.getBits() == v2.getBits() && v1.getClass() == v2.getClass()) {
+ Stamp result = op.foldStamp(v1, v2);
+ Stamp v1lower = boundaryStamp(v1, false);
+ Stamp v1upper = boundaryStamp(v1, true);
+ Stamp v2lower = boundaryStamp(v2, false);
+ Stamp v2upper = boundaryStamp(v2, true);
+ checkBinaryOperation(op, result, v1lower, v2lower);
+ checkBinaryOperation(op, result, v1lower, v2upper);
+ checkBinaryOperation(op, result, v1upper, v2lower);
+ checkBinaryOperation(op, result, v1upper, v2upper);
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testUnaryBoundaryValues() {
+ for (ArithmeticOpTable.UnaryOp<?> op : IntegerStamp.OPS.getUnaryOps()) {
+ if (op != null) {
+ testUnaryBoundaryValues(op, integerTestStamps);
+ }
+ }
+ for (ArithmeticOpTable.UnaryOp<?> op : FloatStamp.OPS.getUnaryOps()) {
+ if (op != null) {
+ testUnaryBoundaryValues(op, floatTestStamps);
+ }
+ }
+ }
+
+ private static void testUnaryBoundaryValues(ArithmeticOpTable.UnaryOp<?> op, HashSet<PrimitiveStamp> stamps) {
+ for (PrimitiveStamp v1 : stamps) {
+ Stamp result = op.foldStamp(v1);
+ checkUnaryOperation(op, result, boundaryStamp(v1, false));
+ checkUnaryOperation(op, result, boundaryStamp(v1, true));
+ }
+ }
+
+ private static void checkUnaryOperation(ArithmeticOpTable.UnaryOp<?> op, Stamp result, Stamp v1stamp) {
+ Stamp folded = op.foldStamp(v1stamp);
+ Constant v1constant = v1stamp.asConstant();
+ if (v1constant != null) {
+ Constant constant = op.foldConstant(v1constant);
+ if (constant != null) {
+ Constant constant2 = folded.asConstant();
+ if (constant2 == null && v1stamp instanceof FloatStamp) {
+ JavaConstant c = (JavaConstant) constant;
+ assertTrue((c.getJavaKind() == JavaKind.Double && Double.isNaN(c.asDouble())) ||
+ (c.getJavaKind() == JavaKind.Float && Float.isNaN(c.asFloat())));
+ } else {
+ assertTrue(constant2 != null, "should constant fold %s %s %s", op, v1stamp, folded);
+ assertTrue(constant.equals(constant2), "should produce same constant %s %s %s %s", op, v1stamp, constant, constant2);
+ }
+ }
+ } else {
+ assert v1stamp instanceof FloatStamp;
+ }
+ assertTrue(result.meet(folded).equals(result), "result out of range %s %s %s %s %s", op, v1stamp, folded, result, result.meet(folded));
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/CompressionNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/CompressionNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -122,9 +122,9 @@
// We always want uncompressed constants
return this;
}
- int stableDimension = ((ConstantNode) forValue).getStableDimension();
- boolean isDefaultStable = ((ConstantNode) forValue).isDefaultStable();
- return ConstantNode.forConstant(stamp(), convert(forValue.asConstant(), tool.getConstantReflection()), stableDimension, isDefaultStable, tool.getMetaAccess());
+
+ ConstantNode constant = (ConstantNode) forValue;
+ return ConstantNode.forConstant(stamp(), convert(constant.getValue(), tool.getConstantReflection()), constant.getStableDimension(), constant.isDefaultStable(), tool.getMetaAccess());
} else if (forValue instanceof CompressionNode) {
CompressionNode other = (CompressionNode) forValue;
if (op != other.op && encoding.equals(other.encoding)) {
@@ -136,22 +136,22 @@
@Override
public void generate(NodeLIRBuilderTool gen) {
- LIRGeneratorTool hsGen = gen.getLIRGeneratorTool();
boolean nonNull;
- if (getValue().stamp() instanceof AbstractObjectStamp) {
- nonNull = StampTool.isPointerNonNull(getValue().stamp());
+ if (value.stamp() instanceof AbstractObjectStamp) {
+ nonNull = StampTool.isPointerNonNull(value.stamp());
} else {
// metaspace pointers are never null
nonNull = true;
}
+ LIRGeneratorTool tool = gen.getLIRGeneratorTool();
Value result;
switch (op) {
case Compress:
- result = hsGen.emitCompress(gen.operand(getValue()), encoding, nonNull);
+ result = tool.emitCompress(gen.operand(value), encoding, nonNull);
break;
case Uncompress:
- result = hsGen.emitUncompress(gen.operand(getValue()), encoding, nonNull);
+ result = tool.emitUncompress(gen.operand(value), encoding, nonNull);
break;
default:
throw GraalError.shouldNotReachHere();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ConstantNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ConstantNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -54,7 +54,7 @@
/**
* The {@code ConstantNode} represents a {@link Constant constant}.
*/
-@NodeInfo(nameTemplate = "C({p#rawvalue})", cycles = CYCLES_0, size = SIZE_1)
+@NodeInfo(nameTemplate = "C({p#rawvalue}) {p#stampKind}", cycles = CYCLES_0, size = SIZE_1)
public final class ConstantNode extends FloatingNode implements LIRLowerable {
public static final NodeClass<ConstantNode> TYPE = NodeClass.create(ConstantNode.class);
@@ -518,13 +518,14 @@
public Map<Object, Object> getDebugProperties(Map<Object, Object> map) {
Map<Object, Object> properties = super.getDebugProperties(map);
properties.put("rawvalue", value.toValueString());
+ properties.put("stampKind", stamp.unrestricted().toString());
return properties;
}
@Override
public String toString(Verbosity verbosity) {
if (verbosity == Verbosity.Name) {
- return super.toString(Verbosity.Name) + "(" + value.toValueString() + ")";
+ return super.toString(Verbosity.Name) + "(" + value.toValueString() + ", " + stamp().unrestricted().toString() + ")";
} else {
return super.toString(verbosity);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,7 +22,7 @@
*/
package org.graalvm.compiler.nodes;
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2;
import java.util.ArrayList;
@@ -74,7 +74,7 @@
* The {@code IfNode} represents a branch that can go one of two directions depending on the outcome
* of a comparison.
*/
-@NodeInfo(cycles = CYCLES_2, size = SIZE_2, sizeRationale = "2 jmps")
+@NodeInfo(cycles = CYCLES_1, size = SIZE_2, sizeRationale = "2 jmps")
public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable {
public static final NodeClass<IfNode> TYPE = NodeClass.create(IfNode.class);
@@ -375,7 +375,7 @@
}
// Falsify the reference check.
- setCondition(graph().addOrUnique(LogicConstantNode.contradiction()));
+ setCondition(graph().addOrUniqueWithInputs(LogicConstantNode.contradiction()));
return true;
}
@@ -726,10 +726,11 @@
protected void removeThroughFalseBranch(SimplifierTool tool, AbstractMergeNode merge) {
AbstractBeginNode trueBegin = trueSuccessor();
+ LogicNode conditionNode = condition();
graph().removeSplitPropagate(this, trueBegin);
tool.addToWorkList(trueBegin);
- if (condition() != null) {
- GraphUtil.tryKillUnused(condition());
+ if (conditionNode != null) {
+ GraphUtil.tryKillUnused(conditionNode);
}
if (merge.isAlive() && merge.forwardEndCount() > 1) {
for (FixedNode end : merge.forwardEnds()) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PhiNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PhiNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -132,12 +132,24 @@
}
str.append(valueAt(i) == null ? "-" : valueAt(i).toString(Verbosity.Id));
}
+ String description = valueDescription();
+ if (description.length() > 0) {
+ str.append(", ").append(description);
+ }
return super.toString(Verbosity.Name) + "(" + str + ")";
} else {
return super.toString(verbosity);
}
}
+ /**
+ * String describing the kind of value this Phi merges. Used by {@link #toString(Verbosity)} and
+ * dumping.
+ */
+ protected String valueDescription() {
+ return "";
+ }
+
public void addInput(ValueNode x) {
assert !(x instanceof ValuePhiNode) || ((ValuePhiNode) x).merge() instanceof LoopBeginNode || ((ValuePhiNode) x).merge() != this.merge();
assert !(this instanceof ValuePhiNode) || x.stamp().isCompatible(stamp());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -59,14 +59,14 @@
*
* In contrast to a {@link GuardedValueNode}, a {@link PiNode} is useless as soon as the type of its
* input is as narrow or narrower than the {@link PiNode}'s type. The {@link PiNode}, and therefore
- * also the scheduling restriction enforced by the anchor, will go away.
+ * also the scheduling restriction enforced by the guard, will go away.
*/
@NodeInfo(cycles = CYCLES_0, size = SIZE_0)
public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, IterableNodeType, Canonicalizable, ValueProxy {
public static final NodeClass<PiNode> TYPE = NodeClass.create(PiNode.class);
@Input ValueNode object;
- protected final Stamp piStamp;
+ protected Stamp piStamp;
public ValueNode object() {
return object;
@@ -84,12 +84,12 @@
this(object, stamp, null);
}
- public PiNode(ValueNode object, Stamp stamp, ValueNode anchor) {
- this(TYPE, object, stamp, (GuardingNode) anchor);
+ public PiNode(ValueNode object, Stamp stamp, ValueNode guard) {
+ this(TYPE, object, stamp, (GuardingNode) guard);
}
- public PiNode(ValueNode object, ValueNode anchor) {
- this(object, AbstractPointerStamp.pointerNonNull(object.stamp()), anchor);
+ public PiNode(ValueNode object, ValueNode guard) {
+ this(object, AbstractPointerStamp.pointerNonNull(object.stamp()), guard);
}
public PiNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) {
@@ -104,29 +104,29 @@
return new PiNode(object, stamp);
}
- public static ValueNode create(ValueNode object, Stamp stamp, ValueNode anchor) {
- ValueNode value = canonical(object, stamp, (GuardingNode) anchor);
+ public static ValueNode create(ValueNode object, Stamp stamp, ValueNode guard) {
+ ValueNode value = canonical(object, stamp, (GuardingNode) guard);
if (value != null) {
return value;
}
- return new PiNode(object, stamp, anchor);
+ return new PiNode(object, stamp, guard);
}
- public static ValueNode create(ValueNode object, ValueNode anchor) {
+ public static ValueNode create(ValueNode object, ValueNode guard) {
Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp());
- ValueNode value = canonical(object, stamp, (GuardingNode) anchor);
+ ValueNode value = canonical(object, stamp, (GuardingNode) guard);
if (value != null) {
return value;
}
- return new PiNode(object, stamp, anchor);
+ return new PiNode(object, stamp, guard);
}
@SuppressWarnings("unused")
- public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ValueNode anchor) {
+ public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ValueNode guard) {
Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp());
- ValueNode value = canonical(object, stamp, (GuardingNode) anchor);
+ ValueNode value = canonical(object, stamp, (GuardingNode) guard);
if (value == null) {
- value = new PiNode(object, stamp, anchor);
+ value = new PiNode(object, stamp, guard);
}
b.push(JavaKind.Object, b.append(value));
return true;
@@ -147,6 +147,11 @@
return piStamp;
}
+ public void strengthenPiStamp(Stamp newPiStamp) {
+ assert this.piStamp.join(newPiStamp).equals(newPiStamp) : "stamp can only improve";
+ this.piStamp = newPiStamp;
+ }
+
@Override
public void generate(NodeLIRBuilderTool generator) {
if (generator.hasOperand(object)) {
@@ -256,17 +261,17 @@
/**
* Changes the stamp of an object and ensures the newly stamped value is non-null and does not
- * float above a given anchor.
+ * float above a given guard.
*/
@NodeIntrinsic
- public static native Object piCastNonNull(Object object, GuardingNode anchor);
+ public static native Object piCastNonNull(Object object, GuardingNode guard);
/**
* Changes the stamp of an object and ensures the newly stamped value is non-null and does not
- * float above a given anchor.
+ * float above a given guard.
*/
@NodeIntrinsic
- public static native Class<?> piCastNonNullClass(Class<?> type, GuardingNode anchor);
+ public static native Class<?> piCastNonNullClass(Class<?> type, GuardingNode guard);
/**
* Changes the stamp of an object to represent a given type and to indicate that the object is
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValuePhiNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValuePhiNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,6 +22,8 @@
*/
package org.graalvm.compiler.nodes;
+import java.util.Map;
+
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.graph.NodeClass;
@@ -35,7 +37,7 @@
/**
* Value {@link PhiNode}s merge data flow values at control flow merges.
*/
-@NodeInfo(nameTemplate = "Phi({i#values})")
+@NodeInfo(nameTemplate = "Phi({i#values}, {p#valueDescription})")
public class ValuePhiNode extends PhiNode implements ArrayLengthProvider {
public static final NodeClass<ValuePhiNode> TYPE = NodeClass.create(ValuePhiNode.class);
@@ -113,4 +115,16 @@
}
return super.verify();
}
+
+ @Override
+ protected String valueDescription() {
+ return stamp().unrestricted().toString();
+ }
+
+ @Override
+ public Map<Object, Object> getDebugProperties(Map<Object, Object> map) {
+ Map<Object, Object> properties = super.getDebugProperties(map);
+ properties.put("valueDescription", valueDescription());
+ return properties;
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -91,7 +91,9 @@
public static <OP> ConstantNode tryConstantFold(BinaryOp<OP> op, ValueNode forX, ValueNode forY, Stamp stamp) {
if (forX.isConstant() && forY.isConstant()) {
Constant ret = op.foldConstant(forX.asConstant(), forY.asConstant());
- return ConstantNode.forPrimitive(stamp, ret);
+ if (ret != null) {
+ return ConstantNode.forPrimitive(stamp, ret);
+ }
}
return null;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ConditionalNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ConditionalNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,7 +22,7 @@
*/
package org.graalvm.compiler.nodes.calc;
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0;
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2;
import static org.graalvm.compiler.nodes.calc.CompareNode.createCompareNode;
@@ -47,10 +47,10 @@
import jdk.vm.ci.meta.JavaConstant;
/**
- * The {@code ConditionalNode} class represents a comparison that yields one of two values. Note
- * that these nodes are not built directly from the bytecode but are introduced by canonicalization.
+ * The {@code ConditionalNode} class represents a comparison that yields one of two (eagerly
+ * evaluated) values.
*/
-@NodeInfo(cycles = CYCLES_0, size = SIZE_2)
+@NodeInfo(cycles = CYCLES_1, size = SIZE_2)
public final class ConditionalNode extends FloatingNode implements Canonicalizable, LIRLowerable {
public static final NodeClass<ConditionalNode> TYPE = NodeClass.create(ConditionalNode.class);
@@ -116,7 +116,6 @@
valueStamp = valueStamp.join(bounds);
}
}
-
}
return updateStamp(valueStamp);
}
@@ -145,49 +144,10 @@
}
public static ValueNode canonicalizeConditional(LogicNode condition, ValueNode trueValue, ValueNode falseValue, Stamp stamp) {
- // this optimizes the case where a value from the range 0 - 1 is mapped to the range 0 - 1
- if (trueValue.isConstant() && falseValue.isConstant() && trueValue.stamp() instanceof IntegerStamp && falseValue.stamp() instanceof IntegerStamp) {
- long constTrueValue = trueValue.asJavaConstant().asLong();
- long constFalseValue = falseValue.asJavaConstant().asLong();
- if (condition instanceof IntegerEqualsNode) {
- IntegerEqualsNode equals = (IntegerEqualsNode) condition;
- if (equals.getY().isConstant() && equals.getX().stamp() instanceof IntegerStamp) {
- IntegerStamp equalsXStamp = (IntegerStamp) equals.getX().stamp();
- if (equalsXStamp.upMask() == 1) {
- long equalsY = equals.getY().asJavaConstant().asLong();
- if (equalsY == 0) {
- if (constTrueValue == 0 && constFalseValue == 1) {
- // return x when: x == 0 ? 0 : 1;
- return IntegerConvertNode.convertUnsigned(equals.getX(), stamp);
- } else if (constTrueValue == 1 && constFalseValue == 0) {
- // negate a boolean value via xor
- return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(), 1)), stamp);
- }
- } else if (equalsY == 1) {
- if (constTrueValue == 1 && constFalseValue == 0) {
- // return x when: x == 1 ? 1 : 0;
- return IntegerConvertNode.convertUnsigned(equals.getX(), stamp);
- } else if (constTrueValue == 0 && constFalseValue == 1) {
- // negate a boolean value via xor
- return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(), 1)), stamp);
- }
- }
- }
- }
- } else if (condition instanceof IntegerTestNode) {
- // replace IntegerTestNode with AndNode for the following patterns:
- // (value & 1) == 0 ? 0 : 1
- // (value & 1) == 1 ? 1 : 0
- IntegerTestNode integerTestNode = (IntegerTestNode) condition;
- if (integerTestNode.getY().isConstant()) {
- assert integerTestNode.getX().stamp() instanceof IntegerStamp;
- long testY = integerTestNode.getY().asJavaConstant().asLong();
- if (testY == 1 && constTrueValue == 0 && constFalseValue == 1) {
- return IntegerConvertNode.convertUnsigned(AndNode.create(integerTestNode.getX(), integerTestNode.getY()), stamp);
- }
- }
- }
+ if (trueValue == falseValue) {
+ return trueValue;
}
+
if (condition instanceof CompareNode && ((CompareNode) condition).isIdentityComparison()) {
// optimize the pattern (x == y) ? x : y
CompareNode compare = (CompareNode) condition;
@@ -195,25 +155,87 @@
return falseValue;
}
}
- if (trueValue == falseValue) {
- return trueValue;
- }
+
+ if (trueValue.stamp() instanceof IntegerStamp) {
+ // check if the conditional is redundant
+ if (condition instanceof IntegerLessThanNode) {
+ IntegerLessThanNode lessThan = (IntegerLessThanNode) condition;
+ IntegerStamp falseValueStamp = (IntegerStamp) falseValue.stamp();
+ IntegerStamp trueValueStamp = (IntegerStamp) trueValue.stamp();
+ if (lessThan.getX() == trueValue && lessThan.getY() == falseValue) {
+ // return "x" for "x < y ? x : y" in case that we know "x <= y"
+ if (trueValueStamp.upperBound() <= falseValueStamp.lowerBound()) {
+ return trueValue;
+ }
+ } else if (lessThan.getX() == falseValue && lessThan.getY() == trueValue) {
+ // return "x" for "x < y ? y : x" in case that we know "x <= y"
+ if (falseValueStamp.upperBound() <= trueValueStamp.lowerBound()) {
+ return falseValue;
+ }
+ }
+ }
- if (condition instanceof IntegerLessThanNode && trueValue.stamp() instanceof IntegerStamp) {
- /*
- * Convert a conditional add ((x < 0) ? (x + y) : x) into (x + (y & (x >> (bits - 1))))
- * to avoid the test.
- */
- IntegerLessThanNode lt = (IntegerLessThanNode) condition;
- if (lt.getY().isConstant() && lt.getY().asConstant().isDefaultForKind()) {
- if (falseValue == lt.getX()) {
- if (trueValue instanceof AddNode) {
- AddNode add = (AddNode) trueValue;
- if (add.getX() == falseValue) {
- int bits = ((IntegerStamp) trueValue.stamp()).getBits();
- ValueNode shift = new RightShiftNode(lt.getX(), ConstantNode.forIntegerBits(32, bits - 1));
- ValueNode and = new AndNode(shift, add.getY());
- return new AddNode(add.getX(), and);
+ // this optimizes the case where a value from the range 0 - 1 is mapped to the
+ // range 0 - 1
+ if (trueValue.isConstant() && falseValue.isConstant()) {
+ long constTrueValue = trueValue.asJavaConstant().asLong();
+ long constFalseValue = falseValue.asJavaConstant().asLong();
+ if (condition instanceof IntegerEqualsNode) {
+ IntegerEqualsNode equals = (IntegerEqualsNode) condition;
+ if (equals.getY().isConstant() && equals.getX().stamp() instanceof IntegerStamp) {
+ IntegerStamp equalsXStamp = (IntegerStamp) equals.getX().stamp();
+ if (equalsXStamp.upMask() == 1) {
+ long equalsY = equals.getY().asJavaConstant().asLong();
+ if (equalsY == 0) {
+ if (constTrueValue == 0 && constFalseValue == 1) {
+ // return x when: x == 0 ? 0 : 1;
+ return IntegerConvertNode.convertUnsigned(equals.getX(), stamp);
+ } else if (constTrueValue == 1 && constFalseValue == 0) {
+ // negate a boolean value via xor
+ return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(), 1)), stamp);
+ }
+ } else if (equalsY == 1) {
+ if (constTrueValue == 1 && constFalseValue == 0) {
+ // return x when: x == 1 ? 1 : 0;
+ return IntegerConvertNode.convertUnsigned(equals.getX(), stamp);
+ } else if (constTrueValue == 0 && constFalseValue == 1) {
+ // negate a boolean value via xor
+ return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(), 1)), stamp);
+ }
+ }
+ }
+ }
+ } else if (condition instanceof IntegerTestNode) {
+ // replace IntegerTestNode with AndNode for the following patterns:
+ // (value & 1) == 0 ? 0 : 1
+ // (value & 1) == 1 ? 1 : 0
+ IntegerTestNode integerTestNode = (IntegerTestNode) condition;
+ if (integerTestNode.getY().isConstant()) {
+ assert integerTestNode.getX().stamp() instanceof IntegerStamp;
+ long testY = integerTestNode.getY().asJavaConstant().asLong();
+ if (testY == 1 && constTrueValue == 0 && constFalseValue == 1) {
+ return IntegerConvertNode.convertUnsigned(AndNode.create(integerTestNode.getX(), integerTestNode.getY()), stamp);
+ }
+ }
+ }
+ }
+
+ if (condition instanceof IntegerLessThanNode) {
+ /*
+ * Convert a conditional add ((x < 0) ? (x + y) : x) into (x + (y & (x >> (bits -
+ * 1)))) to avoid the test.
+ */
+ IntegerLessThanNode lt = (IntegerLessThanNode) condition;
+ if (lt.getY().isConstant() && lt.getY().asConstant().isDefaultForKind()) {
+ if (falseValue == lt.getX()) {
+ if (trueValue instanceof AddNode) {
+ AddNode add = (AddNode) trueValue;
+ if (add.getX() == falseValue) {
+ int bits = ((IntegerStamp) trueValue.stamp()).getBits();
+ ValueNode shift = new RightShiftNode(lt.getX(), ConstantNode.forIntegerBits(32, bits - 1));
+ ValueNode and = new AndNode(shift, add.getY());
+ return new AddNode(add.getX(), and);
+ }
}
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/DivNode.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2011, 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.
- *
- * 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 org.graalvm.compiler.nodes.calc;
-
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_32;
-
-import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
-import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
-import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Div;
-import org.graalvm.compiler.core.common.type.Stamp;
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.graph.spi.CanonicalizerTool;
-import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.ConstantNode;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-
-import jdk.vm.ci.code.CodeUtil;
-import jdk.vm.ci.meta.Constant;
-import jdk.vm.ci.meta.PrimitiveConstant;
-
-@NodeInfo(shortName = "/", cycles = CYCLES_32)
-public class DivNode extends BinaryArithmeticNode<Div> {
-
- public static final NodeClass<DivNode> TYPE = NodeClass.create(DivNode.class);
-
- public DivNode(ValueNode x, ValueNode y) {
- super(TYPE, ArithmeticOpTable::getDiv, x, y);
- }
-
- protected DivNode(NodeClass<? extends DivNode> c, ValueNode x, ValueNode y) {
- super(c, ArithmeticOpTable::getDiv, x, y);
- }
-
- public static ValueNode create(ValueNode x, ValueNode y) {
- BinaryOp<Div> op = ArithmeticOpTable.forStamp(x.stamp()).getDiv();
- Stamp stamp = op.foldStamp(x.stamp(), y.stamp());
- ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp);
- if (tryConstantFold != null) {
- return tryConstantFold;
- }
- return canonical(null, op, x, y);
- }
-
- @Override
- public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
- ValueNode ret = super.canonical(tool, forX, forY);
- if (ret != this) {
- return ret;
- }
-
- return canonical(this, getOp(forX, forY), forX, forY);
- }
-
- private static ValueNode canonical(DivNode self, BinaryOp<Div> op, ValueNode forX, ValueNode forY) {
- if (forY.isConstant()) {
- Constant c = forY.asConstant();
- if (op.isNeutral(c)) {
- return forX;
- }
- if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
- long i = ((PrimitiveConstant) c).asLong();
- boolean signFlip = false;
- if (i < 0) {
- i = -i;
- signFlip = true;
- }
- ValueNode divResult = null;
- if (CodeUtil.isPowerOf2(i)) {
- divResult = new RightShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i)));
- }
- if (divResult != null) {
- if (signFlip) {
- return NegateNode.create(divResult);
- } else {
- return divResult;
- }
- }
- }
- }
- return self != null ? self : new DivNode(forX, forY);
- }
-
- @Override
- public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) {
- nodeValueMap.setResult(this, gen.emitDiv(nodeValueMap.operand(getX()), nodeValueMap.operand(getY()), null));
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatDivNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2011, 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.
+ *
+ * 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 org.graalvm.compiler.nodes.calc;
+
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_32;
+
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.FloatStamp;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Div;
+import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
+
+import jdk.vm.ci.meta.Constant;
+
+@NodeInfo(shortName = "/", cycles = CYCLES_32)
+public class FloatDivNode extends BinaryArithmeticNode<Div> {
+
+ public static final NodeClass<FloatDivNode> TYPE = NodeClass.create(FloatDivNode.class);
+
+ public FloatDivNode(ValueNode x, ValueNode y) {
+ this(TYPE, x, y);
+ }
+
+ protected FloatDivNode(NodeClass<? extends FloatDivNode> c, ValueNode x, ValueNode y) {
+ super(c, ArithmeticOpTable::getDiv, x, y);
+ assert stamp instanceof FloatStamp;
+ }
+
+ public static ValueNode create(ValueNode x, ValueNode y) {
+ BinaryOp<Div> op = ArithmeticOpTable.forStamp(x.stamp()).getDiv();
+ Stamp stamp = op.foldStamp(x.stamp(), y.stamp());
+ ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp);
+ if (tryConstantFold != null) {
+ return tryConstantFold;
+ }
+ return canonical(null, op, x, y);
+ }
+
+ @Override
+ public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+ ValueNode ret = super.canonical(tool, forX, forY);
+ if (ret != this) {
+ return ret;
+ }
+
+ return canonical(this, getOp(forX, forY), forX, forY);
+ }
+
+ private static ValueNode canonical(FloatDivNode self, BinaryOp<Div> op, ValueNode forX, ValueNode forY) {
+ if (forY.isConstant()) {
+ Constant c = forY.asConstant();
+ if (op.isNeutral(c)) {
+ return forX;
+ }
+ }
+ return self != null ? self : new FloatDivNode(forX, forY);
+ }
+
+ @Override
+ public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) {
+ nodeValueMap.setResult(this, gen.emitDiv(nodeValueMap.operand(getX()), nodeValueMap.operand(getY()), null));
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerConvertNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerConvertNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -129,7 +129,7 @@
ValueNode convert = convert(input, stamp, false);
if (!convert.isAlive()) {
assert !convert.isDeleted();
- convert = graph.addOrUnique(convert);
+ convert = graph.addOrUniqueWithInputs(convert);
}
return convert;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -52,7 +52,7 @@
@NodeInfo(shortName = "<")
public final class IntegerLessThanNode extends IntegerLowerThanNode {
public static final NodeClass<IntegerLessThanNode> TYPE = NodeClass.create(IntegerLessThanNode.class);
- public static final LessThanOp OP = new LessThanOp();
+ private static final LessThanOp OP = new LessThanOp();
public IntegerLessThanNode(ValueNode x, ValueNode y) {
super(TYPE, x, y, OP);
@@ -203,49 +203,52 @@
}
}
- int bits = ((IntegerStamp) forX.stamp()).getBits();
- assert ((IntegerStamp) forY.stamp()).getBits() == bits;
- long min = OP.minValue(bits);
- long xResidue = 0;
- ValueNode left = null;
- JavaConstant leftCst = null;
- if (forX instanceof AddNode) {
- AddNode xAdd = (AddNode) forX;
- if (xAdd.getY().isJavaConstant()) {
- long xCst = xAdd.getY().asJavaConstant().asLong();
- xResidue = xCst - min;
- left = xAdd.getX();
+ if (forX.stamp() instanceof IntegerStamp) {
+ assert forY.stamp() instanceof IntegerStamp;
+ int bits = ((IntegerStamp) forX.stamp()).getBits();
+ assert ((IntegerStamp) forY.stamp()).getBits() == bits;
+ long min = OP.minValue(bits);
+ long xResidue = 0;
+ ValueNode left = null;
+ JavaConstant leftCst = null;
+ if (forX instanceof AddNode) {
+ AddNode xAdd = (AddNode) forX;
+ if (xAdd.getY().isJavaConstant()) {
+ long xCst = xAdd.getY().asJavaConstant().asLong();
+ xResidue = xCst - min;
+ left = xAdd.getX();
+ }
+ } else if (forX.isJavaConstant()) {
+ leftCst = forX.asJavaConstant();
}
- } else if (forX.isJavaConstant()) {
- leftCst = forX.asJavaConstant();
- }
- if (left != null || leftCst != null) {
- long yResidue = 0;
- ValueNode right = null;
- JavaConstant rightCst = null;
- if (forY instanceof AddNode) {
- AddNode yAdd = (AddNode) forY;
- if (yAdd.getY().isJavaConstant()) {
- long yCst = yAdd.getY().asJavaConstant().asLong();
- yResidue = yCst - min;
- right = yAdd.getX();
+ if (left != null || leftCst != null) {
+ long yResidue = 0;
+ ValueNode right = null;
+ JavaConstant rightCst = null;
+ if (forY instanceof AddNode) {
+ AddNode yAdd = (AddNode) forY;
+ if (yAdd.getY().isJavaConstant()) {
+ long yCst = yAdd.getY().asJavaConstant().asLong();
+ yResidue = yCst - min;
+ right = yAdd.getX();
+ }
+ } else if (forY.isJavaConstant()) {
+ rightCst = forY.asJavaConstant();
}
- } else if (forY.isJavaConstant()) {
- rightCst = forY.asJavaConstant();
- }
- if (right != null || rightCst != null) {
- if ((xResidue == 0 && left != null) || (yResidue == 0 && right != null)) {
- if (left == null) {
- left = ConstantNode.forIntegerBits(bits, leftCst.asLong() - min);
- } else if (xResidue != 0) {
- left = AddNode.create(left, ConstantNode.forIntegerBits(bits, xResidue));
+ if (right != null || rightCst != null) {
+ if ((xResidue == 0 && left != null) || (yResidue == 0 && right != null)) {
+ if (left == null) {
+ left = ConstantNode.forIntegerBits(bits, leftCst.asLong() - min);
+ } else if (xResidue != 0) {
+ left = AddNode.create(left, ConstantNode.forIntegerBits(bits, xResidue));
+ }
+ if (right == null) {
+ right = ConstantNode.forIntegerBits(bits, rightCst.asLong() - min);
+ } else if (yResidue != 0) {
+ right = AddNode.create(right, ConstantNode.forIntegerBits(bits, yResidue));
+ }
+ return new IntegerBelowNode(left, right);
}
- if (right == null) {
- right = ConstantNode.forIntegerBits(bits, rightCst.asLong() - min);
- } else if (yResidue != 0) {
- right = AddNode.create(right, ConstantNode.forIntegerBits(bits, yResidue));
- }
- return new IntegerBelowNode(left, right);
}
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IsNullNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IsNullNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -121,7 +121,8 @@
@Override
public Stamp getSucceedingStampForValue(boolean negated) {
- AbstractPointerStamp pointerStamp = (AbstractPointerStamp) getValue().stamp();
+ // Ignore any more precise input stamp since canonicalization will skip through PiNodes
+ AbstractPointerStamp pointerStamp = (AbstractPointerStamp) getValue().stamp().unrestricted();
return negated ? pointerStamp.asNonNull() : pointerStamp.asAlwaysNull();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedDivNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedDivNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -63,29 +63,9 @@
return ConstantNode.forIntegerStamp(stamp(), forX.asJavaConstant().asLong() / y);
} else if (forY.isConstant()) {
long c = forY.asJavaConstant().asLong();
- if (c == 1) {
- return forX;
- }
- if (c == -1) {
- return NegateNode.create(forX);
- }
- long abs = Math.abs(c);
- if (CodeUtil.isPowerOf2(abs) && forX.stamp() instanceof IntegerStamp) {
- ValueNode dividend = forX;
- IntegerStamp stampX = (IntegerStamp) forX.stamp();
- int log2 = CodeUtil.log2(abs);
- // no rounding if dividend is positive or if its low bits are always 0
- if (stampX.canBeNegative() || (stampX.upMask() & (abs - 1)) != 0) {
- int bits = PrimitiveStamp.getBits(stamp());
- RightShiftNode sign = new RightShiftNode(forX, ConstantNode.forInt(bits - 1));
- UnsignedRightShiftNode round = new UnsignedRightShiftNode(sign, ConstantNode.forInt(bits - log2));
- dividend = BinaryArithmeticNode.add(dividend, round);
- }
- RightShiftNode shift = new RightShiftNode(dividend, ConstantNode.forInt(log2));
- if (c < 0) {
- return NegateNode.create(shift);
- }
- return shift;
+ ValueNode v = canonical(forX, c);
+ if (v != null) {
+ return v;
}
}
@@ -113,6 +93,34 @@
return this;
}
+ public static ValueNode canonical(ValueNode forX, long c) {
+ if (c == 1) {
+ return forX;
+ }
+ if (c == -1) {
+ return NegateNode.create(forX);
+ }
+ long abs = Math.abs(c);
+ if (CodeUtil.isPowerOf2(abs) && forX.stamp() instanceof IntegerStamp) {
+ ValueNode dividend = forX;
+ IntegerStamp stampX = (IntegerStamp) forX.stamp();
+ int log2 = CodeUtil.log2(abs);
+ // no rounding if dividend is positive or if its low bits are always 0
+ if (stampX.canBeNegative() || (stampX.upMask() & (abs - 1)) != 0) {
+ int bits = PrimitiveStamp.getBits(forX.stamp());
+ RightShiftNode sign = new RightShiftNode(forX, ConstantNode.forInt(bits - 1));
+ UnsignedRightShiftNode round = new UnsignedRightShiftNode(sign, ConstantNode.forInt(bits - log2));
+ dividend = BinaryArithmeticNode.add(dividend, round);
+ }
+ RightShiftNode shift = new RightShiftNode(dividend, ConstantNode.forInt(log2));
+ if (c < 0) {
+ return NegateNode.create(shift);
+ }
+ return shift;
+ }
+ return null;
+ }
+
@Override
public void generate(NodeLIRBuilderTool gen) {
gen.setResult(this, gen.getLIRGeneratorTool().getArithmetic().emitDiv(gen.operand(getX()), gen.operand(getY()), gen.state(this)));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedRemNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedRemNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -72,13 +72,14 @@
return ConstantNode.forIntegerStamp(stamp(), 0);
} else if (CodeUtil.isPowerOf2(constY)) {
if (xStamp.isPositive()) {
+ // x & (y - 1)
return new AndNode(forX, ConstantNode.forIntegerStamp(stamp(), constY - 1));
} else if (xStamp.isNegative()) {
+ // -((-x) & (y - 1))
return new NegateNode(new AndNode(new NegateNode(forX), ConstantNode.forIntegerStamp(stamp(), constY - 1)));
} else {
- return new ConditionalNode(IntegerLessThanNode.create(forX, ConstantNode.forIntegerStamp(forX.stamp(), 0)),
- new NegateNode(new AndNode(new NegateNode(forX), ConstantNode.forIntegerStamp(stamp(), constY - 1))),
- new AndNode(forX, ConstantNode.forIntegerStamp(stamp(), constY - 1)));
+ // x - ((x / y) << log2(y))
+ return SubNode.create(forX, LeftShiftNode.create(SignedDivNode.canonical(forX, constY), ConstantNode.forInt(CodeUtil.log2(constY))));
}
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnaryNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnaryNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -45,6 +45,11 @@
return value;
}
+ public void setValue(ValueNode value) {
+ updateUsages(this.value, value);
+ this.value = value;
+ }
+
/**
* Creates a new UnaryNode instance.
*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnpackEndianHalfNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+package org.graalvm.compiler.nodes.calc;
+
+import java.nio.ByteOrder;
+
+import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+import org.graalvm.compiler.nodeinfo.NodeCycles;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.spi.Lowerable;
+import org.graalvm.compiler.nodes.spi.LoweringTool;
+
+import jdk.vm.ci.meta.JavaKind;
+
+/**
+ * Produces the platform dependent first or second half of a long or double value as an int.
+ */
+@NodeInfo(cycles = NodeCycles.CYCLES_2)
+public final class UnpackEndianHalfNode extends UnaryNode implements Lowerable {
+ public static final NodeClass<UnpackEndianHalfNode> TYPE = NodeClass.create(UnpackEndianHalfNode.class);
+
+ private final boolean firstHalf;
+
+ protected UnpackEndianHalfNode(ValueNode value, boolean firstHalf) {
+ super(TYPE, StampFactory.forKind(JavaKind.Int), value);
+ assert value.getStackKind() == JavaKind.Double || value.getStackKind() == JavaKind.Long : "unexpected kind " + value.getStackKind();
+ this.firstHalf = firstHalf;
+ }
+
+ public static ValueNode create(ValueNode value, boolean firstHalf) {
+ if (value.isConstant() && value.asConstant().isDefaultForKind()) {
+ return ConstantNode.defaultForKind(JavaKind.Int);
+ }
+ return new UnpackEndianHalfNode(value, firstHalf);
+ }
+
+ public boolean isFirstHalf() {
+ return firstHalf;
+ }
+
+ @Override
+ public Node canonical(CanonicalizerTool tool, ValueNode forValue) {
+ if (forValue.isConstant() && forValue.asConstant().isDefaultForKind()) {
+ return ConstantNode.defaultForKind(stamp.getStackKind());
+ }
+ return this;
+ }
+
+ @Override
+ public void lower(LoweringTool tool) {
+ tool.getLowerer().lower(this, tool);
+ }
+
+ public void lower(ByteOrder byteOrder) {
+ ValueNode result = value;
+ if (value.getStackKind() == JavaKind.Double) {
+ result = graph().unique(new ReinterpretNode(JavaKind.Long, value));
+ }
+ if ((byteOrder == ByteOrder.BIG_ENDIAN) == firstHalf) {
+ result = graph().unique(new UnsignedRightShiftNode(result, ConstantNode.forInt(32, graph())));
+ }
+ result = IntegerConvertNode.convert(result, StampFactory.forKind(JavaKind.Int), graph());
+ replaceAtUsagesAndDelete(result);
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/ControlFlowGraph.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/ControlFlowGraph.java Wed Nov 08 16:03:35 2017 -0500
@@ -592,7 +592,11 @@
for (Block block : reversePostOrder) {
AbstractBeginNode beginNode = block.getBeginNode();
if (beginNode instanceof LoopBeginNode) {
- Loop<Block> loop = new HIRLoop(block.getLoop(), loops.size(), block);
+ Loop<Block> parent = block.getLoop();
+ Loop<Block> loop = new HIRLoop(parent, loops.size(), block);
+ if (parent != null) {
+ parent.getChildren().add(loop);
+ }
loops.add(loop);
block.setLoop(loop);
loop.getBlocks().add(block);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BranchProbabilityNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BranchProbabilityNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -82,6 +82,9 @@
@Override
public void simplify(SimplifierTool tool) {
+ if (!hasUsages()) {
+ return;
+ }
if (probability.isConstant()) {
double probabilityValue = probability.asJavaConstant().asDouble();
if (probabilityValue < 0.0) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawLoadNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawLoadNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -79,7 +79,7 @@
super(TYPE, stamp, object, offset, accessKind, locationIdentity, false);
}
- public RawLoadNode(NodeClass<? extends RawLoadNode> c, ValueNode object, ValueNode offset, JavaKind accessKind, LocationIdentity locationIdentity) {
+ protected RawLoadNode(NodeClass<? extends RawLoadNode> c, ValueNode object, ValueNode offset, JavaKind accessKind, LocationIdentity locationIdentity) {
super(c, StampFactory.forKind(accessKind.getStackKind()), object, offset, accessKind, locationIdentity, false);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawStoreNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawStoreNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -29,7 +29,6 @@
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.FrameState;
import org.graalvm.compiler.nodes.StateSplit;
import org.graalvm.compiler.nodes.ValueNode;
@@ -39,12 +38,10 @@
import org.graalvm.compiler.nodes.spi.LoweringTool;
import org.graalvm.compiler.nodes.spi.Virtualizable;
import org.graalvm.compiler.nodes.spi.VirtualizerTool;
-import org.graalvm.compiler.nodes.type.StampTool;
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
import org.graalvm.word.LocationIdentity;
import jdk.vm.ci.meta.Assumptions;
-import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ResolvedJavaField;
@@ -123,41 +120,8 @@
if (indexValue.isConstant()) {
long off = indexValue.asJavaConstant().asLong();
int entryIndex = virtual.entryIndexForOffset(off, accessKind());
- if (entryIndex != -1) {
- JavaKind entryKind = virtual.entryKind(entryIndex);
- boolean canVirtualize = entryKind == accessKind() || (entryKind == accessKind().getStackKind() && !StampTool.typeOrNull(object()).isArray());
- if (!canVirtualize) {
- /*
- * Special case: If the entryKind is long, allow arbitrary kinds as long as
- * a value of the same kind is already there. This can only happen if some
- * other node initialized the entry with a value of a different kind. One
- * example where this happens is the Truffle NewFrameNode.
- */
- ValueNode entry = tool.getEntry(virtual, entryIndex);
- if (entryKind == JavaKind.Long && entry.getStackKind() == value.getStackKind()) {
- canVirtualize = true;
- }
- }
- if (canVirtualize) {
- tool.setVirtualEntry(virtual, entryIndex, value(), true);
- tool.delete();
- } else {
- /*
- * Special case: Allow storing a single long or double value into two
- * consecutive int slots.
- */
- if ((accessKind() == JavaKind.Long || accessKind() == JavaKind.Double) && entryKind == JavaKind.Int) {
- int nextIndex = virtual.entryIndexForOffset(off + 4, entryKind);
- if (nextIndex != -1) {
- JavaKind nextKind = virtual.entryKind(nextIndex);
- if (nextKind == JavaKind.Int) {
- tool.setVirtualEntry(virtual, entryIndex, value(), true);
- tool.setVirtualEntry(virtual, nextIndex, ConstantNode.forConstant(JavaConstant.forIllegal(), tool.getMetaAccessProvider(), graph()), true);
- tool.delete();
- }
- }
- }
- }
+ if (entryIndex != -1 && tool.setVirtualEntry(virtual, entryIndex, value(), accessKind(), off)) {
+ tool.delete();
}
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java Wed Nov 08 16:03:35 2017 -0500
@@ -280,7 +280,7 @@
ObjectStamp receiverStamp = (ObjectStamp) value.stamp();
Stamp stamp = receiverStamp.join(objectNonNull());
FixedGuardNode fixedGuard = append(new FixedGuardNode(condition, NullCheckException, action, true));
- ValueNode nonNullReceiver = getGraph().addOrUnique(PiNode.create(value, stamp, fixedGuard));
+ ValueNode nonNullReceiver = getGraph().addOrUniqueWithInputs(PiNode.create(value, stamp, fixedGuard));
// TODO: Propogating the non-null into the frame state would
// remove subsequent null-checks on the same value. However,
// it currently causes an assertion failure when merging states.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InlineInvokePlugin.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InlineInvokePlugin.java Wed Nov 08 16:03:35 2017 -0500
@@ -53,6 +53,12 @@
*/
public static final InlineInfo DO_NOT_INLINE_NO_EXCEPTION = new InlineInfo(null, null);
+ /**
+ * Denotes a call site must not be inlined and the execution should be transferred to
+ * interpreter in case of an exception.
+ */
+ public static final InlineInfo DO_NOT_INLINE_DEOPTIMIZE_ON_EXCEPTION = new InlineInfo(null, null);
+
private final ResolvedJavaMethod methodToInline;
private final BytecodeProvider intrinsicBytecodeProvider;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/IntrinsicContext.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/IntrinsicContext.java Wed Nov 08 16:03:35 2017 -0500
@@ -66,6 +66,34 @@
*/
final BytecodeProvider bytecodeProvider;
+ final CompilationContext compilationContext;
+
+ final boolean allowPartialIntrinsicArgumentMismatch;
+
+ public IntrinsicContext(ResolvedJavaMethod method, ResolvedJavaMethod intrinsic, BytecodeProvider bytecodeProvider, CompilationContext compilationContext) {
+ this(method, intrinsic, bytecodeProvider, compilationContext, false);
+ }
+
+ public IntrinsicContext(ResolvedJavaMethod method, ResolvedJavaMethod intrinsic, BytecodeProvider bytecodeProvider, CompilationContext compilationContext,
+ boolean allowPartialIntrinsicArgumentMismatch) {
+ this.method = method;
+ this.intrinsic = intrinsic;
+ this.bytecodeProvider = bytecodeProvider;
+ assert bytecodeProvider != null;
+ this.compilationContext = compilationContext;
+ this.allowPartialIntrinsicArgumentMismatch = allowPartialIntrinsicArgumentMismatch;
+ assert !isCompilationRoot() || method.hasBytecodes() : "Cannot root compile intrinsic for native or abstract method " + method.format("%H.%n(%p)");
+ }
+
+ /**
+ * A partial intrinsic exits by (effectively) calling the intrinsified method. Normally, this
+ * call must use exactly the same arguments as the call that is being intrinsified. This allows
+ * to override this behavior.
+ */
+ public boolean allowPartialIntrinsicArgumentMismatch() {
+ return allowPartialIntrinsicArgumentMismatch;
+ }
+
/**
* Gets the method being intrinsified.
*/
@@ -96,17 +124,6 @@
return method.equals(targetMethod) || intrinsic.equals(targetMethod);
}
- final CompilationContext compilationContext;
-
- public IntrinsicContext(ResolvedJavaMethod method, ResolvedJavaMethod intrinsic, BytecodeProvider bytecodeProvider, CompilationContext compilationContext) {
- this.method = method;
- this.intrinsic = intrinsic;
- this.bytecodeProvider = bytecodeProvider;
- assert bytecodeProvider != null;
- this.compilationContext = compilationContext;
- assert !isCompilationRoot() || method.hasBytecodes() : "Cannot root compile intrinsic for native or abstract method " + method.format("%H.%n(%p)");
- }
-
public boolean isPostParseInlined() {
return compilationContext.equals(INLINE_AFTER_PARSING);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -49,6 +49,8 @@
import jdk.vm.ci.meta.JavaTypeProfile;
import jdk.vm.ci.meta.TriState;
+import java.util.Objects;
+
/**
* The {@code InstanceOfNode} represents an instanceof test.
*/
@@ -56,7 +58,7 @@
public class InstanceOfNode extends UnaryOpLogicNode implements Lowerable, Virtualizable {
public static final NodeClass<InstanceOfNode> TYPE = NodeClass.create(InstanceOfNode.class);
- protected final ObjectStamp checkedStamp;
+ private ObjectStamp checkedStamp;
private JavaTypeProfile profile;
@OptionalInput(Anchor) protected AnchoringNode anchor;
@@ -126,7 +128,9 @@
// The check will always succeed, the union of the two stamps is equal to the
// checked stamp.
return LogicConstantNode.tautology();
- } else if (checkedStamp.type().equals(meetStamp.type()) && checkedStamp.isExactType() == meetStamp.isExactType() && checkedStamp.alwaysNull() == meetStamp.alwaysNull()) {
+ } else if (checkedStamp.alwaysNull()) {
+ return IsNullNode.create(object);
+ } else if (Objects.equals(checkedStamp.type(), meetStamp.type()) && checkedStamp.isExactType() == meetStamp.isExactType() && checkedStamp.alwaysNull() == meetStamp.alwaysNull()) {
assert checkedStamp.nonNull() != inputStamp.nonNull();
// The only difference makes the null-ness of the value => simplify the check.
if (checkedStamp.nonNull()) {
@@ -135,8 +139,8 @@
return IsNullNode.create(object);
}
}
+ assert checkedStamp.type() != null;
}
-
return null;
}
@@ -204,4 +208,13 @@
public AnchoringNode getAnchor() {
return anchor;
}
+
+ public ObjectStamp getCheckedStamp() {
+ return checkedStamp;
+ }
+
+ public void strengthenCheckedStamp(ObjectStamp newCheckedStamp) {
+ assert this.checkedStamp.join(newCheckedStamp).equals(newCheckedStamp) : "stamp can only improve";
+ this.checkedStamp = newCheckedStamp;
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadFieldNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadFieldNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -25,7 +25,6 @@
import static org.graalvm.compiler.graph.iterators.NodePredicates.isNotA;
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
-import jdk.vm.ci.meta.ConstantReflectionProvider;
import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.common.type.StampFactory;
@@ -47,15 +46,16 @@
import org.graalvm.compiler.nodes.util.ConstantFoldUtil;
import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode;
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
+import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.meta.Assumptions;
+import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.DeoptimizationAction;
import jdk.vm.ci.meta.DeoptimizationReason;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
-import org.graalvm.compiler.options.OptionValues;
/**
* The {@code LoadFieldNode} represents a read of a static or instance field.
@@ -150,7 +150,7 @@
}
public ConstantNode asConstant(CanonicalizerTool tool, JavaConstant constant) {
- return ConstantFoldUtil.tryConstantFold(tool.getConstantFieldProvider(), tool.getConstantReflection(), tool.getMetaAccess(), field(), constant, getOptions());
+ return ConstantFoldUtil.tryConstantFold(tool.getConstantFieldProvider(), tool.getConstantReflection(), tool.getMetaAccess(), field(), constant, tool.getOptions());
}
private static PhiNode asPhi(ConstantFieldProvider constantFields, ConstantReflectionProvider constantReflection,
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreFieldNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreFieldNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -29,7 +29,6 @@
import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodeinfo.NodeCycles;
import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.FrameState;
import org.graalvm.compiler.nodes.StateSplit;
import org.graalvm.compiler.nodes.ValueNode;
@@ -38,7 +37,6 @@
import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode;
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
-import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.ResolvedJavaField;
/**
@@ -90,15 +88,8 @@
VirtualInstanceNode virtual = (VirtualInstanceNode) alias;
int fieldIndex = virtual.fieldIndex(field());
if (fieldIndex != -1) {
- ValueNode existing = tool.getEntry((VirtualObjectNode) alias, fieldIndex);
- if (existing.stamp().isCompatible(value().stamp())) {
- tool.setVirtualEntry(virtual, fieldIndex, value(), false);
- tool.delete();
- } else {
- // stamp of the value is not compatible with the value in the virtualizer
- // can only happen with unsafe two slot writes on one slot fields
- assert existing instanceof ConstantNode && ((ConstantNode) existing).asConstant().equals(JavaConstant.forIllegal()) : value.stamp() + " vs " + existing.stamp();
- }
+ tool.setVirtualEntry(virtual, fieldIndex, value());
+ tool.delete();
}
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreIndexedNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreIndexedNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -89,7 +89,7 @@
ResolvedJavaType componentType = virtual.type().getComponentType();
if (componentType.isPrimitive() || StampTool.isPointerAlwaysNull(value) || componentType.getSuperclass() == null ||
(StampTool.typeReferenceOrNull(value) != null && componentType.isAssignableFrom(StampTool.typeOrNull(value)))) {
- tool.setVirtualEntry(virtual, idx, value(), false);
+ tool.setVirtualEntry(virtual, idx, value());
tool.delete();
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryPhiNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryPhiNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -62,4 +62,9 @@
public NodeInputList<ValueNode> values() {
return values;
}
+
+ @Override
+ protected String valueDescription() {
+ return locationIdentity.toString();
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/OffsetAddressNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/OffsetAddressNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,6 +22,7 @@
*/
package org.graalvm.compiler.nodes.memory.address;
+import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.graph.Node;
@@ -52,6 +53,9 @@
super(TYPE);
this.base = base;
this.offset = offset;
+
+ assert base != null && (base.stamp() instanceof AbstractPointerStamp || IntegerStamp.getBits(base.stamp()) == 64) &&
+ offset != null && IntegerStamp.getBits(offset.stamp()) == 64 : "both values must have 64 bits";
}
@Override
@@ -62,6 +66,7 @@
public void setBase(ValueNode base) {
updateUsages(this.base, base);
this.base = base;
+ assert base != null && (base.stamp() instanceof AbstractPointerStamp || IntegerStamp.getBits(base.stamp()) == 64);
}
public ValueNode getOffset() {
@@ -71,6 +76,7 @@
public void setOffset(ValueNode offset) {
updateUsages(this.offset, offset);
this.offset = offset;
+ assert offset != null && IntegerStamp.getBits(offset.stamp()) == 64;
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/VirtualizerTool.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/VirtualizerTool.java Wed Nov 08 16:03:35 2017 -0500
@@ -25,6 +25,7 @@
import java.util.List;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.java.MonitorIdNode;
@@ -91,9 +92,17 @@
*
* @param index the index to be set.
* @param value the new value for the given index.
- * @param unsafe if true, then mismatching value {@link JavaKind}s will be accepted.
+ * @param accessKind the kind of the store which might be different than
+ * {@link VirtualObjectNode#entryKind(int)}.
+ * @return true if the operation was permitted
*/
- void setVirtualEntry(VirtualObjectNode virtualObject, int index, ValueNode value, boolean unsafe);
+ boolean setVirtualEntry(VirtualObjectNode virtualObject, int index, ValueNode value, JavaKind accessKind, long offset);
+
+ default void setVirtualEntry(VirtualObjectNode virtualObject, int index, ValueNode value) {
+ if (!setVirtualEntry(virtualObject, index, value, null, 0)) {
+ throw new GraalError("unexpected failure when updating virtual entry");
+ }
+ }
ValueNode getEntry(VirtualObjectNode virtualObject, int index);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java Wed Nov 08 16:03:35 2017 -0500
@@ -242,7 +242,7 @@
EconomicSet<Node> collectedUnusedNodes = unusedNodes = EconomicSet.create(Equivalence.IDENTITY);
nodeEventScope = node.graph().trackNodeEvents(new Graph.NodeEventListener() {
@Override
- public void event(Graph.NodeEvent e, Node n) {
+ public void changed(Graph.NodeEvent e, Node n) {
if (e == Graph.NodeEvent.ZERO_USAGES && isFloatingNode(n) && !(n instanceof GuardNode)) {
collectedUnusedNodes.add(n);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/JavaConstantFormattable.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+package org.graalvm.compiler.nodes.util;
+
+/**
+ * Performs special formatting of values involving {@link jdk.vm.ci.meta.JavaConstant JavaConstants}
+ * when they are being dumped.
+ */
+public interface JavaConstantFormattable {
+ String format(JavaConstantFormatter formatter);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/JavaConstantFormatter.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+package org.graalvm.compiler.nodes.util;
+
+import jdk.vm.ci.meta.JavaConstant;
+
+public interface JavaConstantFormatter {
+ String format(JavaConstant constant);
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/VirtualArrayNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/VirtualArrayNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -37,7 +37,7 @@
import jdk.vm.ci.meta.ResolvedJavaType;
import sun.misc.Unsafe;
-@NodeInfo(nameTemplate = "VirtualArray {p#componentType/s}[{p#length}]")
+@NodeInfo(nameTemplate = "VirtualArray({p#objectId}) {p#componentType/s}[{p#length}]")
public class VirtualArrayNode extends VirtualObjectNode implements ArrayLengthProvider {
public static final NodeClass<VirtualArrayNode> TYPE = NodeClass.create(VirtualArrayNode.class);
@@ -76,7 +76,7 @@
@Override
public String toString(Verbosity verbosity) {
if (verbosity == Verbosity.Name) {
- return super.toString(Verbosity.Name) + " " + componentType.getName() + "[" + length + "]";
+ return super.toString(Verbosity.Name) + "(" + getObjectId() + ") " + componentType.getName() + "[" + length + "]";
} else {
return super.toString(verbosity);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/VirtualInstanceNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/VirtualInstanceNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -32,7 +32,7 @@
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaType;
-@NodeInfo(nameTemplate = "VirtualInstance {p#type/s}")
+@NodeInfo(nameTemplate = "VirtualInstance({p#objectId}) {p#type/s}")
public class VirtualInstanceNode extends VirtualObjectNode {
public static final NodeClass<VirtualInstanceNode> TYPE = NodeClass.create(VirtualInstanceNode.class);
@@ -78,7 +78,7 @@
@Override
public String toString(Verbosity verbosity) {
if (verbosity == Verbosity.Name) {
- return super.toString(Verbosity.Name) + " " + type.toJavaName(false);
+ return super.toString(Verbosity.Name) + "(" + getObjectId() + ") " + type.toJavaName(false);
} else {
return super.toString(verbosity);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.processor/src/org/graalvm/compiler/options/processor/OptionProcessor.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.processor/src/org/graalvm/compiler/options/processor/OptionProcessor.java Wed Nov 08 16:03:35 2017 -0500
@@ -394,6 +394,9 @@
options = new OptionsInfo(topDeclaringType);
map.put(topDeclaringType, options);
}
+ if (!element.getEnclosingElement().getSimpleName().toString().endsWith("Options")) {
+ processingEnv.getMessager().printMessage(Kind.ERROR, "Option declaring classes must have a name that ends with 'Options'", element.getEnclosingElement());
+ }
processElement(element, options);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java Wed Nov 08 16:03:35 2017 -0500
@@ -248,7 +248,7 @@
/**
* Tests which may be eliminated because post dominating tests to prove a broader condition.
*/
- private Deque<PendingTest> pendingTests;
+ private Deque<DeoptimizingGuard> pendingTests;
public Instance(StructuredGraph graph, BlockMap<List<Node>> blockToNodes, PhaseContext context) {
this.graph = graph;
@@ -555,7 +555,8 @@
}
}
if (guard instanceof DeoptimizingGuard) {
- pendingTests.push(new PendingTest(condition, (DeoptimizingGuard) guard));
+ assert ((DeoptimizingGuard) guard).getCondition() == condition;
+ pendingTests.push((DeoptimizingGuard) guard);
}
registerCondition(condition, negated, guard);
}
@@ -628,15 +629,16 @@
}
protected boolean foldPendingTest(DeoptimizingGuard thisGuard, ValueNode original, Stamp newStamp, GuardRewirer rewireGuardFunction) {
- for (PendingTest pending : pendingTests) {
+ for (DeoptimizingGuard pendingGuard : pendingTests) {
+ LogicNode pendingCondition = pendingGuard.getCondition();
TriState result = TriState.UNKNOWN;
- if (pending.condition instanceof UnaryOpLogicNode) {
- UnaryOpLogicNode unaryLogicNode = (UnaryOpLogicNode) pending.condition;
+ if (pendingCondition instanceof UnaryOpLogicNode) {
+ UnaryOpLogicNode unaryLogicNode = (UnaryOpLogicNode) pendingCondition;
if (unaryLogicNode.getValue() == original) {
result = unaryLogicNode.tryFold(newStamp);
}
- } else if (pending.condition instanceof BinaryOpLogicNode) {
- BinaryOpLogicNode binaryOpLogicNode = (BinaryOpLogicNode) pending.condition;
+ } else if (pendingCondition instanceof BinaryOpLogicNode) {
+ BinaryOpLogicNode binaryOpLogicNode = (BinaryOpLogicNode) pendingCondition;
ValueNode x = binaryOpLogicNode.getX();
ValueNode y = binaryOpLogicNode.getY();
if (x == original) {
@@ -659,7 +661,7 @@
*/
InputFilter v = new InputFilter(original);
thisGuard.getCondition().applyInputs(v);
- if (v.ok && foldGuard(thisGuard, pending.guard, newStamp, rewireGuardFunction)) {
+ if (v.ok && foldGuard(thisGuard, pendingGuard, newStamp, rewireGuardFunction)) {
return true;
}
}
@@ -1026,16 +1028,6 @@
boolean rewire(GuardingNode guard, boolean result, Stamp guardedValueStamp, ValueNode newInput);
}
- protected static class PendingTest {
- private final LogicNode condition;
- private final DeoptimizingGuard guard;
-
- public PendingTest(LogicNode condition, DeoptimizingGuard guard) {
- this.condition = condition;
- this.guard = guard;
- }
- }
-
protected static final class InfoElement {
private final Stamp stamp;
private final GuardingNode guard;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java Wed Nov 08 16:03:35 2017 -0500
@@ -221,7 +221,12 @@
EconomicMap<ValueNode, Stamp> endMap = endMaps.get(node);
MapCursor<ValueNode, Stamp> entries = endMap.getEntries();
while (entries.advance()) {
- if (registerNewValueStamp(entries.getKey(), entries.getValue())) {
+ ValueNode value = entries.getKey();
+ if (value.isDeleted()) {
+ // nodes from this map can be deleted when a loop dies
+ continue;
+ }
+ if (registerNewValueStamp(value, entries.getValue())) {
counterBetterMergedStamps.increment(debug);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ProfileCompiledMethodsPhase.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ProfileCompiledMethodsPhase.java Wed Nov 08 16:03:35 2017 -0500
@@ -48,7 +48,7 @@
import org.graalvm.compiler.nodes.VirtualState;
import org.graalvm.compiler.nodes.calc.BinaryNode;
import org.graalvm.compiler.nodes.calc.ConvertNode;
-import org.graalvm.compiler.nodes.calc.DivNode;
+import org.graalvm.compiler.nodes.calc.FloatDivNode;
import org.graalvm.compiler.nodes.calc.IntegerDivRemNode;
import org.graalvm.compiler.nodes.calc.MulNode;
import org.graalvm.compiler.nodes.calc.NotNode;
@@ -162,7 +162,7 @@
return 2;
} else if (node instanceof LogicNode || node instanceof ConvertNode || node instanceof BinaryNode || node instanceof NotNode) {
return 1;
- } else if (node instanceof IntegerDivRemNode || node instanceof DivNode || node instanceof RemNode) {
+ } else if (node instanceof IntegerDivRemNode || node instanceof FloatDivNode || node instanceof RemNode) {
return 10;
} else if (node instanceof MulNode) {
return 3;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/elem/InlineableGraph.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/elem/InlineableGraph.java Wed Nov 08 16:03:35 2017 -0500
@@ -43,7 +43,6 @@
import org.graalvm.compiler.phases.graph.FixedNodeProbabilityCache;
import org.graalvm.compiler.phases.tiers.HighTierContext;
-import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
@@ -159,11 +158,11 @@
if (param.usages().isNotEmpty()) {
ValueNode arg = args.get(param.index());
if (arg.isConstant()) {
- Constant constant = arg.asConstant();
+ ConstantNode constant = (ConstantNode) arg;
parameterUsages = trackParameterUsages(param, parameterUsages);
// collect param usages before replacing the param
param.replaceAtUsagesAndDelete(graph.unique(
- ConstantNode.forConstant(arg.stamp(), constant, ((ConstantNode) arg).getStableDimension(), ((ConstantNode) arg).isDefaultStable(), context.getMetaAccess())));
+ ConstantNode.forConstant(arg.stamp(), constant.getValue(), constant.getStableDimension(), constant.isDefaultStable(), context.getMetaAccess())));
// param-node gone, leaving a gap in the sequence given by param.index()
} else {
Stamp impro = improvedStamp(arg, param);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/util/HashSetNodeEventListener.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/util/HashSetNodeEventListener.java Wed Nov 08 16:03:35 2017 -0500
@@ -37,7 +37,7 @@
* A simple {@link NodeEventListener} implementation that accumulates event nodes in a
* {@link HashSet}.
*/
-public class HashSetNodeEventListener implements NodeEventListener {
+public class HashSetNodeEventListener extends NodeEventListener {
private final EconomicSet<Node> nodes;
private final Set<NodeEvent> filter;
@@ -68,7 +68,7 @@
}
@Override
- public void event(NodeEvent e, Node node) {
+ public void changed(NodeEvent e, Node node) {
if (filter.contains(e)) {
nodes.add(node);
if (node instanceof IndirectCanonicalization) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/BasePhase.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/BasePhase.java Wed Nov 08 16:03:35 2017 -0500
@@ -258,7 +258,7 @@
return false;
}
- private final class GraphChangeListener implements NodeEventListener {
+ private final class GraphChangeListener extends NodeEventListener {
boolean changed;
private StructuredGraph graph;
private Mark mark;
@@ -269,7 +269,7 @@
}
@Override
- public void event(NodeEvent e, Node node) {
+ public void changed(NodeEvent e, Node node) {
if (!graph.isNew(mark, node) && node.isAlive()) {
if (e == NodeEvent.INPUT_CHANGED || e == NodeEvent.ZERO_USAGES) {
changed = true;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/schedule/SchedulePhase.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/schedule/SchedulePhase.java Wed Nov 08 16:03:35 2017 -0500
@@ -109,7 +109,7 @@
if (immutableGraph && Assertions.assertionsEnabled()) {
return graph.trackNodeEvents(new NodeEventListener() {
@Override
- public void event(NodeEvent e, Node node) {
+ public void changed(NodeEvent e, Node node) {
assert false : "graph changed: " + e + " on node " + node;
}
});
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyGetOptionsUsage.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+package org.graalvm.compiler.phases.verify;
+
+import java.lang.reflect.MalformedParametersException;
+import java.lang.reflect.Method;
+
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.phases.VerifyPhase;
+import org.graalvm.compiler.phases.tiers.PhaseContext;
+
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+
+/**
+ * {@link Node#getOptions()} is unsafe for use during canonicalization so try to verify that it
+ * isn't used when a {@link CanonicalizerTool} is available in the arguments. This is slightly more
+ * general but since there are several canonical methods with varying signatures this covers more
+ * cases.
+ */
+public class VerifyGetOptionsUsage extends VerifyPhase<PhaseContext> {
+ static Method lookupMethod(Class<?> klass, String name) {
+ for (Method m : klass.getDeclaredMethods()) {
+ if (m.getName().equals(name)) {
+ return m;
+ }
+ }
+ throw new InternalError();
+ }
+
+ @Override
+ protected boolean verify(StructuredGraph graph, PhaseContext context) {
+ MetaAccessProvider metaAccess = context.getMetaAccess();
+ ResolvedJavaType canonicalizerToolClass = metaAccess.lookupJavaType(CanonicalizerTool.class);
+ boolean hasTool = false;
+ try {
+ for (ResolvedJavaMethod.Parameter parameter : graph.method().getParameters()) {
+ if (parameter.getType().getName().equals(canonicalizerToolClass.getName())) {
+ hasTool = true;
+ break;
+ }
+ }
+ } catch (MalformedParametersException e) {
+ // Lambdas sometimes have malformed parameters so ignore this.
+ }
+ if (hasTool) {
+ ResolvedJavaMethod getOptionsMethod = metaAccess.lookupJavaMethod(lookupMethod(Node.class, "getOptions"));
+ for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.TYPE)) {
+ ResolvedJavaMethod callee = t.targetMethod();
+ if (callee.equals(getOptionsMethod)) {
+ if (hasTool) {
+ throw new VerificationError("Must use CanonicalizerTool.getOptions() instead of Node.getOptions() in method '%s' of class '%s'.",
+ graph.method().getName(), graph.method().getDeclaringClass().getName());
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyGraphAddUsage.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+package org.graalvm.compiler.phases.verify;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import org.graalvm.compiler.debug.GraalError;
+import org.graalvm.compiler.graph.Graph;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.Invoke;
+import org.graalvm.compiler.nodes.ParameterNode;
+import org.graalvm.compiler.nodes.PiNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.ValuePhiNode;
+import org.graalvm.compiler.nodes.ValueProxyNode;
+import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.nodes.java.NewInstanceNode;
+import org.graalvm.compiler.nodes.spi.LoweringProvider;
+import org.graalvm.compiler.phases.VerifyPhase;
+import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.graalvm.util.EconomicSet;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+public class VerifyGraphAddUsage extends VerifyPhase<PhaseContext> {
+ private static final Method ADD_OR_UNIQUE;
+ private static final Method CONSTRUCTOR_NEW_INSTANCE;
+ private static final EconomicSet<Class<?>> ALLOWED_CLASSES = EconomicSet.create();
+
+ static {
+ try {
+ ADD_OR_UNIQUE = Graph.class.getDeclaredMethod("addOrUnique", Node.class);
+ CONSTRUCTOR_NEW_INSTANCE = Constructor.class.getDeclaredMethod("newInstance", Object[].class);
+ } catch (NoSuchMethodException e) {
+ throw new GraalError(e);
+ }
+
+ ALLOWED_CLASSES.add(Graph.class);
+ ALLOWED_CLASSES.add(LoweringProvider.class);
+ }
+
+ @Override
+ protected boolean verify(StructuredGraph graph, PhaseContext context) {
+ boolean allowed = false;
+ for (Class<?> cls : ALLOWED_CLASSES) {
+ ResolvedJavaType declaringClass = graph.method().getDeclaringClass();
+ if (context.getMetaAccess().lookupJavaType(cls).isAssignableFrom(declaringClass)) {
+ allowed = true;
+ }
+ }
+ if (!allowed) {
+ ResolvedJavaMethod addOrUniqueMethod = context.getMetaAccess().lookupJavaMethod(ADD_OR_UNIQUE);
+ for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.TYPE)) {
+ ResolvedJavaMethod callee = t.targetMethod();
+ if (callee.equals(addOrUniqueMethod)) {
+ ValueNode nodeArgument = t.arguments().get(1);
+ EconomicSet<Node> seen = EconomicSet.create();
+ checkNonFactory(graph, seen, context, nodeArgument);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private void checkNonFactory(StructuredGraph graph, EconomicSet<Node> seen, PhaseContext context, ValueNode node) {
+ if (seen.contains(node)) {
+ return;
+ }
+ seen.add(node);
+
+ // Check where the value came from recursively, or if it is allowed.
+ if (node instanceof ValuePhiNode) {
+ for (ValueNode input : ((ValuePhiNode) node).values()) {
+ checkNonFactory(graph, seen, context, input);
+ }
+ } else if (node instanceof PiNode) {
+ checkNonFactory(graph, seen, context, ((PiNode) node).object());
+ } else if (node instanceof ParameterNode) {
+ return;
+ } else if (node instanceof ConstantNode) {
+ return;
+ } else if (node instanceof ValueProxyNode) {
+ checkNonFactory(graph, seen, context, ((ValueProxyNode) node).value());
+ } else if (node instanceof Invoke && ((Invoke) node).callTarget().targetMethod().equals(context.getMetaAccess().lookupJavaMethod(CONSTRUCTOR_NEW_INSTANCE))) {
+ return;
+ } else if (!(node instanceof NewInstanceNode)) {
+ // In all other cases, the argument must be a new instance.
+ throw new VerificationError("Must add node '%s' with inputs in method '%s' of class '%s'.",
+ node, graph.method().getName(), graph.method().getDeclaringClass().getName());
+ }
+ }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BasicIdealGraphPrinter.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,366 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.printer;
-
-import java.io.BufferedOutputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.Charset;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Elementary, generic generator of Ideal Graph Visualizer input for use in printers for specific
- * data structures.
- */
-class BasicIdealGraphPrinter {
-
- /**
- * Edge between two nodes.
- */
- protected static class Edge {
-
- final String from;
- final int fromIndex;
- final String to;
- final int toIndex;
- final String label;
-
- public Edge(String from, int fromIndex, String to, int toIndex, String label) {
- assert (from != null && to != null);
- this.from = from;
- this.fromIndex = fromIndex;
- this.to = to;
- this.toIndex = toIndex;
- this.label = label;
- }
-
- @Override
- public int hashCode() {
- int h = from.hashCode() ^ to.hashCode();
- h = 3 * h + fromIndex;
- h = 5 * h + toIndex;
- if (label != null) {
- h ^= label.hashCode();
- }
- return h;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
- if (obj instanceof Edge) {
- Edge other = (Edge) obj;
- return from.equals(other.from) && fromIndex == other.fromIndex && to.equals(other.to) && toIndex == other.toIndex &&
- (label == other.label || (label != null && label.equals(other.label)));
- }
- return false;
- }
- }
-
- private final PrintStream stream;
-
- /**
- * Creates a new {@link IdealGraphPrinter} that writes to the specified output stream.
- */
- protected BasicIdealGraphPrinter(OutputStream stream) {
- try {
- OutputStream buffered;
- if (stream instanceof BufferedOutputStream) {
- buffered = stream;
- } else {
- buffered = new BufferedOutputStream(stream, 256 * 1024);
- }
- this.stream = new PrintStream(buffered, false, Charset.defaultCharset().name());
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Flushes any buffered output.
- */
- protected void flush() {
- stream.flush();
- }
-
- /**
- * Starts a new graph document.
- */
- protected void begin() {
- stream.println("<graphDocument>");
- }
-
- protected void beginGroup() {
- stream.println("<group>");
- }
-
- protected void beginMethod(String name, String shortName, int bci) {
- stream.printf(" <method name='%s' shortName='%s' bci='%d'>%n", escape(name), escape(shortName), bci);
- }
-
- protected void beginBytecodes() {
- stream.println(" <bytecodes>\n<![CDATA[");
- }
-
- protected void printBytecode(int bci, String mnemonic, int[] extra) {
- stream.print(bci);
- stream.print(' ');
- stream.print(mnemonic);
- if (extra != null) {
- for (int b : extra) {
- stream.print(' ');
- stream.print(b);
- }
- }
- stream.println();
- }
-
- protected void endBytecodes() {
- stream.println(" ]]></bytecodes>");
- }
-
- protected void printBytecodes(String disassembly) {
- beginBytecodes();
- stream.println(disassembly);
- endBytecodes();
- }
-
- protected void endMethod() {
- stream.println(" </method>");
- }
-
- protected void beginGraph(String title) {
- stream.printf(" <graph name='%s'>%n", escape(title));
- }
-
- protected void beginProperties() {
- stream.print("<properties>");
- }
-
- protected void printProperty(String name, String value) {
- stream.printf("<p name='%s'>%s</p>", escape(name), escape(value));
- }
-
- protected void endProperties() {
- stream.print("</properties>");
- }
-
- protected void printProperties(Map<String, String> properties) {
- beginProperties();
- for (Entry<String, String> entry : properties.entrySet()) {
- printProperty(entry.getKey(), entry.getValue());
- }
- endProperties();
- }
-
- protected void beginNodes() {
- stream.println(" <nodes>");
- }
-
- protected void beginNode(String id) {
- stream.printf(" <node id='%s'>", escape(id));
- }
-
- protected void endNode() {
- stream.println(" </node>");
- }
-
- protected void printNode(String id, Map<String, String> properties) {
- beginNode(id);
- if (properties != null) {
- printProperties(properties);
- }
- endNode();
- }
-
- protected void endNodes() {
- stream.println(" </nodes>");
- }
-
- protected void beginEdges() {
- stream.println(" <edges>");
- }
-
- protected void printEdge(Edge edge) {
- stream.printf(" <edge from='%s' fromIndex='%d' to='%s' toIndex='%d' label='%s' />%n", escape(edge.from), edge.fromIndex, escape(edge.to), edge.toIndex, escape(edge.label));
- }
-
- protected void endEdges() {
- stream.println(" </edges>");
- }
-
- protected void beginControlFlow() {
- stream.println(" <controlFlow>");
- }
-
- protected void beginBlock(String name) {
- stream.printf(" <block name='%s'>%n", escape(name));
- }
-
- protected void beginSuccessors() {
- stream.println(" <successors>");
- }
-
- protected void printSuccessor(String name) {
- stream.printf(" <successor name='%s'/>%n", escape(name));
- }
-
- protected void endSuccessors() {
- stream.println(" </successors>");
- }
-
- protected void beginBlockNodes() {
- stream.println(" <nodes>");
- }
-
- protected void printBlockNode(String nodeId) {
- stream.printf(" <node id='%s'/>%n", escape(nodeId));
- }
-
- protected void endBlockNodes() {
- stream.println(" </nodes>");
- }
-
- protected void endBlock() {
- stream.println(" </block>");
- }
-
- protected void endControlFlow() {
- stream.println(" </controlFlow>");
- }
-
- protected void endGraph() {
- stream.println(" </graph>");
- }
-
- /**
- * Ends the current group.
- */
- public void endGroup() {
- stream.println("</group>");
- }
-
- /**
- * Finishes the graph document and flushes the output stream.
- */
- protected void end() {
- stream.println("</graphDocument>");
- flush();
- }
-
- public void close() {
- end();
- stream.close();
- }
-
- public boolean isValid() {
- return !stream.checkError();
- }
-
- private static String escape(String s) {
- StringBuilder str = null;
- for (int i = 0; i < s.length(); i++) {
- char c = s.charAt(i);
- switch (c) {
- case '&':
- case '<':
- case '>':
- case '"':
- case '\'':
- if (str == null) {
- str = new StringBuilder();
- str.append(s, 0, i);
- }
- switch (c) {
- case '&':
- str.append("&");
- break;
- case '<':
- str.append("<");
- break;
- case '>':
- str.append(">");
- break;
- case '"':
- str.append(""");
- break;
- case '\'':
- str.append("'");
- break;
- default:
- assert false;
- }
- break;
- case '\u0000':
- case '\u0001':
- case '\u0002':
- case '\u0003':
- case '\u0004':
- case '\u0005':
- case '\u0006':
- case '\u0007':
- case '\u0008':
- case '\u000b':
- case '\u000c':
- case '\u000e':
- case '\u000f':
- case '\u0010':
- case '\u0011':
- case '\u0012':
- case '\u0013':
- case '\u0014':
- case '\u0015':
- case '\u0016':
- case '\u0017':
- case '\u0018':
- case '\u0019':
- case '\u001a':
- case '\u001b':
- case '\u001c':
- case '\u001d':
- case '\u001e':
- case '\u001f':
- if (str == null) {
- str = new StringBuilder();
- str.append(s, 0, i);
- }
- str.append("'0x").append(Integer.toHexString(c));
- break;
- default:
- if (str != null) {
- str.append(c);
- }
- break;
- }
- }
- if (str == null) {
- return s;
- } else {
- return str.toString();
- }
- }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java Wed Nov 08 16:03:35 2017 -0500
@@ -26,18 +26,17 @@
import static org.graalvm.compiler.graph.Edges.Type.Successors;
import java.io.IOException;
-import java.nio.channels.WritableByteChannel;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import jdk.vm.ci.meta.ResolvedJavaField;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.bytecode.Bytecode;
import org.graalvm.compiler.core.common.cfg.BlockMap;
+import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugOptions;
import org.graalvm.compiler.graph.CachedGraph;
import org.graalvm.compiler.graph.Edges;
@@ -46,6 +45,7 @@
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.NodeMap;
+import org.graalvm.compiler.graph.NodeSourcePosition;
import org.graalvm.compiler.nodes.AbstractBeginNode;
import org.graalvm.compiler.nodes.AbstractEndNode;
import org.graalvm.compiler.nodes.AbstractMergeNode;
@@ -55,15 +55,11 @@
import org.graalvm.compiler.nodes.FixedNode;
import org.graalvm.compiler.nodes.PhiNode;
import org.graalvm.compiler.nodes.ProxyNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.VirtualState;
import org.graalvm.compiler.nodes.cfg.Block;
import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.ResolvedJavaType;
-import jdk.vm.ci.meta.Signature;
-import org.graalvm.compiler.debug.DebugContext;
-import org.graalvm.compiler.graph.NodeSourcePosition;
-import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.util.JavaConstantFormattable;
import org.graalvm.compiler.phases.schedule.SchedulePhase;
import org.graalvm.graphio.GraphBlocks;
import org.graalvm.graphio.GraphElements;
@@ -71,6 +67,11 @@
import org.graalvm.graphio.GraphStructure;
import org.graalvm.graphio.GraphTypes;
+import jdk.vm.ci.meta.ResolvedJavaField;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.Signature;
+
public class BinaryGraphPrinter implements
GraphStructure<BinaryGraphPrinter.GraphInfo, Node, NodeClass<?>, Edges>,
GraphBlocks<BinaryGraphPrinter.GraphInfo, Block, Node>,
@@ -79,8 +80,8 @@
private final SnippetReflectionProvider snippetReflection;
private final GraphOutput<BinaryGraphPrinter.GraphInfo, ResolvedJavaMethod> output;
- public BinaryGraphPrinter(WritableByteChannel channel, SnippetReflectionProvider snippetReflection) throws IOException {
- this.output = GraphOutput.newBuilder(this).blocks(this).elements(this).types(this).build(channel);
+ public BinaryGraphPrinter(DebugContext ctx, SnippetReflectionProvider snippetReflection) throws IOException {
+ this.output = ctx.buildOutput(GraphOutput.newBuilder(this).protocolVersion(5, 0).blocks(this).elements(this).types(this));
this.snippetReflection = snippetReflection;
}
@@ -116,17 +117,24 @@
}
@Override
+ public Node node(Object obj) {
+ return obj instanceof Node ? (Node) obj : null;
+ }
+
+ @Override
public NodeClass<?> nodeClass(Object obj) {
if (obj instanceof NodeClass<?>) {
return (NodeClass<?>) obj;
}
- if (obj instanceof Node) {
- return ((Node) obj).getNodeClass();
- }
return null;
}
@Override
+ public NodeClass<?> classForNode(Node node) {
+ return node.getNodeClass();
+ }
+
+ @Override
public Object nodeClassType(NodeClass<?> node) {
return node.getJavaClass();
}
@@ -257,6 +265,13 @@
}
props.put("category", "floating");
}
+ if (getSnippetReflectionProvider() != null) {
+ for (Map.Entry<String, Object> prop : props.entrySet()) {
+ if (prop.getValue() instanceof JavaConstantFormattable) {
+ props.put(prop.getKey(), ((JavaConstantFormattable) prop.getValue()).format(this));
+ }
+ }
+ }
}
private Object getBlockForNode(Node node, NodeMap<Block> nodeToBlocks) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinterObserver.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinterObserver.java Wed Nov 08 16:03:35 2017 -0500
@@ -23,13 +23,13 @@
package org.graalvm.compiler.printer;
import static org.graalvm.compiler.debug.DebugOptions.PrintCFG;
-import static org.graalvm.compiler.printer.GraalDebugHandlersFactory.createDumpPath;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -153,8 +153,8 @@
if (cfgPrinter == null) {
try {
- Graph graph = debug.contextLookupTopdown(Graph.class);
- cfgFile = createDumpPath(options, graph, "cfg", false).toFile();
+ Path dumpFile = debug.getDumpPath(".cfg", false);
+ cfgFile = dumpFile.toFile();
OutputStream out = new BufferedOutputStream(new FileOutputStream(cfgFile));
cfgPrinter = new CFGPrinter(out);
} catch (IOException e) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CanonicalStringGraphPrinter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CanonicalStringGraphPrinter.java Wed Nov 08 16:03:35 2017 -0500
@@ -26,7 +26,6 @@
import static org.graalvm.compiler.debug.DebugOptions.CanonicalGraphStringsExcludeVirtuals;
import static org.graalvm.compiler.debug.DebugOptions.CanonicalGraphStringsRemoveIdentities;
import static org.graalvm.compiler.debug.DebugOptions.PrintCanonicalGraphStringFlavor;
-import static org.graalvm.compiler.printer.GraalDebugHandlersFactory.sanitizedFileName;
import java.io.BufferedWriter;
import java.io.FileWriter;
@@ -44,6 +43,7 @@
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.core.common.Fields;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.PathUtilities;
import org.graalvm.compiler.graph.Graph;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeMap;
@@ -260,11 +260,11 @@
private StructuredGraph currentGraph;
private Path currentDirectory;
- private Path getDirectory(StructuredGraph graph) throws IOException {
+ private Path getDirectory(DebugContext debug, StructuredGraph graph) {
if (graph == currentGraph) {
return currentDirectory;
}
- currentDirectory = GraalDebugHandlersFactory.createDumpPath(graph.getOptions(), graph, "graph-strings", true);
+ currentDirectory = debug.getDumpPath(".graph-strings", true);
currentGraph = graph;
return currentDirectory;
}
@@ -274,9 +274,9 @@
if (graph instanceof StructuredGraph) {
OptionValues options = graph.getOptions();
StructuredGraph structuredGraph = (StructuredGraph) graph;
- Path outDirectory = getDirectory(structuredGraph);
+ Path outDirectory = getDirectory(debug, structuredGraph);
String title = String.format("%03d-%s.txt", id, String.format(format, simplifyClassArgs(args)));
- Path filePath = outDirectory.resolve(sanitizedFileName(title));
+ Path filePath = outDirectory.resolve(PathUtilities.sanitizeFileName(title));
try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(filePath.toFile())))) {
switch (PrintCanonicalGraphStringFlavor.getValue(options)) {
case 1:
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraalDebugHandlersFactory.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraalDebugHandlersFactory.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,44 +22,18 @@
*/
package org.graalvm.compiler.printer;
-import static org.graalvm.compiler.debug.DebugOptions.PrintBinaryGraphPort;
-import static org.graalvm.compiler.debug.DebugOptions.PrintBinaryGraphs;
-import static org.graalvm.compiler.debug.DebugOptions.PrintGraphHost;
-import static org.graalvm.compiler.debug.DebugOptions.PrintXmlGraphPort;
-import static org.graalvm.compiler.debug.DebugOptions.ShowDumpFiles;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.nio.channels.ClosedByInterruptException;
-import java.nio.channels.FileChannel;
-import java.nio.channels.SocketChannel;
-import java.nio.file.FileAlreadyExistsException;
-import java.nio.file.Files;
-import java.nio.file.InvalidPathException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
-import org.graalvm.compiler.core.common.CompilationIdentifier;
-import org.graalvm.compiler.debug.Assertions;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugDumpHandler;
import org.graalvm.compiler.debug.DebugHandler;
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DebugOptions;
import org.graalvm.compiler.debug.TTY;
-import org.graalvm.compiler.debug.PathUtilities;
-import org.graalvm.compiler.graph.Graph;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.nodeinfo.Verbosity;
-import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.util.GraphUtil;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.serviceprovider.ServiceProvider;
@@ -80,17 +54,13 @@
@Override
public List<DebugHandler> createHandlers(OptionValues options) {
List<DebugHandler> handlers = new ArrayList<>();
- if (DebugOptions.PrintGraphFile.getValue(options)) {
- handlers.add(new GraphPrinterDumpHandler((graph) -> createFilePrinter(graph, options, snippetReflection)));
- } else {
- handlers.add(new GraphPrinterDumpHandler((graph) -> createNetworkPrinter(graph, options, snippetReflection)));
- }
+ handlers.add(new GraphPrinterDumpHandler((debug, graph) -> new BinaryGraphPrinter(debug, snippetReflection)));
if (DebugOptions.PrintCanonicalGraphStrings.getValue(options)) {
- handlers.add(new GraphPrinterDumpHandler((graph) -> createStringPrinter(snippetReflection)));
+ handlers.add(new GraphPrinterDumpHandler((debug, graph) -> createStringPrinter(snippetReflection)));
}
handlers.add(new NodeDumper());
if (DebugOptions.PrintCFG.getValue(options) || DebugOptions.PrintBackendCFG.getValue(options)) {
- if (DebugOptions.PrintBinaryGraphs.getValue(options) && DebugOptions.PrintCFG.getValue(options)) {
+ if (DebugOptions.PrintCFG.getValue(options)) {
TTY.out.println("Complete C1Visualizer dumping slows down PrintBinaryGraphs: use -Dgraal.PrintCFG=false to disable it");
}
handlers.add(new CFGPrinterObserver());
@@ -119,162 +89,4 @@
return new CanonicalStringGraphPrinter(snippetReflection);
}
- public static String sanitizedFileName(String n) {
- /*
- * First ensure that the name does not contain the directory separator (which would be
- * considered a valid path).
- */
- String name = n.replace(File.separatorChar, '_');
-
- try {
- Paths.get(name);
- return name;
- } catch (InvalidPathException e) {
- // fall through
- }
- StringBuilder buf = new StringBuilder(name.length());
- for (int i = 0; i < name.length(); i++) {
- char c = name.charAt(i);
- try {
- Paths.get(String.valueOf(c));
- } catch (InvalidPathException e) {
- buf.append('_');
- }
- buf.append(c);
- }
- return buf.toString();
- }
-
- private static GraphPrinter createNetworkPrinter(Graph graph, OptionValues options, SnippetReflectionProvider snippetReflection) throws IOException {
- String host = PrintGraphHost.getValue(options);
- int port = PrintBinaryGraphs.getValue(options) ? PrintBinaryGraphPort.getValue(options) : PrintXmlGraphPort.getValue(options);
- try {
- GraphPrinter printer;
- if (DebugOptions.PrintBinaryGraphs.getValue(options)) {
- printer = new BinaryGraphPrinter(SocketChannel.open(new InetSocketAddress(host, port)), snippetReflection);
- } else {
- printer = new IdealGraphPrinter(new Socket(host, port).getOutputStream(), true, snippetReflection);
- }
- TTY.println("Connected to the IGV on %s:%d", host, port);
- return printer;
- } catch (ClosedByInterruptException | InterruptedIOException e) {
- /*
- * Interrupts should not count as errors because they may be caused by a cancelled Graal
- * compilation. ClosedByInterruptException occurs if the SocketChannel could not be
- * opened. InterruptedIOException occurs if new Socket(..) was interrupted.
- */
- return null;
- } catch (IOException e) {
- if (!DebugOptions.PrintGraphFile.hasBeenSet(options)) {
- return createFilePrinter(graph, options, snippetReflection);
- } else {
- throw new IOException(String.format("Could not connect to the IGV on %s:%d", host, port), e);
- }
- }
- }
-
- private static final AtomicInteger unknownCompilationId = new AtomicInteger();
-
- /**
- * Creates a new file or directory for dumping based on a given graph and a file extension.
- *
- * @param graph a base path name is derived from {@code graph}
- * @param extension a suffix which if non-null and non-empty added to the end of the returned
- * path separated by a {@code "."}
- * @param createDirectory specifies if this is a request to create a directory instead of a file
- * @return the created directory or file
- * @throws IOException if there was an error creating the directory or file
- */
- static Path createDumpPath(OptionValues options, Graph graph, String extension, boolean createDirectory) throws IOException {
- CompilationIdentifier compilationId = CompilationIdentifier.INVALID_COMPILATION_ID;
- String id = null;
- String label = null;
- if (graph instanceof StructuredGraph) {
- StructuredGraph sgraph = (StructuredGraph) graph;
- label = getGraphName(sgraph);
- compilationId = sgraph.compilationId();
- if (compilationId == CompilationIdentifier.INVALID_COMPILATION_ID) {
- id = graph.getClass().getSimpleName() + "-" + sgraph.graphId();
- } else {
- id = compilationId.toString(CompilationIdentifier.Verbosity.ID);
- }
- } else {
- label = graph == null ? null : graph.name != null ? graph.name : graph.toString();
- id = "UnknownCompilation-" + unknownCompilationId.incrementAndGet();
- }
- String ext = PathUtilities.formatExtension(extension);
- Path result = createUnique(DebugOptions.getDumpDirectory(options), id, label, ext, createDirectory);
- if (ShowDumpFiles.getValue(options) || Assertions.assertionsEnabled()) {
- TTY.println("Dumping debug output to %s", result.toAbsolutePath().toString());
- }
- return result;
- }
-
- /**
- * A maximum file name length supported by most file systems. There is no platform independent
- * way to get this in Java.
- */
- private static final int MAX_FILE_NAME_LENGTH = 255;
-
- private static final String ELLIPSIS = "...";
-
- private static Path createUnique(Path dumpDir, String id, String label, String ext, boolean createDirectory) throws IOException {
- String timestamp = "";
- for (;;) {
- int fileNameLengthWithoutLabel = timestamp.length() + ext.length() + id.length() + "[]".length();
- int labelLengthLimit = MAX_FILE_NAME_LENGTH - fileNameLengthWithoutLabel;
- String fileName;
- if (labelLengthLimit < ELLIPSIS.length()) {
- // This means `id` is very long
- String suffix = timestamp + ext;
- int idLengthLimit = Math.min(MAX_FILE_NAME_LENGTH - suffix.length(), id.length());
- fileName = sanitizedFileName(id.substring(0, idLengthLimit) + suffix);
- } else {
- if (label == null) {
- fileName = sanitizedFileName(id + timestamp + ext);
- } else {
- String adjustedLabel = label;
- if (label.length() > labelLengthLimit) {
- adjustedLabel = label.substring(0, labelLengthLimit - ELLIPSIS.length()) + ELLIPSIS;
- }
- fileName = sanitizedFileName(id + '[' + adjustedLabel + ']' + timestamp + ext);
- }
- }
- Path result = dumpDir.resolve(fileName);
- try {
- if (createDirectory) {
- return Files.createDirectory(result);
- } else {
- return Files.createFile(result);
- }
- } catch (FileAlreadyExistsException e) {
- timestamp = "_" + Long.toString(System.currentTimeMillis());
- }
- }
- }
-
- private static String getGraphName(StructuredGraph graph) {
- if (graph.name != null) {
- return graph.name;
- } else if (graph.method() != null) {
- return graph.method().format("%h.%n(%p)").replace(" ", "");
- } else {
- return graph.toString();
- }
- }
-
- private static GraphPrinter createFilePrinter(Graph graph, OptionValues options, SnippetReflectionProvider snippetReflection) throws IOException {
- Path path = createDumpPath(options, graph, PrintBinaryGraphs.getValue(options) ? "bgv" : "gv.xml", false);
- try {
- GraphPrinter printer;
- if (DebugOptions.PrintBinaryGraphs.getValue(options)) {
- printer = new BinaryGraphPrinter(FileChannel.open(path, StandardOpenOption.WRITE), snippetReflection);
- } else {
- printer = new IdealGraphPrinter(Files.newOutputStream(path), true, snippetReflection);
- }
- return printer;
- } catch (IOException e) {
- throw new IOException(String.format("Failed to open %s to dump IGV graphs", path), e);
- }
- }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java Wed Nov 08 16:03:35 2017 -0500
@@ -35,6 +35,7 @@
import org.graalvm.compiler.graph.Graph;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.util.JavaConstantFormatter;
import org.graalvm.compiler.phases.schedule.SchedulePhase;
import org.graalvm.compiler.serviceprovider.JDK9Method;
@@ -46,7 +47,7 @@
import jdk.vm.ci.runtime.JVMCI;
import jdk.vm.ci.services.Services;
-interface GraphPrinter extends Closeable {
+interface GraphPrinter extends Closeable, JavaConstantFormatter {
/**
* Starts a new group of graphs with the given name, short name and method byte code index (BCI)
@@ -116,30 +117,44 @@
return true;
}
}
+ if (c.getClassLoader() == GraphPrinter.class.getClassLoader()) {
+ return true;
+ }
return false;
}
/**
+ * Use the real {@link Object#toString()} method for {@link JavaConstant JavaConstants} that are
+ * wrapping trusted types, other just return the results of {@link JavaConstant#toString()}.
+ */
+ @Override
+ default String format(JavaConstant constant) {
+ SnippetReflectionProvider snippetReflection = getSnippetReflectionProvider();
+ if (snippetReflection != null) {
+ if (constant.getJavaKind() == JavaKind.Object) {
+ Object obj = snippetReflection.asObject(Object.class, constant);
+ if (obj != null) {
+ return GraphPrinter.constantToString(obj);
+ }
+ }
+ }
+ return constant.toString();
+ }
+
+ /**
* Sets or updates the {@code "rawvalue"} and {@code "toString"} properties in {@code props} for
* {@code cn} if it's a boxed Object value and {@code snippetReflection} can access the raw
* value.
*/
default void updateStringPropertiesForConstant(Map<Object, Object> props, ConstantNode cn) {
- SnippetReflectionProvider snippetReflection = getSnippetReflectionProvider();
- if (snippetReflection != null && cn.getValue() instanceof JavaConstant) {
- JavaConstant constant = (JavaConstant) cn.getValue();
- if (constant.getJavaKind() == JavaKind.Object) {
- Object obj = snippetReflection.asObject(Object.class, constant);
- if (obj != null) {
- String toString = GraphPrinter.constantToString(obj);
- String rawvalue = GraphPrinter.truncate(toString);
- // Overwrite the value inserted by
- // ConstantNode.getDebugProperties()
- props.put("rawvalue", rawvalue);
- if (!rawvalue.equals(toString)) {
- props.put("toString", toString);
- }
- }
+ if (cn.isJavaConstant() && cn.getStackKind().isObject()) {
+ String toString = format(cn.asJavaConstant());
+ String rawvalue = GraphPrinter.truncate(toString);
+ // Overwrite the value inserted by
+ // ConstantNode.getDebugProperties()
+ props.put("rawvalue", rawvalue);
+ if (!rawvalue.equals(toString)) {
+ props.put("toString", toString);
}
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java Wed Nov 08 16:03:35 2017 -0500
@@ -52,8 +52,8 @@
//JaCoCo Exclude
/**
- * Observes compilation events and uses {@link IdealGraphPrinter} to generate a graph representation
- * that can be inspected with the Graph Visualizer.
+ * Observes compilation events and uses {@link BinaryGraphPrinter} to generate a graph
+ * representation that can be inspected with the Graph Visualizer.
*/
public class GraphPrinterDumpHandler implements DebugDumpHandler {
@@ -69,7 +69,7 @@
@FunctionalInterface
public interface GraphPrinterSupplier {
- GraphPrinter get(Graph graph) throws IOException;
+ GraphPrinter get(DebugContext ctx, Graph graph) throws IOException;
}
/**
@@ -93,7 +93,7 @@
}
}
- private void ensureInitialized(Graph graph) {
+ private void ensureInitialized(DebugContext ctx, Graph graph) {
if (printer == null) {
if (failuresCount >= FAILURE_LIMIT) {
return;
@@ -102,7 +102,7 @@
inlineContextMap = new WeakHashMap<>();
DebugContext debug = graph.getDebug();
try {
- printer = printerSupplier.get(graph);
+ printer = printerSupplier.get(ctx, graph);
} catch (IOException e) {
handleException(debug, e);
}
@@ -123,7 +123,7 @@
OptionValues options = debug.getOptions();
if (object instanceof Graph && DebugOptions.PrintGraph.getValue(options)) {
final Graph graph = (Graph) object;
- ensureInitialized(graph);
+ ensureInitialized(debug, graph);
if (printer == null) {
return;
}
@@ -168,11 +168,13 @@
// Save inline context for next dump.
previousInlineContext = inlineContext;
+ // Capture before creating the sandbox
+ String currentScopeName = debug.getCurrentScopeName();
try (DebugContext.Scope s = debug.sandbox("PrintingGraph", null)) {
// Finally, output the graph.
Map<Object, Object> properties = new HashMap<>();
properties.put("graph", graph.toString());
- properties.put("scope", debug.getCurrentScopeName());
+ properties.put("scope", currentScopeName);
if (graph instanceof StructuredGraph) {
properties.put("compilationIdentifier", ((StructuredGraph) graph).compilationId());
try {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/IdealGraphPrinter.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,356 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.printer;
-
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
-import org.graalvm.compiler.bytecode.BytecodeDisassembler;
-import org.graalvm.compiler.debug.DebugContext;
-import org.graalvm.compiler.debug.DebugOptions;
-import org.graalvm.compiler.graph.Graph;
-import org.graalvm.compiler.graph.Node;
-import org.graalvm.compiler.graph.NodeMap;
-import org.graalvm.compiler.graph.Position;
-import org.graalvm.compiler.nodeinfo.Verbosity;
-import org.graalvm.compiler.nodes.AbstractMergeNode;
-import org.graalvm.compiler.nodes.BeginNode;
-import org.graalvm.compiler.nodes.ConstantNode;
-import org.graalvm.compiler.nodes.EndNode;
-import org.graalvm.compiler.nodes.ParameterNode;
-import org.graalvm.compiler.nodes.PhiNode;
-import org.graalvm.compiler.nodes.StateSplit;
-import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
-import org.graalvm.compiler.nodes.cfg.Block;
-import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
-import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.phases.schedule.SchedulePhase;
-import org.graalvm.util.EconomicSet;
-import org.graalvm.util.Equivalence;
-
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-
-/**
- * Generates a representation of {@link Graph Graphs} that can be visualized and inspected with the
- * <a href="http://kenai.com/projects/igv">Ideal Graph Visualizer</a>.
- */
-public class IdealGraphPrinter extends BasicIdealGraphPrinter implements GraphPrinter {
-
- private final boolean tryToSchedule;
- private final SnippetReflectionProvider snippetReflection;
-
- /**
- * Creates a new {@link IdealGraphPrinter} that writes to the specified output stream.
- *
- * @param tryToSchedule If false, no scheduling is done, which avoids exceptions for
- * non-schedulable graphs.
- */
- public IdealGraphPrinter(OutputStream stream, boolean tryToSchedule, SnippetReflectionProvider snippetReflection) {
- super(stream);
- this.snippetReflection = snippetReflection;
- this.begin();
- this.tryToSchedule = tryToSchedule;
- }
-
- @Override
- public SnippetReflectionProvider getSnippetReflectionProvider() {
- return snippetReflection;
- }
-
- /**
- * Starts a new group of graphs with the given name, short name and method byte code index (BCI)
- * as properties.
- */
- @Override
- public void beginGroup(DebugContext debug, String name, String shortName, ResolvedJavaMethod method, int bci, Map<Object, Object> properties) {
- beginGroup();
- beginProperties();
- printProperty("name", name);
- if (properties != null) {
- for (Entry<Object, Object> entry : properties.entrySet()) {
- printProperty(entry.getKey().toString(), entry.getValue().toString());
- }
- }
- endProperties();
- beginMethod(name, shortName, bci);
- if (method != null && method.getCode() != null) {
- printBytecodes(new BytecodeDisassembler(false).disassemble(method));
- }
- endMethod();
- }
-
- /**
- * Prints an entire {@link Graph} with the specified title, optionally using short names for
- * nodes.
- */
- @Override
- public void print(DebugContext debug, Graph graph, Map<Object, Object> properties, int id, String format, Object... args) {
- String title = id + ": " + String.format(format, simplifyClassArgs(args));
- beginGraph(title);
- EconomicSet<Node> noBlockNodes = EconomicSet.create(Equivalence.IDENTITY);
- ScheduleResult schedule = null;
- if (graph instanceof StructuredGraph) {
- StructuredGraph structuredGraph = (StructuredGraph) graph;
- schedule = structuredGraph.getLastSchedule();
- if (schedule == null && tryToSchedule) {
- OptionValues options = graph.getOptions();
- if (DebugOptions.PrintGraphWithSchedule.getValue(options)) {
- try {
- SchedulePhase schedulePhase = new SchedulePhase(options);
- schedulePhase.apply(structuredGraph);
- schedule = structuredGraph.getLastSchedule();
- } catch (Throwable t) {
- }
- }
- }
- }
- ControlFlowGraph cfg = schedule == null ? null : schedule.getCFG();
-
- if (properties != null) {
- beginProperties();
- for (Entry<Object, Object> entry : properties.entrySet()) {
- printProperty(entry.getKey().toString(), entry.getValue().toString());
- }
- endProperties();
- }
-
- beginNodes();
- List<Edge> edges = printNodes(graph, cfg == null ? null : cfg.getNodeToBlock(), noBlockNodes);
- endNodes();
-
- beginEdges();
- for (Edge edge : edges) {
- printEdge(edge);
- }
- endEdges();
-
- if (cfg != null && cfg.getBlocks() != null) {
- beginControlFlow();
- for (Block block : cfg.getBlocks()) {
- printBlock(graph, block, cfg.getNodeToBlock());
- }
- printNoBlock(noBlockNodes);
- endControlFlow();
- }
-
- endGraph();
- flush();
- }
-
- private List<Edge> printNodes(Graph graph, NodeMap<Block> nodeToBlock, EconomicSet<Node> noBlockNodes) {
- ArrayList<Edge> edges = new ArrayList<>();
-
- NodeMap<Set<Entry<String, Integer>>> colors = graph.createNodeMap();
- NodeMap<Set<Entry<String, String>>> colorsToString = graph.createNodeMap();
- NodeMap<Set<String>> bits = graph.createNodeMap();
-
- for (Node node : graph.getNodes()) {
-
- beginNode(node.toString(Verbosity.Id));
- beginProperties();
- printProperty("idx", node.toString(Verbosity.Id));
-
- Map<Object, Object> props = node.getDebugProperties();
- if (!props.containsKey("name") || props.get("name").toString().trim().length() == 0) {
- String name = node.toString(Verbosity.Name);
- printProperty("name", name);
- }
- printProperty("class", node.getClass().getSimpleName());
-
- Block block = nodeToBlock == null || nodeToBlock.isNew(node) ? null : nodeToBlock.get(node);
- if (block != null) {
- printProperty("block", Integer.toString(block.getId()));
- // if (!(node instanceof PhiNode || node instanceof FrameState || node instanceof
- // ParameterNode) && !block.nodes().contains(node)) {
- // printProperty("notInOwnBlock", "true");
- // }
- } else {
- printProperty("block", "noBlock");
- noBlockNodes.add(node);
- }
-
- Set<Entry<String, Integer>> nodeColors = colors.get(node);
- if (nodeColors != null) {
- for (Entry<String, Integer> color : nodeColors) {
- String name = color.getKey();
- Integer value = color.getValue();
- printProperty(name, Integer.toString(value));
- }
- }
- Set<Entry<String, String>> nodeColorStrings = colorsToString.get(node);
- if (nodeColorStrings != null) {
- for (Entry<String, String> color : nodeColorStrings) {
- String name = color.getKey();
- String value = color.getValue();
- printProperty(name, value);
- }
- }
- Set<String> nodeBits = bits.get(node);
- if (nodeBits != null) {
- for (String bit : nodeBits) {
- printProperty(bit, "true");
- }
- }
- if (node instanceof BeginNode) {
- printProperty("shortName", "B");
- } else if (node.getClass() == EndNode.class) {
- printProperty("shortName", "E");
- } else if (node instanceof ConstantNode) {
- ConstantNode cn = (ConstantNode) node;
- updateStringPropertiesForConstant(props, cn);
- }
- if (node.predecessor() != null) {
- printProperty("hasPredecessor", "true");
- }
-
- try {
- printProperty("NodeCost-Size", node.estimatedNodeSize().toString());
- printProperty("NodeCost-Cycles", node.estimatedNodeCycles().toString());
- } catch (Throwable t) {
- props.put("node-cost-exception", t.getMessage());
- }
-
- for (Entry<Object, Object> entry : props.entrySet()) {
- String key = entry.getKey().toString();
- Object value = entry.getValue();
- String valueString;
- if (value == null) {
- valueString = "null";
- } else {
- Class<?> type = value.getClass();
- if (type.isArray()) {
- if (!type.getComponentType().isPrimitive()) {
- valueString = Arrays.toString((Object[]) value);
- } else if (type.getComponentType() == Integer.TYPE) {
- valueString = Arrays.toString((int[]) value);
- } else if (type.getComponentType() == Double.TYPE) {
- valueString = Arrays.toString((double[]) value);
- } else {
- valueString = toString();
- }
- } else {
- valueString = value.toString();
- }
- }
- printProperty(key, valueString);
- }
-
- endProperties();
- endNode();
-
- // successors
- int fromIndex = 0;
- for (Position position : node.successorPositions()) {
- Node successor = position.get(node);
- if (successor != null) {
- edges.add(new Edge(node.toString(Verbosity.Id), fromIndex, successor.toString(Verbosity.Id), 0, position.getName()));
- }
- fromIndex++;
- }
-
- // inputs
- int toIndex = 1;
- for (Position position : node.inputPositions()) {
- Node input = position.get(node);
- if (input != null) {
- edges.add(new Edge(input.toString(Verbosity.Id), input.successors().count(), node.toString(Verbosity.Id), toIndex, position.getName()));
- }
- toIndex++;
- }
- }
-
- return edges;
- }
-
- private void printBlock(Graph graph, Block block, NodeMap<Block> nodeToBlock) {
- beginBlock(Integer.toString(block.getId()));
- beginSuccessors();
- for (Block sux : block.getSuccessors()) {
- if (sux != null) {
- printSuccessor(Integer.toString(sux.getId()));
- }
- }
- endSuccessors();
- beginBlockNodes();
-
- EconomicSet<Node> nodes = EconomicSet.create(Equivalence.IDENTITY);
-
- if (nodeToBlock != null) {
- for (Node n : graph.getNodes()) {
- Block blk = nodeToBlock.isNew(n) ? null : nodeToBlock.get(n);
- if (blk == block) {
- nodes.add(n);
- }
- }
- }
-
- if (nodes.size() > 0) {
- // if this is the first block: add all locals to this block
- if (block.getBeginNode() == ((StructuredGraph) graph).start()) {
- for (Node node : graph.getNodes()) {
- if (node instanceof ParameterNode) {
- nodes.add(node);
- }
- }
- }
-
- EconomicSet<Node> snapshot = EconomicSet.create(Equivalence.IDENTITY, nodes);
- // add all framestates and phis to their blocks
- for (Node node : snapshot) {
- if (node instanceof StateSplit && ((StateSplit) node).stateAfter() != null) {
- nodes.add(((StateSplit) node).stateAfter());
- }
- if (node instanceof AbstractMergeNode) {
- for (PhiNode phi : ((AbstractMergeNode) node).phis()) {
- nodes.add(phi);
- }
- }
- }
-
- for (Node node : nodes) {
- printBlockNode(node.toString(Verbosity.Id));
- }
- }
- endBlockNodes();
- endBlock();
- }
-
- private void printNoBlock(EconomicSet<Node> noBlockNodes) {
- if (!noBlockNodes.isEmpty()) {
- beginBlock("noBlock");
- beginBlockNodes();
- for (Node node : noBlockNodes) {
- printBlockNode(node.toString(Verbosity.Id));
- }
- endBlockNodes();
- endBlock();
- }
- }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringIndexOfNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringIndexOfNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,13 +22,13 @@
*/
package org.graalvm.compiler.replacements.amd64;
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_256;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.NodeInputList;
import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodeinfo.NodeCycles;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.NamedLocationIdentity;
@@ -44,7 +44,7 @@
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.Value;
-@NodeInfo(size = SIZE_64, cycles = CYCLES_256)
+@NodeInfo(size = SIZE_64, cycles = NodeCycles.CYCLES_UNKNOWN)
public class AMD64StringIndexOfNode extends FixedWithNextNode implements LIRLowerable, MemoryAccess {
public static final NodeClass<AMD64StringIndexOfNode> TYPE = NodeClass.create(AMD64StringIndexOfNode.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantBindingParameterPlugin.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantBindingParameterPlugin.java Wed Nov 08 16:03:35 2017 -0500
@@ -63,7 +63,7 @@
* This is a node from another graph, so copy over extra state into a new
* ConstantNode.
*/
- constantNode = ConstantNode.forConstant(stamp.getTrustedStamp(), otherCon.asConstant(), otherCon.getStableDimension(), otherCon.isDefaultStable(), metaAccess);
+ constantNode = ConstantNode.forConstant(stamp.getTrustedStamp(), otherCon.getValue(), otherCon.getStableDimension(), otherCon.isDefaultStable(), metaAccess);
} else {
constantNode = otherCon;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java Wed Nov 08 16:03:35 2017 -0500
@@ -33,6 +33,7 @@
import static org.graalvm.compiler.nodes.java.ArrayLengthNode.readArrayLength;
import static org.graalvm.compiler.nodes.util.GraphUtil.skipPiWhileNonNull;
+import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
@@ -43,6 +44,7 @@
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.core.common.type.ObjectStamp;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.core.common.type.TypeReference;
@@ -50,6 +52,7 @@
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodes.CompressionNode.CompressionOp;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.FieldLocationIdentity;
import org.graalvm.compiler.nodes.FixedNode;
@@ -69,6 +72,7 @@
import org.graalvm.compiler.nodes.calc.RightShiftNode;
import org.graalvm.compiler.nodes.calc.SignExtendNode;
import org.graalvm.compiler.nodes.calc.SubNode;
+import org.graalvm.compiler.nodes.calc.UnpackEndianHalfNode;
import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
import org.graalvm.compiler.nodes.debug.VerifyHeapNode;
import org.graalvm.compiler.nodes.extended.BoxNode;
@@ -150,14 +154,16 @@
protected final MetaAccessProvider metaAccess;
protected final ForeignCallsProvider foreignCalls;
protected final TargetDescription target;
+ private final boolean useCompressedOops;
private BoxingSnippets.Templates boxingSnippets;
private ConstantStringIndexOfSnippets.Templates indexOfSnippets;
- public DefaultJavaLoweringProvider(MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, TargetDescription target) {
+ public DefaultJavaLoweringProvider(MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, TargetDescription target, boolean useCompressedOops) {
this.metaAccess = metaAccess;
this.foreignCalls = foreignCalls;
this.target = target;
+ this.useCompressedOops = useCompressedOops;
}
public void initialize(OptionValues options, Iterable<DebugHandlersFactory> factories, SnippetCounter.Group.Factory factory, Providers providers, SnippetReflectionProvider snippetReflection) {
@@ -218,11 +224,18 @@
lowerBinaryMath((BinaryMathIntrinsicNode) n, tool);
} else if (n instanceof StringIndexOfNode) {
lowerIndexOf((StringIndexOfNode) n);
+ } else if (n instanceof UnpackEndianHalfNode) {
+ lowerSecondHalf((UnpackEndianHalfNode) n);
} else {
throw GraalError.shouldNotReachHere("Node implementing Lowerable not handled: " + n);
}
}
+ private void lowerSecondHalf(UnpackEndianHalfNode n) {
+ ByteOrder byteOrder = target.arch.getByteOrder();
+ n.lower(byteOrder);
+ }
+
private void lowerIndexOf(StringIndexOfNode n) {
if (n.getArgument(3).isConstant()) {
SnippetLowering lowering = new SnippetLowering() {
@@ -326,19 +339,21 @@
}
}
+ protected abstract JavaKind getStorageKind(ResolvedJavaField field);
+
protected void lowerLoadFieldNode(LoadFieldNode loadField, LoweringTool tool) {
assert loadField.getStackKind() != JavaKind.Illegal;
StructuredGraph graph = loadField.graph();
ResolvedJavaField field = loadField.field();
ValueNode object = loadField.isStatic() ? staticFieldBase(graph, field) : loadField.object();
object = createNullCheckedValue(object, loadField, tool);
- Stamp loadStamp = loadStamp(loadField.stamp(), field.getJavaKind());
+ Stamp loadStamp = loadStamp(loadField.stamp(), getStorageKind(field));
AddressNode address = createFieldAddress(graph, object, field);
assert address != null : "Field that is loaded must not be eliminated: " + field.getDeclaringClass().toJavaName(true) + "." + field.getName();
ReadNode memoryRead = graph.add(new ReadNode(address, fieldLocationIdentity(field), loadStamp, fieldLoadBarrierType(field)));
- ValueNode readValue = implicitLoadConvert(graph, field.getJavaKind(), memoryRead);
+ ValueNode readValue = implicitLoadConvert(graph, getStorageKind(field), memoryRead);
loadField.replaceAtUsages(readValue);
graph.replaceFixed(loadField, memoryRead);
@@ -355,7 +370,7 @@
ResolvedJavaField field = storeField.field();
ValueNode object = storeField.isStatic() ? staticFieldBase(graph, field) : storeField.object();
object = createNullCheckedValue(object, storeField, tool);
- ValueNode value = implicitStoreConvert(graph, storeField.field().getJavaKind(), storeField.value());
+ ValueNode value = implicitStoreConvert(graph, getStorageKind(storeField.field()), storeField.value());
AddressNode address = createFieldAddress(graph, object, field);
assert address != null;
@@ -651,9 +666,7 @@
protected void lowerJavaWriteNode(JavaWriteNode write) {
StructuredGraph graph = write.graph();
- JavaKind valueKind = write.getWriteKind();
- ValueNode value = implicitStoreConvert(graph, valueKind, write.value(), write.isCompressible());
-
+ ValueNode value = implicitStoreConvert(graph, write.getWriteKind(), write.value(), write.isCompressible());
WriteNode memoryWrite = graph.add(new WriteNode(write.getAddress(), write.getLocationIdentity(), value, write.getBarrierType()));
memoryWrite.setStateAfter(write.stateAfter());
graph.replaceFixedWithFixed(write, memoryWrite);
@@ -918,10 +931,20 @@
return loadStamp(stamp, kind, true);
}
+ private boolean useCompressedOops(JavaKind kind, boolean compressible) {
+ return kind == JavaKind.Object && compressible && useCompressedOops;
+ }
+
+ protected abstract Stamp loadCompressedStamp(ObjectStamp stamp);
+
/**
* @param compressible whether the stamp should be compressible
*/
protected Stamp loadStamp(Stamp stamp, JavaKind kind, boolean compressible) {
+ if (useCompressedOops(kind, compressible)) {
+ return loadCompressedStamp((ObjectStamp) stamp);
+ }
+
switch (kind) {
case Boolean:
case Byte:
@@ -949,10 +972,16 @@
return ret;
}
+ protected abstract ValueNode newCompressionNode(CompressionOp op, ValueNode value);
+
/**
- * @param compressible whether the covert should be compressible
+ * @param compressible whether the convert should be compressible
*/
protected ValueNode implicitLoadConvert(JavaKind kind, ValueNode value, boolean compressible) {
+ if (useCompressedOops(kind, compressible)) {
+ return newCompressionNode(CompressionOp.Uncompress, value);
+ }
+
switch (kind) {
case Byte:
case Short:
@@ -984,6 +1013,10 @@
* @param compressible whether the covert should be compressible
*/
protected ValueNode implicitStoreConvert(JavaKind kind, ValueNode value, boolean compressible) {
+ if (useCompressedOops(kind, compressible)) {
+ return newCompressionNode(CompressionOp.Compress, value);
+ }
+
switch (kind) {
case Boolean:
case Byte:
@@ -1011,9 +1044,8 @@
LogicNode boundsCheck = IntegerBelowNode.create(n.index(), arrayLength);
if (boundsCheck.isTautology()) {
return null;
- } else {
- return tool.createGuard(n, graph.addOrUniqueWithInputs(boundsCheck), BoundsCheckException, InvalidateReprofile);
}
+ return tool.createGuard(n, graph.addOrUniqueWithInputs(boundsCheck), BoundsCheckException, InvalidateReprofile);
}
protected GuardingNode createNullCheck(ValueNode object, FixedNode before, LoweringTool tool) {
@@ -1027,9 +1059,8 @@
GuardingNode nullCheck = createNullCheck(object, before, tool);
if (nullCheck == null) {
return object;
- } else {
- return before.graph().maybeAddOrUnique(PiNode.create(object, (object.stamp()).join(StampFactory.objectNonNull()), (ValueNode) nullCheck));
}
+ return before.graph().maybeAddOrUnique(PiNode.create(object, (object.stamp()).join(StampFactory.objectNonNull()), (ValueNode) nullCheck));
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java Wed Nov 08 16:03:35 2017 -0500
@@ -75,7 +75,6 @@
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.Signature;
/**
@@ -252,6 +251,10 @@
return new MethodCallTargetNode(invokeKind, targetMethod, args, returnStamp, null);
}
+ protected final JavaKind asKind(JavaType type) {
+ return wordTypes != null ? wordTypes.asKind(type) : type.getJavaKind();
+ }
+
/**
* Determines if a given set of arguments is compatible with the signature of a given method.
*
@@ -267,14 +270,12 @@
}
int argIndex = 0;
if (!isStatic) {
- ResolvedJavaType expectedType = method.getDeclaringClass();
- JavaKind expected = wordTypes == null ? expectedType.getJavaKind() : wordTypes.asKind(expectedType);
+ JavaKind expected = asKind(method.getDeclaringClass());
JavaKind actual = args[argIndex++].stamp().getStackKind();
assert expected == actual : graph + ": wrong kind of value for receiver argument of call to " + method + " [" + actual + " != " + expected + "]";
}
for (int i = 0; i != signature.getParameterCount(false); i++) {
- JavaType expectedType = signature.getParameterType(i, method.getDeclaringClass());
- JavaKind expected = wordTypes == null ? expectedType.getJavaKind().getStackKind() : wordTypes.asKind(expectedType).getStackKind();
+ JavaKind expected = asKind(signature.getParameterType(i, method.getDeclaringClass())).getStackKind();
JavaKind actual = args[argIndex++].stamp().getStackKind();
if (expected != actual) {
throw new AssertionError(graph + ": wrong kind of value for argument " + i + " of call to " + method + " [" + actual + " != " + expected + "]");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java Wed Nov 08 16:03:35 2017 -0500
@@ -433,13 +433,14 @@
}
IntrinsicContext initialIntrinsicContext = null;
- if (method.getAnnotation(Snippet.class) == null) {
+ Snippet snippetAnnotation = method.getAnnotation(Snippet.class);
+ if (snippetAnnotation == null) {
// Post-parse inlined intrinsic
initialIntrinsicContext = new IntrinsicContext(substitutedMethod, method, bytecodeProvider, INLINE_AFTER_PARSING);
} else {
// Snippet
ResolvedJavaMethod original = substitutedMethod != null ? substitutedMethod : method;
- initialIntrinsicContext = new IntrinsicContext(original, method, bytecodeProvider, INLINE_AFTER_PARSING);
+ initialIntrinsicContext = new IntrinsicContext(original, method, bytecodeProvider, INLINE_AFTER_PARSING, snippetAnnotation.allowPartialIntrinsicArgumentMismatch());
}
createGraphBuilder(metaAccess, replacements.providers.getStampProvider(), replacements.providers.getConstantReflection(), replacements.providers.getConstantFieldProvider(), config,
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounter.java Wed Nov 08 16:03:35 2017 -0500
@@ -93,12 +93,7 @@
*/
@Override
public int compareTo(SnippetCounter o) {
- if (value > o.value) {
- return -1;
- } else if (o.value < value) {
- return 1;
- }
- return 0;
+ return Long.signum(o.value - value);
}
private final Group group;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetIntegerHistogram.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,153 @@
+/*
+ * 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.
+ */
+package org.graalvm.compiler.replacements;
+
+/**
+ * A histogram that can (only) be {@linkplain #inc(long) incremented} from within a snippet for
+ * gathering snippet specific metrics.
+ */
+public final class SnippetIntegerHistogram {
+ private final SnippetCounter.Group group;
+ private final String name;
+
+ private final SnippetCounter counter0;
+ private final SnippetCounter counter1;
+ private final SnippetCounter counter2;
+ private final SnippetCounter counter3;
+ private final SnippetCounter counter4;
+ private final SnippetCounter counter5;
+ private final SnippetCounter counter6;
+ private final SnippetCounter counter7;
+ private final SnippetCounter counter8;
+ private final SnippetCounter counter9;
+ private final SnippetCounter counter10;
+
+ private final int counter0UpperBound;
+ private final int counter1UpperBound;
+ private final int counter2UpperBound;
+ private final int counter3UpperBound;
+ private final int counter4UpperBound;
+ private final int counter5UpperBound;
+ private final int counter6UpperBound;
+ private final int counter7UpperBound;
+ private final int counter8UpperBound;
+ private final int counter9UpperBound;
+
+ public SnippetIntegerHistogram(SnippetCounter.Group group, int log2StepLength, String name, String description) {
+ assert log2StepLength > 0;
+
+ this.group = group;
+ this.name = name;
+
+ int lowerBound = 0;
+ counter0UpperBound = 0;
+ counter0 = createCounter(group, name, description, lowerBound, counter0UpperBound);
+
+ lowerBound = counter0UpperBound + 1;
+ counter1UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+ counter1 = createCounter(group, name, description, lowerBound, counter1UpperBound);
+
+ lowerBound = counter1UpperBound + 1;
+ counter2UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+ counter2 = createCounter(group, name, description, lowerBound, counter2UpperBound);
+
+ lowerBound = counter2UpperBound + 1;
+ counter3UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+ counter3 = createCounter(group, name, description, lowerBound, counter3UpperBound);
+
+ lowerBound = counter3UpperBound + 1;
+ counter4UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+ counter4 = createCounter(group, name, description, lowerBound, counter4UpperBound);
+
+ lowerBound = counter4UpperBound + 1;
+ counter5UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+ counter5 = createCounter(group, name, description, lowerBound, counter5UpperBound);
+
+ lowerBound = counter5UpperBound + 1;
+ counter6UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+ counter6 = createCounter(group, name, description, lowerBound, counter6UpperBound);
+
+ lowerBound = counter6UpperBound + 1;
+ counter7UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+ counter7 = createCounter(group, name, description, lowerBound, counter7UpperBound);
+
+ lowerBound = counter7UpperBound + 1;
+ counter8UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+ counter8 = createCounter(group, name, description, lowerBound, counter8UpperBound);
+
+ lowerBound = counter8UpperBound + 1;
+ counter9UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+ counter9 = createCounter(group, name, description, lowerBound, counter9UpperBound);
+
+ lowerBound = counter9UpperBound + 1;
+ counter10 = createCounter(group, name, description, lowerBound, Long.MAX_VALUE);
+ }
+
+ private static SnippetCounter createCounter(SnippetCounter.Group group, String name, String description, long lowerBound, long upperBound) {
+ if (group != null) {
+ SnippetCounter snippetCounter = new SnippetCounter(group, name + "[" + lowerBound + ", " + upperBound + "]", description);
+ return snippetCounter;
+ }
+ return null;
+ }
+
+ /**
+ * Increments the value of the matching histogram element. This method can only be used in a
+ * snippet on a compile-time constant {@link SnippetIntegerHistogram} object.
+ */
+ public void inc(long value) {
+ if (group != null) {
+ if (value <= counter0UpperBound) {
+ counter0.inc();
+ } else if (value <= counter1UpperBound) {
+ counter1.inc();
+ } else if (value <= counter2UpperBound) {
+ counter2.inc();
+ } else if (value <= counter3UpperBound) {
+ counter3.inc();
+ } else if (value <= counter4UpperBound) {
+ counter4.inc();
+ } else if (value <= counter5UpperBound) {
+ counter5.inc();
+ } else if (value <= counter6UpperBound) {
+ counter6.inc();
+ } else if (value <= counter7UpperBound) {
+ counter7.inc();
+ } else if (value <= counter8UpperBound) {
+ counter8.inc();
+ } else if (value <= counter9UpperBound) {
+ counter9.inc();
+ } else {
+ counter10.inc();
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ if (group != null) {
+ return "SnippetHistogram-" + group.name + ":" + name;
+ }
+ return super.toString();
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -23,15 +23,15 @@
package org.graalvm.compiler.replacements.nodes;
import static org.graalvm.compiler.nodeinfo.InputType.Memory;
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1024;
-import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1024;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.spi.Canonicalizable;
import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+import org.graalvm.compiler.nodeinfo.NodeCycles;
import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodeinfo.NodeSize;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.NamedLocationIdentity;
@@ -57,7 +57,7 @@
/**
* Compares two arrays with the same length.
*/
-@NodeInfo(cycles = CYCLES_1024, size = SIZE_1024)
+@NodeInfo(cycles = NodeCycles.CYCLES_UNKNOWN, size = NodeSize.SIZE_128)
public final class ArrayEqualsNode extends FixedWithNextNode implements LIRLowerable, Canonicalizable, Virtualizable, MemoryAccess {
public static final NodeClass<ArrayEqualsNode> TYPE = NodeClass.create(ArrayEqualsNode.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -24,7 +24,6 @@
import static org.graalvm.compiler.nodeinfo.InputType.Memory;
import static org.graalvm.compiler.nodeinfo.InputType.State;
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_256;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
import static org.graalvm.word.LocationIdentity.any;
@@ -32,6 +31,7 @@
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.NodeInputList;
+import org.graalvm.compiler.nodeinfo.NodeCycles;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.DeoptimizingNode;
@@ -56,7 +56,7 @@
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ResolvedJavaType;
-@NodeInfo(cycles = CYCLES_256, size = SIZE_64)
+@NodeInfo(cycles = NodeCycles.CYCLES_UNKNOWN, size = SIZE_64)
public class BasicArrayCopyNode extends AbstractMemoryCheckpoint implements Virtualizable, MemoryCheckpoint.Single, MemoryAccess, Lowerable, DeoptimizingNode.DeoptDuring {
public static final NodeClass<BasicArrayCopyNode> TYPE = NodeClass.create(BasicArrayCopyNode.class);
@@ -215,7 +215,7 @@
return;
}
for (int i = 0; i < len; i++) {
- tool.setVirtualEntry(destVirtual, destPosInt + i, tool.getEntry(srcVirtual, srcPosInt + i), false);
+ tool.setVirtualEntry(destVirtual, destPosInt + i, tool.getEntry(srcVirtual, srcPosInt + i));
}
tool.delete();
DebugContext debug = getDebug();
@@ -235,7 +235,7 @@
for (int i = 0; i < len; i++) {
LoadIndexedNode load = new LoadIndexedNode(graph().getAssumptions(), srcAlias, ConstantNode.forInt(i + srcPosInt, graph()), destComponentType.getJavaKind());
tool.addNode(load);
- tool.setVirtualEntry(destVirtual, destPosInt + i, load, false);
+ tool.setVirtualEntry(destVirtual, destPosInt + i, load);
}
tool.delete();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,7 +22,6 @@
*/
package org.graalvm.compiler.replacements.nodes;
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8;
import java.util.Collections;
@@ -32,6 +31,7 @@
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.core.common.type.StampPair;
import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.NodeCycles;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
import org.graalvm.compiler.nodes.ValueNode;
@@ -49,7 +49,7 @@
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
-@NodeInfo(cycles = CYCLES_8, size = SIZE_8)
+@NodeInfo(cycles = NodeCycles.CYCLES_UNKNOWN, size = SIZE_8)
public abstract class BasicObjectCloneNode extends MacroStateSplitNode implements VirtualizableAllocation, ArrayLengthProvider {
public static final NodeClass<BasicObjectCloneNode> TYPE = NodeClass.create(BasicObjectCloneNode.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BinaryMathIntrinsicNode.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BinaryMathIntrinsicNode.java Wed Nov 08 16:03:35 2017 -0500
@@ -37,7 +37,7 @@
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.BinaryNode;
-import org.graalvm.compiler.nodes.calc.DivNode;
+import org.graalvm.compiler.nodes.calc.FloatDivNode;
import org.graalvm.compiler.nodes.calc.MulNode;
import org.graalvm.compiler.nodes.calc.SqrtNode;
import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -141,7 +141,7 @@
// x**-1 = 1/x
if (yValue == -1.0D) {
- return new DivNode(ConstantNode.forDouble(1), x);
+ return new FloatDivNode(ConstantNode.forDouble(1), x);
}
// x**2 = x*x
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -36,6 +36,7 @@
import java.util.Collections;
import java.util.List;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugDumpHandler;
@@ -392,6 +393,20 @@
* {@link DebugDumpHandler}s closed in {@link #afterTest()}.
*/
protected DebugContext getDebugContext(OptionValues options) {
+ return getDebugContext(options, null, null);
+ }
+
+ /**
+ * Gets a {@link DebugContext} object corresponding to {@code options}, creating a new one if
+ * none currently exists.Debug contexts created by this method will have their
+ * {@link DebugDumpHandler}s closed in {@link #afterTest()}.
+ *
+ * @param options currently active options
+ * @param id identification of the compilation or {@code null}
+ * @param method method to use for a proper description of the context or {@code null}
+ * @return configured context for compilation
+ */
+ protected DebugContext getDebugContext(OptionValues options, String id, ResolvedJavaMethod method) {
List<DebugContext> cached = cachedDebugs.get();
if (cached == null) {
cached = new ArrayList<>();
@@ -402,7 +417,13 @@
return debug;
}
}
- DebugContext debug = DebugContext.create(options, NO_DESCRIPTION, NO_GLOBAL_METRIC_VALUES, DEFAULT_LOG_STREAM, getDebugHandlersFactories());
+ final DebugContext.Description descr;
+ if (method == null) {
+ descr = NO_DESCRIPTION;
+ } else {
+ descr = new DebugContext.Description(method, id == null ? method.getName() : id);
+ }
+ DebugContext debug = DebugContext.create(options, descr, NO_GLOBAL_METRIC_VALUES, DEFAULT_LOG_STREAM, getDebugHandlersFactories());
cached.add(debug);
return debug;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectList.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectList.java Wed Nov 08 16:03:35 2017 -0500
@@ -171,9 +171,14 @@
}
public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes, boolean cfgKills) {
+ boolean message = false;
for (int i = 0; i < size(); i++) {
Effect effect = effects[i];
if (effect.isCfgKill() == cfgKills) {
+ if (!message) {
+ message = true;
+ debug.log(cfgKills ? " ==== cfg kill effects" : " ==== effects");
+ }
try {
effect.apply(graph, obsoleteNodes);
} catch (Throwable t) {
@@ -202,7 +207,7 @@
// Inner classes could capture the EffectList itself.
continue;
}
- str.append(first ? "" : ", ").append(format(object));
+ str.append(first ? "" : ", ").append(field.getName()).append("=").append(format(object));
first = false;
} catch (SecurityException | IllegalAccessException e) {
throw new RuntimeException(e);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsClosure.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsClosure.java Wed Nov 08 16:03:35 2017 -0500
@@ -184,7 +184,6 @@
};
ReentrantBlockIterator.apply(closure, cfg.getStartBlock());
for (GraphEffectList effects : effectList) {
- debug.log(" ==== effects");
effects.apply(graph, obsoleteNodes, false);
}
/*
@@ -193,7 +192,6 @@
* indexes.
*/
for (GraphEffectList effects : effectList) {
- debug.log(" ==== cfg kill effects");
effects.apply(graph, obsoleteNodes, true);
}
debug.dump(DebugContext.DETAILED_LEVEL, graph, "After applying effects");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsPhase.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsPhase.java Wed Nov 08 16:03:35 2017 -0500
@@ -99,8 +99,8 @@
closure.applyEffects();
}
- if (debug.isDumpEnabled(DebugContext.INFO_LEVEL)) {
- debug.dump(DebugContext.DETAILED_LEVEL, graph, "%s iteration", getName());
+ if (debug.isDumpEnabled(DebugContext.VERBOSE_LEVEL)) {
+ debug.dump(DebugContext.VERBOSE_LEVEL, graph, "%s iteration", getName());
}
new DeadCodeEliminationPhase(Required).apply(graph);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ObjectState.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ObjectState.java Wed Nov 08 16:03:35 2017 -0500
@@ -68,6 +68,7 @@
}
public ObjectState(ValueNode[] entries, LockState locks, boolean ensureVirtualized) {
+ assert checkIllegalValues(entries);
this.entries = entries;
this.locks = locks;
this.ensureVirtualized = ensureVirtualized;
@@ -92,6 +93,30 @@
return new ObjectState(this);
}
+ /**
+ * Ensure that if an {@link JavaConstant#forIllegal() illegal value} is seen that the previous
+ * value is a double word value.
+ */
+ public static boolean checkIllegalValues(ValueNode[] values) {
+ if (values != null) {
+ for (int v = 1; v < values.length; v++) {
+ checkIllegalValue(values, v);
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Ensure that if an {@link JavaConstant#forIllegal() illegal value} is seen that the previous
+ * value is a double word value.
+ */
+ public static boolean checkIllegalValue(ValueNode[] values, int v) {
+ if (v > 0 && values[v].isConstant() && values[v].asConstant().equals(JavaConstant.forIllegal())) {
+ assert values[v - 1].getStackKind().needsTwoSlots();
+ }
+ return true;
+ }
+
public EscapeObjectState createEscapeObjectState(DebugContext debug, VirtualObjectNode virtual) {
GET_ESCAPED_OBJECT_STATE.increment(debug);
if (cachedState == null) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java Wed Nov 08 16:03:35 2017 -0500
@@ -854,6 +854,7 @@
ValueNode nextValue = objectState.getEntry(valueIndex + 1);
if (value.isConstant() && value.asConstant().equals(JavaConstant.INT_0) && nextValue.isConstant() && nextValue.asConstant().equals(JavaConstant.INT_0)) {
// rewrite to a zero constant of the larger kind
+ debug.log("Rewriting entry %s to constant of larger size", valueIndex);
states[i].setEntry(object, valueIndex, ConstantNode.defaultForKind(twoSlotKinds[valueIndex], graph()));
states[i].setEntry(object, valueIndex + 1, ConstantNode.forConstant(JavaConstant.forIllegal(), tool.getMetaAccessProvider(), graph()));
} else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualizerToolImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualizerToolImpl.java Wed Nov 08 16:03:35 2017 -0500
@@ -30,18 +30,22 @@
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.FixedNode;
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.FloatingNode;
+import org.graalvm.compiler.nodes.calc.UnpackEndianHalfNode;
import org.graalvm.compiler.nodes.java.MonitorIdNode;
import org.graalvm.compiler.nodes.spi.LoweringProvider;
import org.graalvm.compiler.nodes.spi.VirtualizerTool;
+import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode;
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.meta.Assumptions;
import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.MetaAccessProvider;
@@ -58,6 +62,7 @@
private final OptionValues options;
private final DebugContext debug;
private final LoweringProvider loweringProvider;
+ private ConstantNode illegalConstant;
VirtualizerToolImpl(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider, PartialEscapeClosure<?> closure,
Assumptions assumptions, OptionValues options, DebugContext debug, LoweringProvider loweringProvider) {
@@ -125,17 +130,81 @@
}
@Override
- public void setVirtualEntry(VirtualObjectNode virtual, int index, ValueNode value, boolean unsafe) {
+ public boolean setVirtualEntry(VirtualObjectNode virtual, int index, ValueNode value, JavaKind theAccessKind, long offset) {
ObjectState obj = state.getObjectState(virtual);
assert obj.isVirtual() : "not virtual: " + obj;
ValueNode newValue;
+ JavaKind entryKind = virtual.entryKind(index);
+ JavaKind accessKind = theAccessKind != null ? theAccessKind : entryKind;
if (value == null) {
newValue = null;
} else {
newValue = closure.getAliasAndResolve(state, value);
- assert unsafe || obj.getEntry(index) == null || obj.getEntry(index).getStackKind() == newValue.getStackKind() || (isObjectEntry(obj.getEntry(index)) && isObjectEntry(newValue));
+ }
+ getDebug().log(DebugContext.DETAILED_LEVEL, "Setting entry %d in virtual object %s %s results in %s", index, virtual.getObjectId(), virtual, state.getObjectState(virtual.getObjectId()));
+ ValueNode oldValue = getEntry(virtual, index);
+ boolean canVirtualize = entryKind == accessKind || (entryKind == accessKind.getStackKind() && virtual instanceof VirtualInstanceNode);
+ if (!canVirtualize) {
+ if (entryKind == JavaKind.Long && oldValue.getStackKind() == newValue.getStackKind() && oldValue.getStackKind().isPrimitive()) {
+ /*
+ * Special case: If the entryKind is long, allow arbitrary kinds as long as a value
+ * of the same kind is already there. This can only happen if some other node
+ * initialized the entry with a value of a different kind. One example where this
+ * happens is the Truffle NewFrameNode.
+ */
+ getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s with primitive of kind %s in long entry ", current, oldValue.getStackKind());
+ canVirtualize = true;
+ } else if (entryKind == JavaKind.Int && (accessKind == JavaKind.Long || accessKind == JavaKind.Double) && offset % 8 == 0) {
+ /*
+ * Special case: Allow storing a single long or double value into two consecutive
+ * int slots.
+ */
+ int nextIndex = virtual.entryIndexForOffset(offset + 4, JavaKind.Int);
+ if (nextIndex != -1) {
+ canVirtualize = true;
+ assert nextIndex == index + 1 : "expected to be sequential";
+ getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s for double word stored in two ints", current);
+ }
+ }
}
- state.setEntry(virtual.getObjectId(), index, newValue);
+
+ if (canVirtualize) {
+ getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s for entryKind %s and access kind %s", current, entryKind, accessKind);
+ state.setEntry(virtual.getObjectId(), index, newValue);
+ if (entryKind == JavaKind.Int) {
+ if (accessKind.needsTwoSlots()) {
+ // Storing double word value two int slots
+ assert virtual.entryKind(index + 1) == JavaKind.Int;
+ state.setEntry(virtual.getObjectId(), index + 1, getIllegalConstant());
+ } else if (oldValue.getStackKind() == JavaKind.Double || oldValue.getStackKind() == JavaKind.Long) {
+ // Splitting double word constant by storing over it with an int
+ getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s producing second half of double word value %s", current, oldValue);
+ ValueNode secondHalf = UnpackEndianHalfNode.create(oldValue, false);
+ addNode(secondHalf);
+ state.setEntry(virtual.getObjectId(), index + 1, secondHalf);
+ }
+ }
+ if (oldValue.isConstant() && oldValue.asConstant().equals(JavaConstant.forIllegal())) {
+ // Storing into second half of double, so replace previous value
+ ValueNode previous = getEntry(virtual, index - 1);
+ getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s producing first half of double word value %s", current, previous);
+ ValueNode firstHalf = UnpackEndianHalfNode.create(previous, true);
+ addNode(firstHalf);
+ state.setEntry(virtual.getObjectId(), index - 1, firstHalf);
+ }
+ return true;
+ }
+ // Should only occur if there are mismatches between the entry and access kind
+ assert entryKind != accessKind;
+ return false;
+ }
+
+ private ValueNode getIllegalConstant() {
+ if (illegalConstant == null) {
+ illegalConstant = ConstantNode.forConstant(JavaConstant.forIllegal(), getMetaAccessProvider());
+ addNode(illegalConstant);
+ }
+ return illegalConstant;
}
@Override
@@ -149,10 +218,6 @@
return state.getObjectState(virtualObject).getEnsureVirtualized();
}
- private static boolean isObjectEntry(ValueNode value) {
- return value.getStackKind() == JavaKind.Object || value instanceof VirtualObjectNode;
- }
-
@Override
public void replaceWithVirtual(VirtualObjectNode virtual) {
closure.addVirtualAlias(virtual, current);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphOutput.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphOutput.java Wed Nov 08 16:03:35 2017 -0500
@@ -113,12 +113,30 @@
private GraphElements<M, ?, ?, ?> elements = null;
private GraphTypes types = DefaultGraphTypes.DEFAULT;
private GraphBlocks<G, ?, N> blocks = DefaultGraphBlocks.empty();
+ private int major = 4;
+ private int minor = 0;
Builder(GraphStructure<G, N, ?, ?> structure) {
this.structure = structure;
}
/**
+ * Chooses which version of the protocol to use. The default version is <code>4.0</code>
+ * (when the {@link GraphOutput} & co. classes were introduced). The default can be changed
+ * to other known versions manually by calling this method.
+ *
+ * @param majorVersion by default 4, newer version may be known
+ * @param minorVersion usually 0
+ * @return this builder
+ * @since 0.28
+ */
+ public Builder<G, N, M> protocolVersion(int majorVersion, int minorVersion) {
+ this.major = majorVersion;
+ this.minor = minorVersion;
+ return this;
+ }
+
+ /**
* Associates different implementation of types.
*
* @param graphTypes implementation of types and enum recognition
@@ -161,7 +179,28 @@
* @throws IOException if something goes wrong when writing to the channel
*/
public GraphOutput<G, M> build(WritableByteChannel channel) throws IOException {
- ProtocolImpl<G, N, ?, ?, ?, M, ?, ?, ?> p = new ProtocolImpl<>(structure, types, blocks, elements, channel);
+ ProtocolImpl<G, N, ?, ?, ?, M, ?, ?, ?> p = new ProtocolImpl<>(major, minor, structure, types, blocks, elements, channel);
+ return new GraphOutput<>(p);
+ }
+
+ /**
+ * Support for nesting heterogenous graphs. The newly created output uses all the interfaces
+ * currently associated with this builder, but shares with {@code parent} the output
+ * {@code channel}, internal constant pool and {@link #protocolVersion(int, int) protocol
+ * version}.
+ * <p>
+ * Both GraphOutput (the {@code parent} and the returned one) has to be used in
+ * synchronization - e.g. only one
+ * {@link #beginGroup(java.lang.Object, java.lang.String, java.lang.String, java.lang.Object, int, java.util.Map)
+ * begin}, {@link #endGroup() end} of group or
+ * {@link #print(java.lang.Object, java.util.Map, int, java.lang.String, java.lang.Object...)
+ * printing} can be on at a given moment.
+ *
+ * @param parent the output to inherit {@code channel} and protocol version from
+ * @return new output sharing {@code channel} and other internals with {@code parent}
+ */
+ public GraphOutput<G, M> build(GraphOutput<?, ?> parent) {
+ ProtocolImpl<G, N, ?, ?, ?, M, ?, ?, ?> p = new ProtocolImpl<>(parent.printer, structure, types, blocks, elements);
return new GraphOutput<>(p);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java Wed Nov 08 16:03:35 2017 -0500
@@ -52,6 +52,7 @@
private static final int POOL_FIELD = 0x07;
private static final int POOL_SIGNATURE = 0x08;
private static final int POOL_NODE_SOURCE_POSITION = 0x09;
+ private static final int POOL_NODE = 0x0a;
private static final int PROPERTY_POOL = 0x00;
private static final int PROPERTY_INT = 0x01;
@@ -71,19 +72,12 @@
private final ConstantPool constantPool;
private final ByteBuffer buffer;
private final WritableByteChannel channel;
- private final int versionMajor;
- private final int versionMinor;
-
- protected GraphProtocol(WritableByteChannel channel) throws IOException {
- this(channel, 4, 0);
- }
+ final int versionMajor;
+ final int versionMinor;
- private GraphProtocol(WritableByteChannel channel, int major, int minor) throws IOException {
- if (major > 4) {
- throw new IllegalArgumentException();
- }
- if (major == 4 && minor > 0) {
- throw new IllegalArgumentException();
+ GraphProtocol(WritableByteChannel channel, int major, int minor) throws IOException {
+ if (major > 5 || (major == 5 && minor > 0)) {
+ throw new IllegalArgumentException("Unrecognized version " + major + "." + minor);
}
this.versionMajor = major;
this.versionMinor = minor;
@@ -93,6 +87,14 @@
writeVersion();
}
+ GraphProtocol(GraphProtocol<?, ?, ?, ?, ?, ?, ?, ?, ?> parent) {
+ this.versionMajor = parent.versionMajor;
+ this.versionMinor = parent.versionMinor;
+ this.constantPool = parent.constantPool;
+ this.buffer = parent.buffer;
+ this.channel = parent.channel;
+ }
+
@SuppressWarnings("all")
public final void print(Graph graph, Map<? extends Object, ? extends Object> properties, int id, String format, Object... args) throws IOException {
writeByte(BEGIN_GRAPH);
@@ -137,9 +139,33 @@
protected abstract ResolvedJavaMethod findMethod(Object obj);
+ /**
+ * Attempts to recognize the provided object as a node. Used to encode it with
+ * {@link #POOL_NODE} pool type.
+ *
+ * @param obj any object
+ * @return <code>null</code> if it is not a node object, non-null otherwise
+ */
+ protected abstract Node findNode(Object obj);
+
+ /**
+ * Determines whether the provided object is node class or not.
+ *
+ * @param obj object to check
+ * @return {@code null} if {@code obj} does not represent a NodeClass otherwise the NodeClass
+ * represented by {@code obj}
+ */
protected abstract NodeClass findNodeClass(Object obj);
/**
+ * Returns the NodeClass for a given Node {@code obj}.
+ *
+ * @param obj instance of node
+ * @return non-{@code null} instance of the node's class object
+ */
+ protected abstract NodeClass findClassForNode(Node obj);
+
+ /**
* Find a Java class. The returned object must be acceptable by
* {@link #findJavaTypeName(java.lang.Object)} and return valid name for the class.
*
@@ -239,7 +265,7 @@
private void flush() throws IOException {
buffer.flip();
/*
- * Try not to let interrupted threads aborting the write. There's still a race here but an
+ * Try not to let interrupted threads abort the write. There's still a race here but an
* interrupt that's been pending for a long time shouldn't stop this writing.
*/
boolean interrupted = Thread.interrupted();
@@ -338,7 +364,8 @@
}
}
- private void writePoolObject(Object object) throws IOException {
+ private void writePoolObject(Object obj) throws IOException {
+ Object object = obj;
if (object == null) {
writeByte(POOL_NULL);
return;
@@ -347,23 +374,31 @@
if (id == null) {
addPoolEntry(object);
} else {
- if (object instanceof Enum<?> || findEnumOrdinal(object) >= 0) {
- writeByte(POOL_ENUM);
- } else if (object instanceof Class<?> || findJavaTypeName(object) != null) {
- writeByte(POOL_CLASS);
- } else if (findJavaField(object) != null) {
+ if (findJavaField(object) != null) {
writeByte(POOL_FIELD);
} else if (findSignature(object) != null) {
writeByte(POOL_SIGNATURE);
} else if (versionMajor >= 4 && findNodeSourcePosition(object) != null) {
writeByte(POOL_NODE_SOURCE_POSITION);
} else {
+ final Node node = findNode(object);
+ if (versionMajor == 4 && node != null) {
+ object = classForNode(node);
+ }
if (findNodeClass(object) != null) {
writeByte(POOL_NODE_CLASS);
+ } else if (versionMajor >= 5 && node != null) {
+ writeByte(POOL_NODE);
} else if (findMethod(object) != null) {
writeByte(POOL_METHOD);
} else {
- writeByte(POOL_STRING);
+ if (object instanceof Enum<?> || findEnumOrdinal(object) >= 0) {
+ writeByte(POOL_ENUM);
+ } else if (object instanceof Class<?> || findJavaTypeName(object) != null) {
+ writeByte(POOL_CLASS);
+ } else {
+ writeByte(POOL_STRING);
+ }
}
}
writeShort(id.charValue());
@@ -383,10 +418,7 @@
writeInt(size);
int cnt = 0;
for (Node node : findNodes(info)) {
- NodeClass nodeClass = findNodeClass(node);
- if (nodeClass == null) {
- throw new IOException("No class for " + node);
- }
+ NodeClass nodeClass = classForNode(node);
findNodeProperties(node, props, info);
writeInt(findNodeId(node));
@@ -405,7 +437,7 @@
}
private void writeEdges(Graph graph, Node node, boolean dumpInputs) throws IOException {
- NodeClass clazz = findNodeClass(node);
+ NodeClass clazz = classForNode(node);
Edges edges = findClassEdges(clazz, dumpInputs);
int size = findSize(edges);
for (int i = 0; i < size; i++) {
@@ -434,6 +466,14 @@
}
}
+ private NodeClass classForNode(Node node) throws IOException {
+ NodeClass clazz = findClassForNode(node);
+ if (clazz == null) {
+ throw new IOException("No class for " + node);
+ }
+ return clazz;
+ }
+
private void writeNodeRef(Node node) throws IOException {
writeInt(findNodeId(node));
}
@@ -480,7 +520,8 @@
}
@SuppressWarnings("all")
- private void addPoolEntry(Object object) throws IOException {
+ private void addPoolEntry(Object obj) throws IOException {
+ Object object = obj;
ResolvedJavaField field;
String typeName;
Signature signature;
@@ -489,24 +530,7 @@
char index = constantPool.add(object);
writeByte(POOL_NEW);
writeShort(index);
- if ((typeName = findJavaTypeName(object)) != null) {
- writeByte(POOL_CLASS);
- writeString(typeName);
- String[] enumValueNames = findEnumTypeValues(object);
- if (enumValueNames != null) {
- writeByte(ENUM_KLASS);
- writeInt(enumValueNames.length);
- for (String o : enumValueNames) {
- writePoolObject(o);
- }
- } else {
- writeByte(KLASS);
- }
- } else if ((enumOrdinal = findEnumOrdinal(object)) >= 0) {
- writeByte(POOL_ENUM);
- writePoolObject(findEnumClass(object));
- writeInt(enumOrdinal);
- } else if ((field = findJavaField(object)) != null) {
+ if ((field = findJavaField(object)) != null) {
writeByte(POOL_FIELD);
writePoolObject(findFieldDeclaringClass(field));
writePoolObject(findFieldName(field));
@@ -535,6 +559,18 @@
}
writePoolObject(findNodeSourcePositionCaller(pos));
} else {
+ Node node = findNode(object);
+ if (node != null) {
+ if (versionMajor >= 5) {
+ writeByte(POOL_NODE);
+ writeInt(findNodeId(node));
+ writePoolObject(classForNode(node));
+ return;
+ }
+ if (versionMajor == 4) {
+ object = classForNode(node);
+ }
+ }
NodeClass nodeClass = findNodeClass(object);
if (nodeClass != null) {
writeByte(POOL_NODE_CLASS);
@@ -553,8 +589,27 @@
}
ResolvedJavaMethod method = findMethod(object);
if (method == null) {
- writeByte(POOL_STRING);
- writeString(object.toString());
+ if ((typeName = findJavaTypeName(object)) != null) {
+ writeByte(POOL_CLASS);
+ writeString(typeName);
+ String[] enumValueNames = findEnumTypeValues(object);
+ if (enumValueNames != null) {
+ writeByte(ENUM_KLASS);
+ writeInt(enumValueNames.length);
+ for (String o : enumValueNames) {
+ writePoolObject(o);
+ }
+ } else {
+ writeByte(KLASS);
+ }
+ } else if ((enumOrdinal = findEnumOrdinal(object)) >= 0) {
+ writeByte(POOL_ENUM);
+ writePoolObject(findEnumClass(object));
+ writeInt(enumOrdinal);
+ } else {
+ writeByte(POOL_STRING);
+ writeString(object.toString());
+ }
return;
}
writeByte(POOL_METHOD);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphSnippets.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,285 @@
+/*
+ * 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.
+ */
+
+package org.graalvm.graphio;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.WritableByteChannel;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+final class GraphSnippets {
+ static GraphStructure<AcmeGraph, AcmeNode, AcmeNodeType, AcmePorts> acmeGraphStructure() {
+ // @formatter:off
+ // BEGIN: org.graalvm.graphio.GraphSnippets#acmeGraphStructure
+ class AcmeGraphStructure implements
+ GraphStructure<AcmeGraph, AcmeNode, AcmeNodeType, AcmePorts> {
+
+ @Override
+ public AcmeGraph graph(AcmeGraph currentGraph, Object obj) {
+ return obj instanceof AcmeGraph ? (AcmeGraph) obj : null;
+ }
+
+ @Override
+ public Iterable<? extends AcmeNode> nodes(AcmeGraph graph) {
+ return graph.allNodes();
+ }
+
+ @Override
+ public int nodesCount(AcmeGraph graph) {
+ return graph.allNodes().size();
+ }
+
+ @Override
+ public int nodeId(AcmeNode node) {
+ return node.id;
+ }
+
+ @Override
+ public boolean nodeHasPredecessor(AcmeNode node) {
+ return node.id > 0;
+ }
+
+ @Override
+ public void nodeProperties(
+ AcmeGraph graph, AcmeNode node, Map<String, ? super Object> properties
+ ) {
+ properties.put("id", node.id);
+ }
+
+ @Override
+ public AcmeNodeType nodeClass(Object obj) {
+ return obj instanceof AcmeNodeType ? (AcmeNodeType) obj : null;
+ }
+
+ @Override
+ public AcmeNode node(Object obj) {
+ return obj instanceof AcmeNode ? (AcmeNode) obj : null;
+ }
+
+ @Override
+ public AcmeNodeType classForNode(AcmeNode node) {
+ // we have only one type of nodes
+ return AcmeNodeType.STANDARD;
+ }
+
+
+ @Override
+ public String nameTemplate(AcmeNodeType nodeClass) {
+ return "Acme ({p#id})";
+ }
+
+ @Override
+ public Object nodeClassType(AcmeNodeType nodeClass) {
+ return nodeClass.getClass();
+ }
+
+ @Override
+ public AcmePorts portInputs(AcmeNodeType nodeClass) {
+ return AcmePorts.INPUT;
+ }
+
+ @Override
+ public AcmePorts portOutputs(AcmeNodeType nodeClass) {
+ return AcmePorts.OUTPUT;
+ }
+
+ @Override
+ public int portSize(AcmePorts port) {
+ return port == AcmePorts.OUTPUT ? 1 : 0;
+ }
+
+ @Override
+ public boolean edgeDirect(AcmePorts port, int index) {
+ return false;
+ }
+
+ @Override
+ public String edgeName(AcmePorts port, int index) {
+ return port.name();
+ }
+
+ @Override
+ public Object edgeType(AcmePorts port, int index) {
+ return port;
+ }
+
+ @Override
+ public Collection<? extends AcmeNode> edgeNodes(
+ AcmeGraph graph, AcmeNode node, AcmePorts port, int index
+ ) {
+ if (port == AcmePorts.OUTPUT) {
+ return node.outgoing.targets;
+ }
+ return null;
+ }
+ }
+
+ // END: org.graalvm.graphio.GraphSnippets#acmeGraphStructure
+
+ return new AcmeGraphStructure();
+ }
+
+ // BEGIN: org.graalvm.graphio.GraphSnippets#buildOutput
+ static GraphOutput<AcmeGraph, ?> buildOutput(WritableByteChannel channel)
+ throws IOException {
+ return GraphOutput.newBuilder(acmeGraphStructure()).
+ // use the latest version; currently 5.0
+ protocolVersion(5, 0).
+ build(channel);
+ }
+ // END: org.graalvm.graphio.GraphSnippets#buildOutput
+
+ // BEGIN: org.graalvm.graphio.GraphSnippets#buildAll
+ static GraphOutput<AcmeGraph, ?> buildAll(WritableByteChannel channel)
+ throws IOException {
+ GraphBlocks<AcmeGraph, AcmeBlocks, AcmeNode> graphBlocks = acmeBlocks();
+ GraphElements<AcmeMethod, AcmeField,
+ AcmeSignature, AcmeCodePosition> graphElements = acmeElements();
+ GraphTypes graphTypes = acmeTypes();
+
+ return GraphOutput.newBuilder(acmeGraphStructure()).
+ protocolVersion(5, 0).
+ blocks(graphBlocks).
+ elements(graphElements).
+ types(graphTypes).
+ build(channel);
+ }
+ // END: org.graalvm.graphio.GraphSnippets#buildAll
+
+ private static GraphTypes acmeTypes() {
+ GraphTypes graphTypes = null;
+ // in real world don't return null
+ return graphTypes;
+ }
+
+ private static GraphElements<AcmeMethod, AcmeField, AcmeSignature, AcmeCodePosition> acmeElements() {
+ GraphElements<AcmeMethod, AcmeField, AcmeSignature, AcmeCodePosition> graphElements = null;
+ // in real world don't return null
+ return graphElements;
+ }
+
+ private static GraphBlocks<AcmeGraph, AcmeBlocks, AcmeNode> acmeBlocks() {
+ GraphBlocks<AcmeGraph, AcmeBlocks, AcmeNode> graphBlocks = null;
+ // in real world don't return null
+ return graphBlocks;
+ }
+
+ private static class AcmeGraph {
+ final AcmeNode root;
+
+ AcmeGraph(AcmeNode root) {
+ this.root = root;
+ }
+
+ Set<AcmeNode> allNodes() {
+ return allNodes(root, new LinkedHashSet<>());
+ }
+
+ private static Set<AcmeNode> allNodes(AcmeNode node, Set<AcmeNode> collectTo) {
+ if (collectTo.add(node)) {
+ for (AcmeNode target : node.outgoing.targets) {
+ allNodes(target, collectTo);
+ }
+ }
+ return collectTo;
+ }
+ }
+
+ private static class AcmeNode {
+ final int id;
+ final AcmeEdges outgoing;
+
+ AcmeNode(int id) {
+ this.id = id;
+ this.outgoing = new AcmeEdges();
+ }
+
+ void linkTo(AcmeNode target) {
+ outgoing.targets.add(target);
+ }
+ }
+
+ private enum AcmeNodeType {
+ STANDARD
+ }
+
+ private enum AcmePorts {
+ INPUT,
+ OUTPUT;
+ }
+
+ private static class AcmeEdges {
+ final Set<AcmeNode> targets;
+
+ AcmeEdges() {
+ this.targets = new LinkedHashSet<>();
+ }
+ }
+
+ private static class AcmeBlocks {
+ }
+
+ private static class AcmeMethod {
+ }
+
+ private static class AcmeField {
+ }
+
+ private static class AcmeSignature {
+ }
+
+ private static class AcmeCodePosition {
+ }
+
+ // BEGIN: org.graalvm.graphio.GraphSnippets#dump
+ static void dump(File toFile) throws IOException {
+ try (
+ FileChannel ch = new FileOutputStream(toFile).getChannel();
+ GraphOutput<AcmeGraph, ?> output = buildOutput(ch);
+ ) {
+ AcmeNode root = new AcmeNode(0);
+ AcmeNode n1 = new AcmeNode(1);
+ AcmeNode n2 = new AcmeNode(2);
+ AcmeNode n3 = new AcmeNode(3);
+
+ root.linkTo(n1);
+ root.linkTo(n2);
+ n1.linkTo(n3);
+ n2.linkTo(n3);
+
+ AcmeGraph diamondGraph = new AcmeGraph(root);
+
+ output.beginGroup(diamondGraph, "Diamond", "dia", null, 0, null);
+ output.print(diamondGraph, null, 0, "Diamond graph #%d", 1);
+ output.endGroup();
+ }
+ }
+ // END: org.graalvm.graphio.GraphSnippets#dump
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphStructure.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphStructure.java Wed Nov 08 16:03:35 2017 -0500
@@ -38,9 +38,9 @@
*/
public interface GraphStructure<G, N, C, P> {
/**
- * Casts the provided object to graph, if possible. If the given object <code>obj</code> can be
- * seen as a graph or sub-graph of a graph, then return the properly typed instance. Otherwise
- * return <code>null</code>
+ * Casts {@code obj} to graph, if possible. If the given object <code>obj</code> can be seen as
+ * a graph or sub-graph of a graph, then return the properly typed instance. Otherwise return
+ * <code>null</code>
*
* @param currentGraph the currently processed graph
* @param obj an object to check and view as a graph
@@ -69,8 +69,8 @@
int nodesCount(G graph);
/**
- * Id of a node. Each node in the graph is uniquely identified by a integer value. If two nodes
- * have the same id, then they shall be <code>==</code> to each other.
+ * Id of {@code node}. Each node in the graph is uniquely identified by an integer value. If two
+ * nodes have the same id, then they shall be <code>==</code> to each other.
*
* @param node the node to query for an id
* @return the id of the node
@@ -96,16 +96,35 @@
void nodeProperties(G graph, N node, Map<String, ? super Object> properties);
/**
- * Finds the node class for the provided object, if possible. If the given object
- * <code>obj</code> can be seen as an instance of node class or it is a node in this graph,
- * return the properly typed instance of the node class. Otherwise return <code>null</code>
+ * Finds a node for {@code obj}, if possible. If the given object <code>obj</code> can be seen
+ * as an instance of node return the properly typed instance of the node class. Otherwise return
+ * <code>null</code>.
+ *
+ * @param obj an object to find node for
+ * @return appropriate graph object or <code>null</code> if the object doesn't represent a node
+ */
+ N node(Object obj);
+
+ /**
+ * Finds a node class for {@code obj}, if possible. If the given object <code>obj</code> can be
+ * seen as an instance of node class return the properly typed instance of the node class.
+ * Otherwise return <code>null</code>.
*
* @param obj an object to find node class for
- * @return appropriate graph object or <code>null</code> if the object doesn't represent a graph
+ * @return appropriate graph object or <code>null</code> if the object doesn't represent a node
+ * class
*/
C nodeClass(Object obj);
/**
+ * Finds a node class for {@code node}.
+ *
+ * @param node an instance of node in this graph
+ * @return the node's node class, never <code>null</code>
+ */
+ C classForNode(N node);
+
+ /**
* The template used to build the name of nodes of this class. The template may use references
* to inputs ({i#inputName}) and its properties ({p#propertyName}).
*
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/ProtocolImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/ProtocolImpl.java Wed Nov 08 16:03:35 2017 -0500
@@ -34,9 +34,18 @@
private final GraphBlocks<Graph, Block, Node> blocks;
private final GraphElements<ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition> elements;
- ProtocolImpl(GraphStructure<Graph, Node, NodeClass, Port> structure, GraphTypes enums, GraphBlocks<Graph, Block, Node> blocks,
+ ProtocolImpl(int major, int minor, GraphStructure<Graph, Node, NodeClass, Port> structure, GraphTypes enums, GraphBlocks<Graph, Block, Node> blocks,
GraphElements<ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition> elements, WritableByteChannel channel) throws IOException {
- super(channel);
+ super(channel, major, minor);
+ this.structure = structure;
+ this.types = enums;
+ this.blocks = blocks;
+ this.elements = elements;
+ }
+
+ ProtocolImpl(GraphProtocol<?, ?, ?, ?, ?, ?, ?, ?, ?> parent, GraphStructure<Graph, Node, NodeClass, Port> structure, GraphTypes enums, GraphBlocks<Graph, Block, Node> blocks,
+ GraphElements<ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition> elements) {
+ super(parent);
this.structure = structure;
this.types = enums;
this.blocks = blocks;
@@ -49,11 +58,21 @@
}
@Override
+ protected Node findNode(Object obj) {
+ return structure.node(obj);
+ }
+
+ @Override
protected NodeClass findNodeClass(Object obj) {
return structure.nodeClass(obj);
}
@Override
+ protected NodeClass findClassForNode(Node obj) {
+ return structure.classForNode(obj);
+ }
+
+ @Override
protected String findNameTemplate(NodeClass clazz) {
return structure.nameTemplate(clazz);
}
Binary file src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/doc-files/diamond.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/package-info.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,86 @@
+
+/*
+ * 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.
+ */
+
+/**
+ * Send your graphs to <b>IGV</b> via a socket or a file. This package allows one to easily encode
+ * any graph-like data structure and send it for visualization to
+ * <em>OracleLab's Ideal Graph Visualizer</em> tool. Assuming you already have your own data
+ * structure that contains <b>nodes</b> and <b>edges</b> among them, creating a
+ * {@link org.graalvm.graphio.GraphOutput} specialized for your data is a matter of implementing a
+ * single interface:
+ *
+ * {@link org.graalvm.graphio.GraphSnippets#acmeGraphStructure}
+ *
+ * The {@link org.graalvm.graphio.GraphStructure} interface defines the set of operations that are
+ * needed by the <em>graph protocol</em> to encode a graph into the <b>IGV</b> expected format. The
+ * graph structure is implemented as a so called
+ * <a href="http://wiki.apidesign.org/wiki/Singletonizer">singletonizer</a> API pattern: there is no
+ * need to change your data structures or implement some special interfaces - everything needed is
+ * provided by implementing the {@link org.graalvm.graphio.GraphStructure} operations.
+ * <p>
+ * The next step is to turn this graph structure into an instance of
+ * {@link org.graalvm.graphio.GraphOutput}. To do so use the associated
+ * {@link org.graalvm.graphio.GraphOutput.Builder builder} just like shown in the following method:
+ *
+ * {@link org.graalvm.graphio.GraphSnippets#buildOutput}
+ *
+ * Now you are ready to dump your graph into <b>IGV</b>. Where to obtain the right channel? One
+ * option is to create a {@link java.nio.channels.FileChannel} and dump the data into a file
+ * (preferrably with <code>.bgv</code> extension). The other is to open a socket to port
+ * <code>4445</code> (the default port <b>IGV</b> listens to) and dump the data there. Here is an
+ * example:
+ *
+ * {@link org.graalvm.graphio.GraphSnippets#dump}
+ *
+ * Call the {@code dump} method with pointer to file {@code diamond.bgv} and then you can open the
+ * file in <b>IGV</b>. The result will look like this:
+ * <p>
+ * <img src="doc-files/diamond.png">
+ * <p>
+ * You can verify the behavior directly in the <b>IGV</b> by downloading
+ * <a href="doc-files/diamond.bgv">diamond.bgv</a> file generated from the above diamond structure
+ * graph.
+ * <p>
+ * The primary <b>IGV</b> focus is on graphs used by Graal compiler. As such they aren't plain
+ * graphs, but contain various compiler oriented attributes:
+ * <ul>
+ * <li>{@linkplain org.graalvm.graphio.GraphBlocks code blocks} information</li>
+ * <li>{@linkplain org.graalvm.graphio.GraphElements method and fields} information</li>
+ * <li>Advanced support for {@linkplain org.graalvm.graphio.GraphTypes recognizing types}</li>
+ * </ul>
+ * all these additional interfaces ({@link org.graalvm.graphio.GraphBlocks},
+ * {@link org.graalvm.graphio.GraphElements} and {@link org.graalvm.graphio.GraphTypes}) are
+ * optional - they don't have to be provided. As such they can be specified via
+ * {@link org.graalvm.graphio.GraphOutput.Builder} instance methods, which may, but need not be
+ * called at all. Here is an example:
+ *
+ * {@link org.graalvm.graphio.GraphSnippets#buildAll}
+ *
+ * All these interfaces follow the
+ * <a href="http://wiki.apidesign.org/wiki/Singletonizer">singletonizer</a> API pattern again - e.g.
+ * no need to change your existing data structures, just implement the operations provided by the
+ * interfaces you pass into the builder. By combining these interfaces together you can get as rich,
+ * colorful, source linked graphs as Graal compiler produces to describe its optimizations.
+ */
+package org.graalvm.graphio;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/.checkstyle_checks.xml Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
+
+<!--
+ This configuration file was written by the eclipse-cs plugin configuration editor
+-->
+<!--
+ Checkstyle-Configuration: Checks
+ Description: none
+-->
+<module name="Checker">
+ <property name="severity" value="error"/>
+ <module name="TreeWalker">
+ <module name="AvoidStarImport">
+ <property name="allowClassImports" value="false"/>
+ <property name="allowStaticMemberImports" value="false"/>
+ </module>
+ <property name="tabWidth" value="4"/>
+ <module name="FileContentsHolder"/>
+ <module name="JavadocStyle">
+ <property name="checkHtml" value="false"/>
+ </module>
+ <module name="LocalFinalVariableName"/>
+ <module name="LocalVariableName"/>
+ <module name="MemberName">
+ <property name="format" value="^(([a-z][a-zA-Z0-9]*$)|(_[A-Z][a-zA-Z0-9]*_[a-z][a-zA-Z0-9]*$))"/>
+ </module>
+ <module name="MethodName"/>
+ <module name="PackageName"/>
+ <module name="ParameterName"/>
+ <module name="TypeName">
+ <property name="format" value="^[A-Z][_a-zA-Z0-9]*$"/>
+ </module>
+ <module name="RedundantImport"/>
+ <module name="LineLength">
+ <property name="max" value="250"/>
+ </module>
+ <module name="MethodParamPad"/>
+ <module name="NoWhitespaceAfter">
+ <property name="tokens" value="ARRAY_INIT,BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS"/>
+ </module>
+ <module name="NoWhitespaceBefore">
+ <property name="tokens" value="SEMI,DOT,POST_DEC,POST_INC"/>
+ </module>
+ <module name="ParenPad"/>
+ <module name="TypecastParenPad">
+ <property name="tokens" value="RPAREN,TYPECAST"/>
+ </module>
+ <module name="WhitespaceAfter"/>
+ <module name="WhitespaceAround">
+ <property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV,DIV_ASSIGN,EQUAL,GE,GT,LAND,LE,LITERAL_ASSERT,LITERAL_CATCH,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_RETURN,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS,PLUS_ASSIGN,QUESTION,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND"/>
+ </module>
+ <module name="RedundantModifier"/>
+ <module name="AvoidNestedBlocks">
+ <property name="allowInSwitchCase" value="true"/>
+ </module>
+ <module name="EmptyBlock">
+ <property name="option" value="text"/>
+ <property name="tokens" value="LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_IF,LITERAL_TRY,LITERAL_WHILE,STATIC_INIT"/>
+ </module>
+ <module name="LeftCurly"/>
+ <module name="NeedBraces"/>
+ <module name="RightCurly"/>
+ <module name="EmptyStatement"/>
+ <module name="HiddenField">
+ <property name="severity" value="ignore"/>
+ <property name="ignoreConstructorParameter" value="true"/>
+ <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+ </module>
+ <module name="FinalClass"/>
+ <module name="HideUtilityClassConstructor">
+ <property name="severity" value="ignore"/>
+ <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+ </module>
+ <module name="ArrayTypeStyle"/>
+ <module name="UpperEll"/>
+ <module name="FallThrough"/>
+ <module name="FinalLocalVariable">
+ <property name="severity" value="ignore"/>
+ <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+ </module>
+ <module name="MultipleVariableDeclarations"/>
+ <module name="StringLiteralEquality">
+ <property name="severity" value="error"/>
+ </module>
+ <module name="SuperFinalize"/>
+ <module name="UnnecessaryParentheses">
+ <property name="severity" value="ignore"/>
+ <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+ </module>
+ <module name="Indentation">
+ <property name="severity" value="ignore"/>
+ <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+ </module>
+ <module name="StaticVariableName">
+ <property name="format" value="^[A-Za-z][a-zA-Z0-9]*$"/>
+ </module>
+ <module name="EmptyForInitializerPad"/>
+ <module name="EmptyForIteratorPad"/>
+ <module name="ModifierOrder"/>
+ <module name="DefaultComesLast"/>
+ <module name="InnerAssignment">
+ <property name="severity" value="ignore"/>
+ <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+ </module>
+ <module name="ModifiedControlVariable"/>
+ <module name="MutableException">
+ <property name="severity" value="ignore"/>
+ <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+ </module>
+ <module name="ParameterAssignment">
+ <property name="severity" value="ignore"/>
+ <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+ </module>
+ <module name="RegexpSinglelineJava">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Illegal trailing whitespace(s) at the end of the line."/>
+ <property name="format" value="\s$"/>
+ <property name="message" value="Illegal trailing whitespace(s) at the end of the line."/>
+ <property name="ignoreComments" value="true"/>
+ <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Checks for trailing spaces at the end of a line"/>
+ </module>
+ <module name="RegexpSinglelineJava">
+ <metadata name="net.sf.eclipsecs.core.comment" value="illegal space before a comma"/>
+ <property name="format" value=" ,"/>
+ <property name="message" value="illegal space before a comma"/>
+ <property name="ignoreComments" value="true"/>
+ <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Checks for whitespace before a comma."/>
+ <metadata name="com.atlassw.tools.eclipse.checkstyle.customMessage" value="Illegal whitespace before a comma."/>
+ </module>
+ <module name="RegexpSinglelineJava">
+ <property name="format" value="[^\x00-\x7F]"/>
+ <property name="message" value="Only use ASCII characters."/>
+ </module>
+ <module name="RegexpSinglelineJava">
+ <property name="format" value="new (Hashtable|Vector|Stack|StringBuffer)[^\w]"/>
+ <property name="message" value="Don't use old synchronized collection classes"/>
+ </module>
+ <module name="RegexpSinglelineJava">
+ <property name="format" value="instanceof MoveOp"/>
+ <property name="message" value="Do not use `op instanceof MoveOp`. Use `MoveOp.isMoveOp(op)` instead!"/>
+ </module>
+ <module name="RegexpSinglelineJava">
+ <property name="format" value="instanceof ValueMoveOp"/>
+ <property name="message" value="Do not use `op instanceof ValueMoveOp`. Use `ValueMoveOp.isValueMoveOp(op)` instead!"/>
+ </module>
+ <module name="RegexpSinglelineJava">
+ <property name="format" value="instanceof LoadConstantOp"/>
+ <property name="message" value="Do not use `op instanceof LoadConstantOp`. Use `LoadConstantOp.isLoadConstantOp(op)` instead!"/>
+ </module>
+ <module name="RegexpSinglelineJava">
+ <property name="format" value="\(MoveOp\)"/>
+ <property name="message" value="Do not cast directly to `MoveOp`. Use `MoveOp.asMoveOp(op)` instead!"/>
+ </module>
+ <module name="RegexpSinglelineJava">
+ <property name="format" value="\(ValueMoveOp\)"/>
+ <property name="message" value="Do not cast directly to `ValueMoveOp`. Use `ValueMoveOp.asValueMoveOp(op)` instead!"/>
+ </module>
+ <module name="RegexpSinglelineJava">
+ <property name="format" value="\(LoadConstantOp\)"/>
+ <property name="message" value="Do not cast directly to `LoadConstantOp`. Use `LoadConstantOp.asLoadConstantOp(op)` instead!"/>
+ </module>
+ </module>
+ <module name="RegexpHeader">
+ <property name="header" value="/\*\n \* Copyright \(c\) (20[0-9][0-9], )?20[0-9][0-9], Oracle and/or its affiliates. All rights reserved.\n \* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n \*\n \* This code is free software; you can redistribute it and/or modify it\n \* under the terms of the GNU General Public License version 2 only, as\n \* published by the Free Software Foundation. Oracle designates this\n \* particular file as subject to the "Classpath" exception as provided\n \* by Oracle in the LICENSE file that accompanied this code.\n \*\n \* This code is distributed in the hope that it will be useful, but WITHOUT\n \* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n \* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n \* version 2 for more details \(a copy is included in the LICENSE file that\n \* accompanied this code\).\n \*\n \* You should have received a copy of the GNU General Public License version\n \* 2 along with this work; if not, write to the Free Software Foundation,\n \* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n \*\n \* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n \* or visit www.oracle.com if you need additional information or have any\n \* questions.\n \*/\n"/>
+ <property name="fileExtensions" value="java"/>
+ </module>
+ <module name="FileTabCharacter">
+ <property name="severity" value="error"/>
+ <property name="fileExtensions" value="java"/>
+ </module>
+ <module name="NewlineAtEndOfFile">
+ <property name="lineSeparator" value="lf"/>
+ </module>
+ <module name="Translation"/>
+ <module name="SuppressionCommentFilter">
+ <property name="offCommentFormat" value="Checkstyle: stop constant name check"/>
+ <property name="onCommentFormat" value="Checkstyle: resume constant name check"/>
+ <property name="checkFormat" value="ConstantNameCheck"/>
+ <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Allow non-conforming constant names"/>
+ </module>
+ <module name="SuppressionCommentFilter">
+ <property name="offCommentFormat" value="Checkstyle: stop method name check"/>
+ <property name="onCommentFormat" value="Checkstyle: resume method name check"/>
+ <property name="checkFormat" value="MethodName"/>
+ <property name="checkC" value="false"/>
+ <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable method name checks"/>
+ </module>
+ <module name="SuppressionCommentFilter">
+ <property name="offCommentFormat" value="CheckStyle: stop parameter assignment check"/>
+ <property name="onCommentFormat" value="CheckStyle: resume parameter assignment check"/>
+ <property name="checkFormat" value="ParameterAssignment"/>
+ <property name="checkC" value="false"/>
+ <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable Parameter Assignment"/>
+ </module>
+ <module name="SuppressionCommentFilter">
+ <property name="offCommentFormat" value="Checkstyle: stop final variable check"/>
+ <property name="onCommentFormat" value="Checkstyle: resume final variable check"/>
+ <property name="checkFormat" value="FinalLocalVariable"/>
+ <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable final variable checks"/>
+ </module>
+ <module name="SuppressionCommentFilter">
+ <property name="offCommentFormat" value="Checkstyle: stop"/>
+ <property name="onCommentFormat" value="Checkstyle: resume"/>
+ <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable all checks"/>
+ </module>
+ <module name="SuppressionCommentFilter">
+ <property name="offCommentFormat" value="CheckStyle: stop inner assignment check"/>
+ <property name="onCommentFormat" value="CheckStyle: resume inner assignment check"/>
+ <property name="checkFormat" value="InnerAssignment"/>
+ <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable inner assignment checks"/>
+ </module>
+ <module name="SuppressionCommentFilter">
+ <property name="offCommentFormat" value="Checkstyle: stop field name check"/>
+ <property name="onCommentFormat" value="Checkstyle: resume field name check"/>
+ <property name="checkFormat" value="MemberName"/>
+ <property name="checkC" value="false"/>
+ <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable field name checks"/>
+ </module>
+ <module name="RegexpMultiline">
+ <metadata name="net.sf.eclipsecs.core.comment" value="illegal Windows line ending"/>
+ <property name="format" value="\r\n"/>
+ <property name="message" value="illegal Windows line ending"/>
+ </module>
+ <module name="SuppressionCommentFilter">
+ <property name="offCommentFormat" value="CheckStyle: stop header check"/>
+ <property name="onCommentFormat" value="CheckStyle: resume header check"/>
+ <property name="checkFormat" value=".*Header"/>
+ <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable header checks"/>
+ </module>
+ <module name="SuppressionCommentFilter">
+ <property name="offCommentFormat" value="CheckStyle: stop line length check"/>
+ <property name="onCommentFormat" value="CheckStyle: resume line length check"/>
+ <property name="checkFormat" value="LineLength"/>
+ </module>
+ <module name="SuppressionCommentFilter">
+ <property name="offCommentFormat" value="CheckStyle: start generated"/>
+ <property name="onCommentFormat" value="CheckStyle: stop generated"/>
+ <property name="checkFormat" value=".*Name|.*LineLength|.*Header"/>
+ </module>
+</module>
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java Wed Nov 08 16:03:35 2017 -0500
@@ -58,8 +58,6 @@
import java.util.stream.Collectors;
import jdk.internal.module.Checks;
-import jdk.internal.module.ClassFileAttributes;
-import jdk.internal.module.ClassFileConstants;
import jdk.internal.module.DefaultRoots;
import jdk.internal.module.IllegalAccessMaps;
import jdk.internal.module.ModuleHashes;
@@ -68,13 +66,13 @@
import jdk.internal.module.ModuleReferenceImpl;
import jdk.internal.module.ModuleResolution;
import jdk.internal.module.ModuleTarget;
-import jdk.internal.org.objectweb.asm.Attribute;
+
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
-
import static jdk.internal.org.objectweb.asm.Opcodes.*;
import jdk.tools.jlink.internal.ModuleSorter;
@@ -435,24 +433,25 @@
}
boolean hasModulePackages() throws IOException {
- Set<String> attrTypes = new HashSet<>();
- ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) {
+ Set<String> packages = new HashSet<>();
+ ClassVisitor cv = new ClassVisitor(Opcodes.ASM6) {
@Override
- public void visitAttribute(Attribute attr) {
- attrTypes.add(attr.type);
+ public ModuleVisitor visitModule(String name,
+ int flags,
+ String version) {
+ return new ModuleVisitor(Opcodes.ASM6) {
+ public void visitPackage(String pn) {
+ packages.add(pn);
+ }
+ };
}
};
- // prototype of attributes that should be parsed
- Attribute[] attrs = new Attribute[] {
- new ClassFileAttributes.ModulePackagesAttribute()
- };
-
try (InputStream in = getInputStream()) {
// parse module-info.class
ClassReader cr = new ClassReader(in);
- cr.accept(cv, attrs, 0);
- return attrTypes.contains(ClassFileConstants.MODULE_PACKAGES);
+ cr.accept(cv, 0);
+ return packages.size() > 0;
}
}
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/debug/InternalDebugControl.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/debug/InternalDebugControl.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -29,11 +29,10 @@
import jdk.jshell.JShell;
/**
-/**
* This class is used to externally control output messages for debugging the
* implementation of the JShell API.
* <p>
- * This is not part of the SPI, not API.
+ * This is not part of the SPI nor API.
*/
public class InternalDebugControl {
@@ -141,7 +140,7 @@
* @param ex the fatal Exception
* @param where additional context
*/
- public static void debug(JShell state, PrintStream err, Exception ex, String where) {
+ public static void debug(JShell state, PrintStream err, Throwable ex, String where) {
if (isDebugEnabled(state, 0xFFFFFFFF)) {
err.printf("Fatal error: %s: %s\n", where, ex.getMessage());
ex.printStackTrace(err);
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Wed Nov 08 16:03:35 2017 -0500
@@ -237,7 +237,11 @@
.distinct()
.count() == 2;
boolean tooManyItems = suggestions.size() > in.getAutoprintThreshold();
- CompletionTask ordinaryCompletion = new OrdinaryCompletionTask(suggestions, anchor[0], !command && !doc.isEmpty(), hasSmart);
+ CompletionTask ordinaryCompletion =
+ new OrdinaryCompletionTask(suggestions,
+ anchor[0],
+ !command && !doc.isEmpty(),
+ hasBoth);
CompletionTask allCompletion = new AllSuggestionsCompletionTask(suggestions, anchor[0]);
todo = new ArrayList<>();
@@ -439,16 +443,16 @@
private final List<Suggestion> suggestions;
private final int anchor;
private final boolean cont;
- private final boolean smart;
+ private final boolean showSmart;
public OrdinaryCompletionTask(List<Suggestion> suggestions,
int anchor,
boolean cont,
- boolean smart) {
+ boolean showSmart) {
this.suggestions = suggestions;
this.anchor = anchor;
this.cont = cont;
- this.smart = smart;
+ this.showSmart = showSmart;
}
@Override
@@ -460,7 +464,7 @@
public Result perform(String text, int cursor) throws IOException {
List<CharSequence> toShow;
- if (smart) {
+ if (showSmart) {
toShow =
suggestions.stream()
.filter(Suggestion::matchesType)
@@ -487,7 +491,7 @@
String prefixStr = prefix.orElse("").substring(cursor - anchor);
in.putString(prefixStr);
- boolean showItems = toShow.size() > 1 || smart;
+ boolean showItems = toShow.size() > 1 || showSmart;
if (showItems) {
in.println();
@@ -495,7 +499,7 @@
}
if (!prefixStr.isEmpty())
- return showItems ? Result.SKIP : Result.SKIP_NOREPAINT;
+ return showItems ? Result.FINISH : Result.SKIP_NOREPAINT;
return cont ? Result.CONTINUE : Result.FINISH;
}
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Wed Nov 08 16:03:35 2017 -0500
@@ -184,6 +184,7 @@
private IOContext input = null;
private boolean regenerateOnDeath = true;
private boolean live = false;
+ private boolean interactiveModeBegun = false;
private Options options;
SourceCodeAnalysis analysis;
@@ -499,9 +500,13 @@
@Override
void msg(String key, Object... args) {
- startmsg(key, args);
+ errormsg(key, args);
}
+ /**
+ * Parse the command line options.
+ * @return the options as an Options object, or null if error
+ */
@Override
Options parse(OptionSet options) {
if (options.has(argHelp)) {
@@ -541,7 +546,7 @@
if (options.has(argStart)) {
List<String> sts = options.valuesOf(argStart);
if (options.has("no-startup")) {
- startmsg("jshell.err.opt.startup.conflict");
+ msg("jshell.err.opt.startup.conflict");
return null;
}
initialStartup = Startup.fromFileList(sts, "--startup", new InitMessageHandler());
@@ -649,16 +654,6 @@
}
/**
- * Base output for command output -- no pre- or post-fix
- *
- * @param printf format
- * @param printf args
- */
- void rawout(String format, Object... args) {
- cmdout.printf(format, args);
- }
-
- /**
* Must show command output
*
* @param format printf format
@@ -666,17 +661,17 @@
*/
@Override
public void hard(String format, Object... args) {
- rawout(prefix(format), args);
+ cmdout.printf(prefix(format), args);
}
- /**
+ /**
* Error command output
*
* @param format printf format
* @param args printf args
*/
void error(String format, Object... args) {
- rawout(prefixError(format), args);
+ (interactiveModeBegun? cmdout : cmderr).printf(prefixError(format), args);
}
/**
@@ -749,7 +744,8 @@
/**
* Add prefixing/postfixing to embedded newlines in a string,
- * bracketing with prefix/postfix
+ * bracketing with prefix/postfix. No prefixing when non-interactive.
+ * Result is expected to be the format for a printf.
*
* @param s the string to prefix
* @param pre the string to prepend to each line
@@ -760,6 +756,10 @@
if (s == null) {
return "";
}
+ if (!interactiveModeBegun) {
+ // messages expect to be new-line terminated (even when not prefixed)
+ return s + "%n";
+ }
String pp = s.replaceAll("\\R", post + pre);
if (pp.endsWith(post + pre)) {
// prevent an extra prefix char and blank line when the string
@@ -810,21 +810,7 @@
*/
@Override
public void errormsg(String key, Object... args) {
- if (isRunningInteractive()) {
- rawout(prefixError(messageFormat(key, args)));
- } else {
- startmsg(key, args);
- }
- }
-
- /**
- * Print command-line error using resource bundle look-up, MessageFormat
- *
- * @param key the resource key
- * @param args
- */
- void startmsg(String key, Object... args) {
- cmderr.println(messageFormat(key, args));
+ error(messageFormat(key, args));
}
/**
@@ -847,7 +833,7 @@
LinkedHashMap::new));
for (Entry<String, String> e : a2b.entrySet()) {
hard("%s", e.getKey());
- rawout(prefix(e.getValue(), feedback.getPre() + "\t", feedback.getPost()));
+ cmdout.printf(prefix(e.getValue(), feedback.getPre() + "\t", feedback.getPost()));
}
}
@@ -899,7 +885,10 @@
replayableHistoryPrevious = ReplayableHistory.fromPrevious(prefs);
// load snippet/command files given on command-line
for (String loadFile : commandLineArgs.nonOptions()) {
- runFile(loadFile, "jshell");
+ if (!runFile(loadFile, "jshell")) {
+ // Load file failed -- abort
+ return;
+ }
}
// if we survived that...
if (regenerateOnDeath) {
@@ -909,6 +898,7 @@
// check again, as feedback setting could have failed
if (regenerateOnDeath) {
// if we haven't died, and the feedback mode wants fluff, print welcome
+ interactiveModeBegun = true;
if (feedback.shouldDisplayCommandFluff()) {
hardmsg("jshell.msg.welcome", version());
}
@@ -994,7 +984,7 @@
@Override
public void errormsg(String messageKey, Object... args) {
- startmsg(messageKey, args);
+ JShellTool.this.errormsg(messageKey, args);
}
@Override
@@ -1034,6 +1024,7 @@
shutdownSubscription = state.onShutdown((JShell deadState) -> {
if (deadState == state) {
hardmsg("jshell.msg.terminated");
+ fluffmsg("jshell.msg.terminated.restore");
live = false;
}
});
@@ -1056,10 +1047,6 @@
currentNameSpace = mainNamespace;
}
- private boolean isRunningInteractive() {
- return currentNameSpace != null && currentNameSpace == mainNamespace;
- }
-
//where -- one-time per run initialization of feedback modes
private void initFeedback(String initMode) {
// No fluff, no prefix, for init failures
@@ -1096,8 +1083,8 @@
try (IOContext suin = new ScannerIOContext(new StringReader(start))) {
run(suin);
} catch (Exception ex) {
- hardmsg("jshell.err.startup.unexpected.exception", ex);
- ex.printStackTrace(cmdout);
+ errormsg("jshell.err.startup.unexpected.exception", ex);
+ ex.printStackTrace(cmderr);
}
}
@@ -1123,7 +1110,7 @@
String incomplete = "";
while (live) {
String prompt;
- if (isRunningInteractive()) {
+ if (interactive()) {
prompt = testPrompt
? incomplete.isEmpty()
? "\u0005" //ENQ
@@ -1171,7 +1158,7 @@
}
private void addToReplayHistory(String s) {
- if (isRunningInteractive()) {
+ if (!isCurrentlyRunningStartup) {
replayableHistory.add(s);
}
}
@@ -2127,7 +2114,7 @@
fluff("Wrap debugging on");
break;
default:
- hard("Unknown debugging option: %c", ch);
+ error("Unknown debugging option: %c", ch);
fluff("Use: 0 r g f c d e w");
return false;
}
@@ -2697,7 +2684,7 @@
}
currSrcs = nextSrcs;
} catch (IllegalStateException ex) {
- hardmsg("jshell.msg.resetting");
+ errormsg("jshell.msg.resetting");
resetState();
currSrcs = new LinkedHashSet<>(); // re-process everything
}
@@ -2746,16 +2733,21 @@
private boolean runFile(String filename, String context) {
if (!filename.isEmpty()) {
try {
- Path path = toPathResolvingUserHome(filename);
- Reader reader;
- String resource;
- if (!Files.exists(path) && (resource = getResource(filename)) != null) {
- // Not found as file, but found as resource
- reader = new StringReader(resource);
+ Scanner scanner;
+ if (!interactiveModeBegun && filename.equals("-")) {
+ // - on command line: no interactive later, read from input
+ regenerateOnDeath = false;
+ scanner = new Scanner(cmdin);
} else {
- reader = new FileReader(path.toString());
+ Path path = toPathResolvingUserHome(filename);
+ String resource;
+ scanner = new Scanner(
+ (!Files.exists(path) && (resource = getResource(filename)) != null)
+ ? new StringReader(resource) // Not found as file, but found as resource
+ : new FileReader(path.toString())
+ );
}
- run(new ScannerIOContext(reader));
+ run(new ScannerIOContext(scanner));
return true;
} catch (FileNotFoundException e) {
errormsg("jshell.err.file.not.found", context, filename, e.getMessage());
@@ -2841,7 +2833,7 @@
sb.append(a);
}
if (sb.length() > 0) {
- rawout(prefix(sb.toString()));
+ hard(sb.toString());
}
return false;
}
@@ -3175,11 +3167,11 @@
if (ste.causeSnippet() == null) {
// main event
for (Diag d : diagnostics) {
- hardmsg(d.isError()? "jshell.msg.error" : "jshell.msg.warning");
+ errormsg(d.isError()? "jshell.msg.error" : "jshell.msg.warning");
List<String> disp = new ArrayList<>();
displayDiagnostics(source, d, disp);
disp.stream()
- .forEach(l -> hard("%s", l));
+ .forEach(l -> error("%s", l));
}
if (ste.status() != Status.REJECTED) {
@@ -3190,7 +3182,7 @@
} else if (ste.exception() instanceof UnresolvedReferenceException) {
printUnresolvedException((UnresolvedReferenceException) ste.exception());
} else {
- hard("Unexpected execution exception: %s", ste.exception());
+ error("Unexpected execution exception: %s", ste.exception());
return true;
}
} else {
@@ -3242,7 +3234,7 @@
: lineNumber >= 0
? fileName + ":" + lineNumber
: fileName;
- hard(" at %s(%s)", sb, loc);
+ error(" at %s(%s)", sb, loc);
}
}
@@ -3253,9 +3245,9 @@
//where
void printEvalException(EvalException ex) {
if (ex.getMessage() == null) {
- hard("%s thrown", ex.getExceptionClassName());
+ error("%s thrown", ex.getExceptionClassName());
} else {
- hard("%s thrown: %s", ex.getExceptionClassName(), ex.getMessage());
+ error("%s thrown: %s", ex.getExceptionClassName(), ex.getMessage());
}
printStackTrace(ex.getStackTrace());
}
@@ -3394,7 +3386,7 @@
resolution, unrcnt, errcnt,
name, type, value, unresolved, errorLines);
if (!resolutionErrors.trim().isEmpty()) {
- hard(" %s", resolutionErrors);
+ error(" %s", resolutionErrors);
}
} else if (interactive()) {
String display = feedback.format(fcase, action, update,
@@ -3625,7 +3617,6 @@
scannerIn.close();
}
- @Override
public int readUserInput() {
return -1;
}
@@ -3657,7 +3648,6 @@
public void close() {
}
- @Override
public int readUserInput() {
return -1;
}
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Wed Nov 08 16:03:35 2017 -0500
@@ -33,9 +33,8 @@
jshell.err.opt.feedback.one = Only one feedback option (--feedback, -q, -s, or -v) may be used.
jshell.err.opt.unknown = Unknown option: {0}
-jshell.msg.terminated =\
-State engine terminated.\n\
-Restore definitions with: /reload -restore
+jshell.msg.terminated = State engine terminated.
+jshell.msg.terminated.restore = Restore definitions with: /reload -restore
jshell.msg.use.one.of = Use one of: {0}
jshell.msg.see.classes.etc = See /types, /methods, /vars, or /list
@@ -189,7 +188,7 @@
/help shortcuts
help.usage = \
-Usage: jshell <options> <load files>\n\
+Usage: jshell <option>... <load file>...\n\
where possible options include:\n\
\ --class-path <path> Specify where to find user class files\n\
\ --module-path <path> Specify where to find application modules\n\
@@ -213,7 +212,11 @@
\ --version Print version information and exit\n\
\ --show-version Print version information and continue\n\
\ --help Print this synopsis of standard options and exit\n\
-\ --help-extra, -X Print help on non-standard options and exit\n
+\ --help-extra, -X Print help on non-standard options and exit\n\
+A file argument may be a file name, or one of the predefined file names: DEFAULT,\n\
+PRINTING, or JAVASE.\n\
+A load file may also be "-" to indicate standard input, without interactive I/O.\n
+
help.usage.x = \
\ --add-exports <module>/<package> Export specified module-private package to snippets\n\
\ --execution <spec> Specify an alternate execution engine.\n\
--- a/src/jdk.jshell/share/classes/jdk/jshell/Eval.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/Eval.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -48,6 +48,7 @@
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
+import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import jdk.jshell.ExpressionToTypeInfo.ExpressionInfo;
@@ -100,6 +101,12 @@
private final JShell state;
+ // The set of names of methods on Object
+ private final Set<String> objectMethods = Arrays
+ .stream(Object.class.getMethods())
+ .map(m -> m.getName())
+ .collect(toSet());
+
Eval(JShell state) {
this.state = state;
}
@@ -528,10 +535,26 @@
private List<Snippet> processMethod(String userSource, Tree unitTree, String compileSource, ParseTask pt) {
TreeDependencyScanner tds = new TreeDependencyScanner();
tds.scan(unitTree);
- TreeDissector dis = TreeDissector.createByFirstClass(pt);
+ final TreeDissector dis = TreeDissector.createByFirstClass(pt);
+
+ final MethodTree mt = (MethodTree) unitTree;
+ final String name = mt.getName().toString();
+ if (objectMethods.contains(name)) {
+ // The name matches a method on Object, short of an overhaul, this
+ // fails, see 8187137. Generate a descriptive error message
- MethodTree mt = (MethodTree) unitTree;
- String name = mt.getName().toString();
+ // The error position will be the position of the name, find it
+ long possibleStart = dis.getEndPosition(mt.getReturnType());
+ Range possibleRange = new Range((int) possibleStart,
+ dis.getStartPosition(mt.getBody()));
+ String possibleNameSection = possibleRange.part(compileSource);
+ int offset = possibleNameSection.indexOf(name);
+ long start = offset < 0
+ ? possibleStart // something wrong, punt
+ : possibleStart + offset;
+
+ return compileFailResult(new DiagList(objectMethodNameDiag(name, start)), userSource, Kind.METHOD);
+ }
String parameterTypes
= mt.getParameters()
.stream()
@@ -900,6 +923,47 @@
return PREFIX_PATTERN.matcher(ste.getClassName()).find();
}
+ /**
+ * Construct a diagnostic for a method name matching an Object method name
+ * @param name the method name
+ * @param nameStart the position within the source of the method name
+ * @return the generated diagnostic
+ */
+ private Diag objectMethodNameDiag(String name, long nameStart) {
+ return new Diag() {
+ @Override
+ public boolean isError() {
+ return true;
+ }
+
+ @Override
+ public long getPosition() {
+ return nameStart;
+ }
+
+ @Override
+ public long getStartPosition() {
+ return nameStart;
+ }
+
+ @Override
+ public long getEndPosition() {
+ return nameStart + name.length();
+ }
+
+ @Override
+ public String getCode() {
+ return "jdk.eval.error.object.method";
+ }
+
+ @Override
+ public String getMessage(Locale locale) {
+ return state.messageFormat("jshell.diag.object.method.fatal",
+ String.join(" ", objectMethods));
+ }
+ };
+ }
+
private DiagList modifierDiagnostics(ModifiersTree modtree,
final TreeDissector dis, boolean isAbstractProhibited) {
--- a/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Wed Nov 08 16:03:35 2017 -0500
@@ -807,7 +807,7 @@
InternalDebugControl.debug(this, err, flags, format, args);
}
- void debug(Exception ex, String where) {
+ void debug(Throwable ex, String where) {
InternalDebugControl.debug(this, err, ex, where);
}
--- a/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -58,7 +58,6 @@
import com.sun.tools.javac.util.Pair;
import jdk.jshell.CompletenessAnalyzer.CaInfo;
import jdk.jshell.TaskFactory.AnalyzeTask;
-import jdk.jshell.TaskFactory.ParseTask;
import java.util.ArrayList;
import java.util.Collections;
@@ -255,6 +254,9 @@
suspendIndexing();
try {
return completionSuggestionsImpl(code, cursor, anchor);
+ } catch (Throwable exc) {
+ proc.debug(exc, "Exception thrown in SourceCodeAnalysisImpl.completionSuggestions");
+ return Collections.emptyList();
} finally {
resumeIndexing();
}
@@ -1148,6 +1150,9 @@
suspendIndexing();
try {
return documentationImpl(code, cursor, computeJavadoc);
+ } catch (Throwable exc) {
+ proc.debug(exc, "Exception thrown in SourceCodeAnalysisImpl.documentation");
+ return Collections.emptyList();
} finally {
resumeIndexing();
}
--- a/src/jdk.jshell/share/classes/jdk/jshell/resources/l10n.properties Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/resources/l10n.properties Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -27,6 +27,7 @@
jshell.diag.modifier.plural.ignore = Modifiers {0} not permitted in top-level declarations, ignored
jshell.diag.modifier.single.fatal = Modifier {0} not permitted in top-level declarations
jshell.diag.modifier.single.ignore = Modifier {0} not permitted in top-level declarations, ignored
+jshell.diag.object.method.fatal = JShell method names must not match Object methods: {0}
jshell.exc.null = Snippet must not be null
jshell.exc.alien = Snippet not from this JShell: {0}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/Main.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.rmic/share/classes/sun/rmi/rmic/Main.java Wed Nov 08 16:03:35 2017 -0500
@@ -139,21 +139,6 @@
*/
public synchronized boolean compile(String argv[]) {
- /*
- * Handle internal option to use the new (and incomplete) rmic
- * implementation. This option is handled here, rather than
- * in parseArgs, so that none of the arguments will be nulled
- * before delegating to the new implementation.
- */
- // disable the -Xnew option as per JDK-8146299 and JDK-8145980
- // to allow further discussion how to progress with this feature
- //for (int i = 0; i < argv.length; i++) {
- // if (argv[i].equals("-Xnew")) {
- // return (new sun.rmi.rmic.newrmic.Main(out,
- // program)).compile(argv);
- // }
- //}
-
if (!parseArgs(argv)) {
return false;
}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/BatchEnvironment.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic;
-
-import com.sun.javadoc.ClassDoc;
-import com.sun.javadoc.RootDoc;
-import java.io.File;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import static sun.rmi.rmic.newrmic.Constants.*;
-
-/**
- * The environment for an rmic compilation batch.
- *
- * A BatchEnvironment contains a RootDoc, which is the entry point
- * into the doclet environment for the associated rmic compilation
- * batch. A BatchEnvironment collects the source files generated
- * during the batch's execution, for eventual source code compilation
- * and, possibly, deletion. Errors that occur during generation
- * activity should be reported through the BatchEnvironment's "error"
- * method.
- *
- * A protocol-specific generator class may require the use of a
- * particular BatchEnvironment subclass for enhanced environment
- * functionality. A BatchEnvironment subclass must declare a
- * public constructor with one parameter of type RootDoc.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API. Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-public class BatchEnvironment {
-
- private final RootDoc rootDoc;
-
- /** cached ClassDoc for certain types used by rmic */
- private final ClassDoc docRemote;
- private final ClassDoc docException;
- private final ClassDoc docRemoteException;
- private final ClassDoc docRuntimeException;
-
- private boolean verbose = false;
- private final List<File> generatedFiles = new ArrayList<File>();
-
- /**
- * Creates a new BatchEnvironment with the specified RootDoc.
- **/
- public BatchEnvironment(RootDoc rootDoc) {
- this.rootDoc = rootDoc;
-
- /*
- * Initialize cached ClassDoc for types used by rmic. Note
- * that any of these could be null if the boot class path is
- * incorrect, which could cause a NullPointerException later.
- */
- docRemote = rootDoc().classNamed(REMOTE);
- docException = rootDoc().classNamed(EXCEPTION);
- docRemoteException = rootDoc().classNamed(REMOTE_EXCEPTION);
- docRuntimeException = rootDoc().classNamed(RUNTIME_EXCEPTION);
- }
-
- /**
- * Returns the RootDoc for this environment.
- **/
- public RootDoc rootDoc() {
- return rootDoc;
- }
-
- public ClassDoc docRemote() { return docRemote; }
- public ClassDoc docException() { return docException; }
- public ClassDoc docRemoteException() { return docRemoteException; }
- public ClassDoc docRuntimeException() { return docRuntimeException; }
-
- /**
- * Sets this environment's verbosity status.
- **/
- public void setVerbose(boolean verbose) {
- this.verbose = verbose;
- }
-
- /**
- * Returns this environment's verbosity status.
- **/
- public boolean verbose() {
- return verbose;
- }
-
- /**
- * Adds the specified file to the list of source files generated
- * during this batch.
- **/
- public void addGeneratedFile(File file) {
- generatedFiles.add(file);
- }
-
- /**
- * Returns the list of files generated during this batch.
- **/
- public List<File> generatedFiles() {
- return Collections.unmodifiableList(generatedFiles);
- }
-
- /**
- * Outputs the specified (non-error) message.
- **/
- public void output(String msg) {
- rootDoc.printNotice(msg);
- }
-
- /**
- * Reports an error using the specified resource key and text
- * formatting arguments.
- **/
- public void error(String key, String... args) {
- rootDoc.printError(Resources.getText(key, args));
- }
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/Constants.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic;
-
-/**
- * Constants potentially useful to all rmic generators.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API. Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-public final class Constants {
-
- private Constants() { throw new AssertionError(); }
-
- /*
- * fully-qualified names of types used by rmic
- */
- public static final String REMOTE = "java.rmi.Remote";
- public static final String EXCEPTION = "java.lang.Exception";
- public static final String REMOTE_EXCEPTION = "java.rmi.RemoteException";
- public static final String RUNTIME_EXCEPTION = "java.lang.RuntimeException";
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/Generator.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic;
-
-import com.sun.javadoc.ClassDoc;
-import java.io.File;
-import java.util.Set;
-
-/**
- * The interface to rmic back end implementations. Classes that
- * implement this interface correspond to the various generation modes
- * of rmic (JRMP, IIOP, IDL, etc.).
- *
- * A Generator instance corresponds to a particular rmic compilation
- * batch, and its instance state represents the generator-specific
- * command line options for that batch. Main will instantiate a
- * generator class when the command line arguments indicate selection
- * of the corresponding generation mode. Main will then invoke the
- * "parseArgs" method to allow the generator to process any
- * generator-specific command line options and set its instance state
- * accordingly.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API. Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-public interface Generator {
-
- /**
- * Processes the command line options specific to this generator.
- * Processed options are set to null in the specified array.
- * Returns true if successful or false if an error occurs. Errors
- * are output to the specific Main instance.
- **/
- public boolean parseArgs(String[] args, Main main);
-
- /**
- * Returns the most specific environment class required by this
- * generator.
- **/
- public Class<? extends BatchEnvironment> envClass();
-
- /**
- * Returns the names of the classes that must be available through
- * the doclet API in order for this generator to function.
- **/
- public Set<String> bootstrapClassNames();
-
- /**
- * Generates the protocol-specific rmic output files for the
- * specified remote class. This method is invoked once for each
- * class or interface specified on the command line for the rmic
- * compilation batch associated with this instance.
- *
- * Any generated source files (to be compiled with javac) are
- * passed to the addGeneratedFile method of the specified
- * BatchEnvironment.
- **/
- public void generate(BatchEnvironment env,
- ClassDoc inputClass,
- File destDir);
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/IndentingWriter.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,291 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic;
-
-import java.io.Writer;
-import java.io.BufferedWriter;
-import java.io.IOException;
-
-/**
- * A BufferedWriter that supports automatic indentation of lines of
- * text written to the underlying Writer.
- *
- * Methods are provided for compact/convenient indenting in and out,
- * writing text, and writing lines of text in various combinations.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API. Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-public class IndentingWriter extends BufferedWriter {
-
- /** number of spaces to change indent when indenting in or out */
- private final int indentStep;
-
- /** number of spaces to convert into tabs (use MAX_VALUE to disable) */
- private final int tabSize;
-
- /** true if the next character written is the first on a line */
- private boolean beginningOfLine = true;
-
- /** current number of spaces to prepend to lines */
- private int currentIndent = 0;
-
- /**
- * Creates a new IndentingWriter that writes indented text to the
- * given Writer. Use the default indent step of four spaces.
- **/
- public IndentingWriter(Writer out) {
- this(out, 4);
- }
-
- /**
- * Creates a new IndentingWriter that writes indented text to the
- * given Writer and uses the supplied indent step.
- **/
- public IndentingWriter(Writer out, int indentStep) {
- this(out, indentStep, 8);
- }
-
- /**
- * Creates a new IndentingWriter that writes indented text to the
- * given Writer and uses the supplied indent step and tab size.
- **/
- public IndentingWriter(Writer out, int indentStep, int tabSize) {
- super(out);
- if (indentStep < 0) {
- throw new IllegalArgumentException("negative indent step");
- }
- if (tabSize < 0) {
- throw new IllegalArgumentException("negative tab size");
- }
- this.indentStep = indentStep;
- this.tabSize = tabSize;
- }
-
- /**
- * Writes a single character.
- **/
- public void write(int c) throws IOException {
- checkWrite();
- super.write(c);
- }
-
- /**
- * Writes a portion of an array of characters.
- **/
- public void write(char[] cbuf, int off, int len) throws IOException {
- if (len > 0) {
- checkWrite();
- }
- super.write(cbuf, off, len);
- }
-
- /**
- * Writes a portion of a String.
- **/
- public void write(String s, int off, int len) throws IOException {
- if (len > 0) {
- checkWrite();
- }
- super.write(s, off, len);
- }
-
- /**
- * Writes a line separator. The next character written will be
- * preceded by an indent.
- **/
- public void newLine() throws IOException {
- super.newLine();
- beginningOfLine = true;
- }
-
- /**
- * Checks if an indent needs to be written before writing the next
- * character.
- *
- * The indent generation is optimized (and made consistent with
- * certain coding conventions) by condensing groups of eight
- * spaces into tab characters.
- **/
- protected void checkWrite() throws IOException {
- if (beginningOfLine) {
- beginningOfLine = false;
- int i = currentIndent;
- while (i >= tabSize) {
- super.write('\t');
- i -= tabSize;
- }
- while (i > 0) {
- super.write(' ');
- i--;
- }
- }
- }
-
- /**
- * Increases the current indent by the indent step.
- **/
- protected void indentIn() {
- currentIndent += indentStep;
- }
-
- /**
- * Decreases the current indent by the indent step.
- **/
- protected void indentOut() {
- currentIndent -= indentStep;
- if (currentIndent < 0)
- currentIndent = 0;
- }
-
- /**
- * Indents in.
- **/
- public void pI() {
- indentIn();
- }
-
- /**
- * Indents out.
- **/
- public void pO() {
- indentOut();
- }
-
- /**
- * Writes string.
- **/
- public void p(String s) throws IOException {
- write(s);
- }
-
- /**
- * Ends current line.
- **/
- public void pln() throws IOException {
- newLine();
- }
-
- /**
- * Writes string; ends current line.
- **/
- public void pln(String s) throws IOException {
- p(s);
- pln();
- }
-
- /**
- * Writes string; ends current line; indents in.
- **/
- public void plnI(String s) throws IOException {
- p(s);
- pln();
- pI();
- }
-
- /**
- * Indents out; writes string.
- **/
- public void pO(String s) throws IOException {
- pO();
- p(s);
- }
-
- /**
- * Indents out; writes string; ends current line.
- **/
- public void pOln(String s) throws IOException {
- pO(s);
- pln();
- }
-
- /**
- * Indents out; writes string; ends current line; indents in.
- *
- * This method is useful for generating lines of code that both
- * end and begin nested blocks, like "} else {".
- **/
- public void pOlnI(String s) throws IOException {
- pO(s);
- pln();
- pI();
- }
-
- /**
- * Writes object.
- **/
- public void p(Object o) throws IOException {
- write(o.toString());
- }
-
- /**
- * Writes object; ends current line.
- **/
- public void pln(Object o) throws IOException {
- p(o.toString());
- pln();
- }
-
- /**
- * Writes object; ends current line; indents in.
- **/
- public void plnI(Object o) throws IOException {
- p(o.toString());
- pln();
- pI();
- }
-
- /**
- * Indents out; writes object.
- **/
- public void pO(Object o) throws IOException {
- pO();
- p(o.toString());
- }
-
- /**
- * Indents out; writes object; ends current line.
- **/
- public void pOln(Object o) throws IOException {
- pO(o.toString());
- pln();
- }
-
- /**
- * Indents out; writes object; ends current line; indents in.
- *
- * This method is useful for generating lines of code that both
- * end and begin nested blocks, like "} else {".
- **/
- public void pOlnI(Object o) throws IOException {
- pO(o.toString());
- pln();
- pI();
- }
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/Main.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,689 +0,0 @@
-/*
- * Copyright (c) 2003, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic;
-
-import com.sun.javadoc.ClassDoc;
-import com.sun.javadoc.RootDoc;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import sun.rmi.rmic.newrmic.jrmp.JrmpGenerator;
-import sun.tools.util.CommandLine;
-
-/**
- * The rmic front end. This class contains the "main" method for rmic
- * command line invocation.
- *
- * A Main instance contains the stream to output error messages and
- * other diagnostics to.
- *
- * An rmic compilation batch (for example, one rmic command line
- * invocation) is executed by invoking the "compile" method of a Main
- * instance.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API. Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * NOTE: If and when there is a J2SE API for invoking SDK tools, this
- * class should be updated to support that API.
- *
- * NOTE: This class is the front end for a "new" rmic implementation,
- * which uses javadoc and the doclet API for reading class files and
- * javac for compiling generated source files. This implementation is
- * incomplete: it lacks any CORBA-based back end implementations, and
- * thus the command line options "-idl", "-iiop", and their related
- * options are not yet supported. The front end for the "old",
- * oldjavac-based rmic implementation is sun.rmi.rmic.Main.
- *
- * @author Peter Jones
- **/
-public class Main {
-
- /*
- * Implementation note:
- *
- * In order to use the doclet API to read class files, much of
- * this implementation of rmic executes as a doclet within an
- * invocation of javadoc. This class is used as the doclet class
- * for such javadoc invocations, via its static "start" and
- * "optionLength" methods. There is one javadoc invocation per
- * rmic compilation batch.
- *
- * The only guaranteed way to pass data to a doclet through a
- * javadoc invocation is through doclet-specific options on the
- * javadoc "command line". Rather than passing numerous pieces of
- * individual data in string form as javadoc options, we use a
- * single doclet-specific option ("-batchID") to pass a numeric
- * identifier that uniquely identifies the rmic compilation batch
- * that the javadoc invocation is for, and that identifier can
- * then be used as a key in a global table to retrieve an object
- * containing all of batch-specific data (rmic command line
- * arguments, etc.).
- */
-
- /** guards "batchCount" */
- private static final Object batchCountLock = new Object();
-
- /** number of batches run; used to generated batch IDs */
- private static long batchCount = 0;
-
- /** maps batch ID to batch data */
- private static final Map<Long,Batch> batchTable =
- Collections.synchronizedMap(new HashMap<Long,Batch>());
-
- /** stream to output error messages and other diagnostics to */
- private final PrintStream out;
-
- /** name of this program, to use in error messages */
- private final String program;
-
- /**
- * Command line entry point.
- **/
- public static void main(String[] args) {
- Main rmic = new Main(System.err, "rmic");
- System.exit(rmic.compile(args) ? 0 : 1);
- }
-
- /**
- * Creates a Main instance that writes output to the specified
- * stream. The specified program name is used in error messages.
- **/
- public Main(OutputStream out, String program) {
- this.out = out instanceof PrintStream ?
- (PrintStream) out : new PrintStream(out);
- this.program = program;
- }
-
- /**
- * Compiles a batch of input classes, as given by the specified
- * command line arguments. Protocol-specific generators are
- * determined by the choice options on the command line. Returns
- * true if successful, or false if an error occurred.
- *
- * NOTE: This method is retained for transitional consistency with
- * previous implementations.
- **/
- public boolean compile(String[] args) {
- long startTime = System.currentTimeMillis();
-
- long batchID;
- synchronized (batchCountLock) {
- batchID = batchCount++; // assign batch ID
- }
-
- // process command line
- Batch batch = parseArgs(args);
- if (batch == null) {
- return false; // terminate if error occurred
- }
-
- /*
- * With the batch data retrievable in the global table, run
- * javadoc to continue the rest of the batch's compliation as
- * a doclet.
- */
- boolean status;
- try {
- batchTable.put(batchID, batch);
- status = invokeJavadoc(batch, batchID);
- } finally {
- batchTable.remove(batchID);
- }
-
- if (batch.verbose) {
- long deltaTime = System.currentTimeMillis() - startTime;
- output(Resources.getText("rmic.done_in",
- Long.toString(deltaTime)));
- }
-
- return status;
- }
-
- /**
- * Prints the specified string to the output stream of this Main
- * instance.
- **/
- public void output(String msg) {
- out.println(msg);
- }
-
- /**
- * Prints an error message to the output stream of this Main
- * instance. The first argument is used as a key in rmic's
- * resource bundle, and the rest of the arguments are used as
- * arguments in the formatting of the resource string.
- **/
- public void error(String msg, String... args) {
- output(Resources.getText(msg, args));
- }
-
- /**
- * Prints rmic's usage message to the output stream of this Main
- * instance.
- *
- * This method is public so that it can be used by the "parseArgs"
- * methods of Generator implementations.
- **/
- public void usage() {
- error("rmic.usage", program);
- }
-
- /**
- * Processes rmic command line arguments. Returns a Batch object
- * representing the command line arguments if successful, or null
- * if an error occurred. Processed elements of the args array are
- * set to null.
- **/
- private Batch parseArgs(String[] args) {
- Batch batch = new Batch();
-
- /*
- * Pre-process command line for @file arguments.
- */
- try {
- args = CommandLine.parse(args);
- } catch (FileNotFoundException e) {
- error("rmic.cant.read", e.getMessage());
- return null;
- } catch (IOException e) {
- e.printStackTrace(out);
- return null;
- }
-
- for (int i = 0; i < args.length; i++) {
-
- if (args[i] == null) {
- // already processed by a generator
- continue;
-
- } else if (args[i].equals("-Xnew")) {
- // we're already using the "new" implementation
- args[i] = null;
-
- } else if (args[i].equals("-show")) {
- // obselete: fail
- error("rmic.option.unsupported", args[i]);
- usage();
- return null;
-
- } else if (args[i].equals("-O")) {
- // obselete: warn but tolerate
- error("rmic.option.unsupported", args[i]);
- args[i] = null;
-
- } else if (args[i].equals("-debug")) {
- // obselete: warn but tolerate
- error("rmic.option.unsupported", args[i]);
- args[i] = null;
-
- } else if (args[i].equals("-depend")) {
- // obselete: warn but tolerate
- // REMIND: should this fail instead?
- error("rmic.option.unsupported", args[i]);
- args[i] = null;
-
- } else if (args[i].equals("-keep") ||
- args[i].equals("-keepgenerated"))
- {
- batch.keepGenerated = true;
- args[i] = null;
-
- } else if (args[i].equals("-g")) {
- batch.debug = true;
- args[i] = null;
-
- } else if (args[i].equals("-nowarn")) {
- batch.noWarn = true;
- args[i] = null;
-
- } else if (args[i].equals("-nowrite")) {
- batch.noWrite = true;
- args[i] = null;
-
- } else if (args[i].equals("-verbose")) {
- batch.verbose = true;
- args[i] = null;
-
- } else if (args[i].equals("-Xnocompile")) {
- batch.noCompile = true;
- batch.keepGenerated = true;
- args[i] = null;
-
- } else if (args[i].equals("-bootclasspath")) {
- if ((i + 1) >= args.length) {
- error("rmic.option.requires.argument", args[i]);
- usage();
- return null;
- }
- if (batch.bootClassPath != null) {
- error("rmic.option.already.seen", args[i]);
- usage();
- return null;
- }
- args[i] = null;
- batch.bootClassPath = args[++i];
- assert batch.bootClassPath != null;
- args[i] = null;
-
- } else if (args[i].equals("-extdirs")) {
- if ((i + 1) >= args.length) {
- error("rmic.option.requires.argument", args[i]);
- usage();
- return null;
- }
- if (batch.extDirs != null) {
- error("rmic.option.already.seen", args[i]);
- usage();
- return null;
- }
- args[i] = null;
- batch.extDirs = args[++i];
- assert batch.extDirs != null;
- args[i] = null;
-
- } else if (args[i].equals("-classpath")) {
- if ((i + 1) >= args.length) {
- error("rmic.option.requires.argument", args[i]);
- usage();
- return null;
- }
- if (batch.classPath != null) {
- error("rmic.option.already.seen", args[i]);
- usage();
- return null;
- }
- args[i] = null;
- batch.classPath = args[++i];
- assert batch.classPath != null;
- args[i] = null;
-
- } else if (args[i].equals("-d")) {
- if ((i + 1) >= args.length) {
- error("rmic.option.requires.argument", args[i]);
- usage();
- return null;
- }
- if (batch.destDir != null) {
- error("rmic.option.already.seen", args[i]);
- usage();
- return null;
- }
- args[i] = null;
- batch.destDir = new File(args[++i]);
- assert batch.destDir != null;
- args[i] = null;
- if (!batch.destDir.exists()) {
- error("rmic.no.such.directory", batch.destDir.getPath());
- usage();
- return null;
- }
-
- } else if (args[i].equals("-v1.1") ||
- args[i].equals("-vcompat") ||
- args[i].equals("-v1.2"))
- {
- Generator gen = new JrmpGenerator();
- batch.generators.add(gen);
- // JrmpGenerator only requires base BatchEnvironment class
- if (!gen.parseArgs(args, this)) {
- return null;
- }
-
- } else if (args[i].equalsIgnoreCase("-iiop")) {
- error("rmic.option.unimplemented", args[i]);
- return null;
-
- // Generator gen = new IiopGenerator();
- // batch.generators.add(gen);
- // if (!batch.envClass.isAssignableFrom(gen.envClass())) {
- // error("rmic.cannot.use.both",
- // batch.envClass.getName(), gen.envClass().getName());
- // return null;
- // }
- // batch.envClass = gen.envClass();
- // if (!gen.parseArgs(args, this)) {
- // return null;
- // }
-
- } else if (args[i].equalsIgnoreCase("-idl")) {
- error("rmic.option.unimplemented", args[i]);
- return null;
-
- // see implementation sketch above
-
- } else if (args[i].equalsIgnoreCase("-xprint")) {
- error("rmic.option.unimplemented", args[i]);
- return null;
-
- // see implementation sketch above
- }
- }
-
- /*
- * At this point, all that remains non-null in the args
- * array are input class names or illegal options.
- */
- for (int i = 0; i < args.length; i++) {
- if (args[i] != null) {
- if (args[i].startsWith("-")) {
- error("rmic.no.such.option", args[i]);
- usage();
- return null;
- } else {
- batch.classes.add(args[i]);
- }
- }
- }
- if (batch.classes.isEmpty()) {
- usage();
- return null;
- }
-
- /*
- * If options did not specify at least one protocol-specific
- * generator, then JRMP is the default.
- */
- if (batch.generators.isEmpty()) {
- batch.generators.add(new JrmpGenerator());
- }
- return batch;
- }
-
- /**
- * Doclet class entry point.
- **/
- public static boolean start(RootDoc rootDoc) {
-
- /*
- * Find batch ID among javadoc options, and retrieve
- * corresponding batch data from global table.
- */
- long batchID = -1;
- for (String[] option : rootDoc.options()) {
- if (option[0].equals("-batchID")) {
- try {
- batchID = Long.parseLong(option[1]);
- } catch (NumberFormatException e) {
- throw new AssertionError(e);
- }
- }
- }
- Batch batch = batchTable.get(batchID);
- assert batch != null;
-
- /*
- * Construct batch environment using class agreed upon by
- * generator implementations.
- */
- BatchEnvironment env;
- try {
- Constructor<? extends BatchEnvironment> cons =
- batch.envClass.getConstructor(new Class<?>[] { RootDoc.class });
- env = cons.newInstance(rootDoc);
- } catch (NoSuchMethodException e) {
- throw new AssertionError(e);
- } catch (IllegalAccessException e) {
- throw new AssertionError(e);
- } catch (InstantiationException e) {
- throw new AssertionError(e);
- } catch (InvocationTargetException e) {
- throw new AssertionError(e);
- }
-
- env.setVerbose(batch.verbose);
-
- /*
- * Determine the destination directory (the top of the package
- * hierarchy) for the output of this batch; if no destination
- * directory was specified on the command line, then the
- * default is the current working directory.
- */
- File destDir = batch.destDir;
- if (destDir == null) {
- destDir = new File(System.getProperty("user.dir"));
- }
-
- /*
- * Run each input class through each generator.
- */
- for (String inputClassName : batch.classes) {
- ClassDoc inputClass = rootDoc.classNamed(inputClassName);
- try {
- for (Generator gen : batch.generators) {
- gen.generate(env, inputClass, destDir);
- }
- } catch (NullPointerException e) {
- /*
- * We assume that this means that some class that was
- * needed (perhaps even a bootstrap class) was not
- * found, and that javadoc has already reported this
- * as an error. There is nothing for us to do here
- * but try to continue with the next input class.
- *
- * REMIND: More explicit error checking throughout
- * would be preferable, however.
- */
- }
- }
-
- /*
- * Compile any generated source files, if configured to do so.
- */
- boolean status = true;
- List<File> generatedFiles = env.generatedFiles();
- if (!batch.noCompile && !batch.noWrite && !generatedFiles.isEmpty()) {
- status = batch.enclosingMain().invokeJavac(batch, generatedFiles);
- }
-
- /*
- * Delete any generated source files, if configured to do so.
- */
- if (!batch.keepGenerated) {
- for (File file : generatedFiles) {
- file.delete();
- }
- }
-
- return status;
- }
-
- /**
- * Doclet class method that indicates that this doclet class
- * recognizes (only) the "-batchID" option on the javadoc command
- * line, and that the "-batchID" option comprises two arguments on
- * the javadoc command line.
- **/
- public static int optionLength(String option) {
- if (option.equals("-batchID")) {
- return 2;
- } else {
- return 0;
- }
- }
-
- /**
- * Runs the javadoc tool to invoke this class as a doclet, passing
- * command line options derived from the specified batch data and
- * indicating the specified batch ID.
- *
- * NOTE: This method currently uses a J2SE-internal API to run
- * javadoc. If and when there is a J2SE API for invoking SDK
- * tools, this method should be updated to use that API instead.
- **/
- private boolean invokeJavadoc(Batch batch, long batchID) {
- List<String> javadocArgs = new ArrayList<String>();
-
- // include all types, regardless of language-level access
- javadocArgs.add("-private");
-
- // inputs are class names, not source files
- javadocArgs.add("-Xclasses");
-
- // reproduce relevant options from rmic invocation
- if (batch.verbose) {
- javadocArgs.add("-verbose");
- }
- if (batch.bootClassPath != null) {
- javadocArgs.add("-bootclasspath");
- javadocArgs.add(batch.bootClassPath);
- }
- if (batch.extDirs != null) {
- javadocArgs.add("-extdirs");
- javadocArgs.add(batch.extDirs);
- }
- if (batch.classPath != null) {
- javadocArgs.add("-classpath");
- javadocArgs.add(batch.classPath);
- }
-
- // specify batch ID
- javadocArgs.add("-batchID");
- javadocArgs.add(Long.toString(batchID));
-
- /*
- * Run javadoc on union of rmic input classes and all
- * generators' bootstrap classes, so that they will all be
- * available to the doclet code.
- */
- Set<String> classNames = new HashSet<String>();
- for (Generator gen : batch.generators) {
- classNames.addAll(gen.bootstrapClassNames());
- }
- classNames.addAll(batch.classes);
- for (String s : classNames) {
- javadocArgs.add(s);
- }
-
- // run javadoc with our program name and output stream
- int status = com.sun.tools.javadoc.Main.execute(
- program,
- new PrintWriter(out, true),
- new PrintWriter(out, true),
- new PrintWriter(out, true),
- this.getClass().getName(), // doclet class is this class
- javadocArgs.toArray(new String[javadocArgs.size()]));
- return status == 0;
- }
-
- /**
- * Runs the javac tool to compile the specified source files,
- * passing command line options derived from the specified batch
- * data.
- *
- * NOTE: This method currently uses a J2SE-internal API to run
- * javac. If and when there is a J2SE API for invoking SDK tools,
- * this method should be updated to use that API instead.
- **/
- private boolean invokeJavac(Batch batch, List<File> files) {
- List<String> javacArgs = new ArrayList<String>();
-
- // rmic never wants to display javac warnings
- javacArgs.add("-nowarn");
-
- // reproduce relevant options from rmic invocation
- if (batch.debug) {
- javacArgs.add("-g");
- }
- if (batch.verbose) {
- javacArgs.add("-verbose");
- }
- if (batch.bootClassPath != null) {
- javacArgs.add("-bootclasspath");
- javacArgs.add(batch.bootClassPath);
- }
- if (batch.extDirs != null) {
- javacArgs.add("-extdirs");
- javacArgs.add(batch.extDirs);
- }
- if (batch.classPath != null) {
- javacArgs.add("-classpath");
- javacArgs.add(batch.classPath);
- }
-
- /*
- * For now, rmic still always produces class files that have a
- * class file format version compatible with JDK 1.1.
- */
- javacArgs.add("-source");
- javacArgs.add("1.3");
- javacArgs.add("-target");
- javacArgs.add("1.1");
-
- // add source files to compile
- for (File file : files) {
- javacArgs.add(file.getPath());
- }
-
- // run javac with our output stream
- int status = com.sun.tools.javac.Main.compile(
- javacArgs.toArray(new String[javacArgs.size()]),
- new PrintWriter(out, true));
- return status == 0;
- }
-
- /**
- * The data for an rmic compliation batch: the processed command
- * line arguments.
- **/
- private class Batch {
- boolean keepGenerated = false; // -keep or -keepgenerated
- boolean debug = false; // -g
- boolean noWarn = false; // -nowarn
- boolean noWrite = false; // -nowrite
- boolean verbose = false; // -verbose
- boolean noCompile = false; // -Xnocompile
- String bootClassPath = null; // -bootclasspath
- String extDirs = null; // -extdirs
- String classPath = null; // -classpath
- File destDir = null; // -d
- List<Generator> generators = new ArrayList<Generator>();
- Class<? extends BatchEnvironment> envClass = BatchEnvironment.class;
- List<String> classes = new ArrayList<String>();
-
- Batch() { }
-
- /**
- * Returns the Main instance for this batch.
- **/
- Main enclosingMain() {
- return Main.this;
- }
- }
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/Resources.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2003, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic;
-
-import java.text.MessageFormat;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-/**
- * Provides resource support for rmic.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API. Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-public final class Resources {
-
- private static ResourceBundle resources = null;
- private static ResourceBundle resourcesExt = null;
- static {
- try {
- resources =
- ResourceBundle.getBundle("sun.rmi.rmic.resources.rmic");
- } catch (MissingResourceException e) {
- // gracefully handle this later
- }
- try {
- resourcesExt =
- ResourceBundle.getBundle("sun.rmi.rmic.resources.rmicext");
- } catch (MissingResourceException e) {
- // OK if this isn't found
- }
- }
-
- private Resources() { throw new AssertionError(); }
-
- /**
- * Returns the text of the rmic resource for the specified key
- * formatted with the specified arguments.
- **/
- public static String getText(String key, String... args) {
- String format = getString(key);
- if (format == null) {
- format = "missing resource key: key = \"" + key + "\", " +
- "arguments = \"{0}\", \"{1}\", \"{2}\"";
- }
- return MessageFormat.format(format, (Object[]) args);
- }
-
- /**
- * Returns the rmic resource string for the specified key.
- **/
- private static String getString(String key) {
- if (resourcesExt != null) {
- try {
- return resourcesExt.getString(key);
- } catch (MissingResourceException e) {
- }
- }
- if (resources != null) {
- try {
- return resources.getString(key);
- } catch (MissingResourceException e) {
- return null;
- }
- }
- return "missing resource bundle: key = \"" + key + "\", " +
- "arguments = \"{0}\", \"{1}\", \"{2}\"";
- }
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/jrmp/Constants.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic.jrmp;
-
-/**
- * Constants specific to the JRMP rmic generator.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API. Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-final class Constants {
-
- private Constants() { throw new AssertionError(); }
-
- /*
- * fully-qualified names of types used by rmic
- */
- static final String REMOTE_OBJECT = "java.rmi.server.RemoteObject";
- static final String REMOTE_STUB = "java.rmi.server.RemoteStub";
- static final String REMOTE_REF = "java.rmi.server.RemoteRef";
- static final String OPERATION = "java.rmi.server.Operation";
- static final String SKELETON = "java.rmi.server.Skeleton";
- static final String SKELETON_MISMATCH_EXCEPTION =
- "java.rmi.server.SkeletonMismatchException";
- static final String REMOTE_CALL = "java.rmi.server.RemoteCall";
- static final String MARSHAL_EXCEPTION = "java.rmi.MarshalException";
- static final String UNMARSHAL_EXCEPTION = "java.rmi.UnmarshalException";
- static final String UNEXPECTED_EXCEPTION = "java.rmi.UnexpectedException";
-
- /*
- * stub protocol versions
- */
- enum StubVersion { V1_1, VCOMPAT, V1_2 };
-
- /*
- * serialVersionUID for all stubs that can use 1.2 protocol
- */
- static final long STUB_SERIAL_VERSION_UID = 2;
-
- /*
- * version number used to seed interface hash computation
- */
- static final int INTERFACE_HASH_STUB_VERSION = 1;
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/jrmp/JrmpGenerator.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,226 +0,0 @@
-/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic.jrmp;
-
-import com.sun.javadoc.ClassDoc;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import sun.rmi.rmic.newrmic.BatchEnvironment;
-import sun.rmi.rmic.newrmic.Generator;
-import sun.rmi.rmic.newrmic.IndentingWriter;
-import sun.rmi.rmic.newrmic.Main;
-import sun.rmi.rmic.newrmic.Resources;
-
-import static sun.rmi.rmic.newrmic.jrmp.Constants.*;
-
-/**
- * JRMP rmic back end; generates source code for JRMP stub and
- * skeleton classes.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API. Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-public class JrmpGenerator implements Generator {
-
- private static final Map<String,StubVersion> versionOptions =
- new HashMap<String,StubVersion>();
- static {
- versionOptions.put("-v1.1", StubVersion.V1_1);
- versionOptions.put("-vcompat", StubVersion.VCOMPAT);
- versionOptions.put("-v1.2", StubVersion.V1_2);
- }
-
- private static final Set<String> bootstrapClassNames =
- new HashSet<String>();
- static {
- bootstrapClassNames.add("java.lang.Exception");
- bootstrapClassNames.add("java.rmi.Remote");
- bootstrapClassNames.add("java.rmi.RemoteException");
- bootstrapClassNames.add("java.lang.RuntimeException");
- };
-
- /** version of the JRMP stub protocol to generate code for */
- private StubVersion version = StubVersion.V1_2; // default is -v1.2
-
- /**
- * Creates a new JrmpGenerator.
- **/
- public JrmpGenerator() { }
-
- /**
- * The JRMP generator recognizes command line options for
- * selecting the JRMP stub protocol version to generate classes
- * for. Only one such option is allowed.
- **/
- public boolean parseArgs(String[] args, Main main) {
- String explicitVersion = null;
- for (int i = 0; i < args.length; i++) {
- String arg = args[i];
- if (versionOptions.containsKey(arg)) {
- if (explicitVersion != null && !explicitVersion.equals(arg)) {
- main.error("rmic.cannot.use.both", explicitVersion, arg);
- return false;
- }
- explicitVersion = arg;
- version = versionOptions.get(arg);
- args[i] = null;
- }
- }
- return true;
- }
-
- /**
- * The JRMP generator does not require an environment class more
- * specific than BatchEnvironment.
- **/
- public Class<? extends BatchEnvironment> envClass() {
- return BatchEnvironment.class;
- }
-
- public Set<String> bootstrapClassNames() {
- return Collections.unmodifiableSet(bootstrapClassNames);
- }
-
- /**
- * Generates the source file(s) for the JRMP stub class and
- * (optionally) skeleton class for the specified remote
- * implementation class.
- **/
- public void generate(BatchEnvironment env,
- ClassDoc inputClass,
- File destDir)
- {
- RemoteClass remoteClass = RemoteClass.forClass(env, inputClass);
- if (remoteClass == null) {
- return; // an error must have occurred
- }
-
- StubSkeletonWriter writer =
- new StubSkeletonWriter(env, remoteClass, version);
-
- File stubFile = sourceFileForClass(writer.stubClassName(), destDir);
- try {
- IndentingWriter out = new IndentingWriter(
- new OutputStreamWriter(new FileOutputStream(stubFile)));
- writer.writeStub(out);
- out.close();
- if (env.verbose()) {
- env.output(Resources.getText("rmic.wrote",
- stubFile.getPath()));
- }
- env.addGeneratedFile(stubFile);
- } catch (IOException e) {
- env.error("rmic.cant.write", stubFile.toString());
- return;
- }
-
- File skeletonFile =
- sourceFileForClass(writer.skeletonClassName(), destDir);
- if (version == StubVersion.V1_1 ||
- version == StubVersion.VCOMPAT)
- {
- try {
- IndentingWriter out = new IndentingWriter(
- new OutputStreamWriter(
- new FileOutputStream(skeletonFile)));
- writer.writeSkeleton(out);
- out.close();
- if (env.verbose()) {
- env.output(Resources.getText("rmic.wrote",
- skeletonFile.getPath()));
- }
- env.addGeneratedFile(skeletonFile);
- } catch (IOException e) {
- env.error("rmic.cant.write", skeletonFile.toString());
- return;
- }
- } else {
- /*
- * If skeleton files are not being generated for this run,
- * delete old skeleton source or class files for this
- * remote implementation class that were (presumably) left
- * over from previous runs, to avoid user confusion from
- * extraneous or inconsistent generated files.
- */
- File skeletonClassFile =
- classFileForClass(writer.skeletonClassName(), destDir);
-
- skeletonFile.delete(); // ignore failures (no big deal)
- skeletonClassFile.delete();
- }
- }
-
-
- /**
- * Returns the File object to be used as the source file for a
- * class with the specified binary name, with the specified
- * destination directory as the top of the package hierarchy.
- **/
- private File sourceFileForClass(String binaryName, File destDir) {
- return fileForClass(binaryName, destDir, ".java");
- }
-
- /**
- * Returns the File object to be used as the class file for a
- * class with the specified binary name, with the supplied
- * destination directory as the top of the package hierarchy.
- **/
- private File classFileForClass(String binaryName, File destDir) {
- return fileForClass(binaryName, destDir, ".class");
- }
-
- private File fileForClass(String binaryName, File destDir, String ext) {
- int i = binaryName.lastIndexOf('.');
- String classFileName = binaryName.substring(i + 1) + ext;
- if (i != -1) {
- String packageName = binaryName.substring(0, i);
- String packagePath = packageName.replace('.', File.separatorChar);
- File packageDir = new File(destDir, packagePath);
- /*
- * Make sure that the directory for this package exists.
- * We assume that the caller has verified that the top-
- * level destination directory exists, so we need not
- * worry about creating it unintentionally.
- */
- if (!packageDir.exists()) {
- packageDir.mkdirs();
- }
- return new File(packageDir, classFileName);
- } else {
- return new File(destDir, classFileName);
- }
- }
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/jrmp/RemoteClass.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,710 +0,0 @@
-/*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic.jrmp;
-
-import com.sun.javadoc.ClassDoc;
-import com.sun.javadoc.MethodDoc;
-import com.sun.javadoc.Parameter;
-import com.sun.javadoc.Type;
-import java.io.IOException;
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.security.MessageDigest;
-import java.security.DigestOutputStream;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-import java.util.HashMap;
-import java.util.Map;
-import sun.rmi.rmic.newrmic.BatchEnvironment;
-
-import static sun.rmi.rmic.newrmic.Constants.*;
-import static sun.rmi.rmic.newrmic.jrmp.Constants.*;
-
-/**
- * Encapsulates RMI-specific information about a remote implementation
- * class (a class that implements one or more remote interfaces).
- *
- * WARNING: The contents of this source file are not part of any
- * supported API. Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-final class RemoteClass {
-
- /** rmic environment for this object */
- private final BatchEnvironment env;
-
- /** the remote implementation class this object represents */
- private final ClassDoc implClass;
-
- /** remote interfaces implemented by this class */
- private ClassDoc[] remoteInterfaces;
-
- /** the remote methods of this class */
- private Method[] remoteMethods;
-
- /** stub/skeleton "interface hash" for this class */
- private long interfaceHash;
-
- /**
- * Creates a RemoteClass instance that represents the RMI-specific
- * information about the specified remote implementation class.
- *
- * If the class is not a valid remote implementation class or if
- * some other error occurs, the return value will be null, and
- * errors will have been reported to the supplied
- * BatchEnvironment.
- **/
- static RemoteClass forClass(BatchEnvironment env, ClassDoc implClass) {
- RemoteClass remoteClass = new RemoteClass(env, implClass);
- if (remoteClass.init()) {
- return remoteClass;
- } else {
- return null;
- }
- }
-
- /**
- * Creates a RemoteClass instance for the specified class. The
- * resulting object is not yet initialized.
- **/
- private RemoteClass(BatchEnvironment env, ClassDoc implClass) {
- this.env = env;
- this.implClass = implClass;
- }
-
- /**
- * Returns the ClassDoc for this remote implementation class.
- **/
- ClassDoc classDoc() {
- return implClass;
- }
-
- /**
- * Returns the remote interfaces implemented by this remote
- * implementation class.
- *
- * A remote interface is an interface that is a subinterface of
- * java.rmi.Remote. The remote interfaces of a class are the
- * direct superinterfaces of the class and all of its superclasses
- * that are remote interfaces.
- *
- * The order of the array returned is arbitrary, and some elements
- * may be superfluous (i.e., superinterfaces of other interfaces
- * in the array).
- **/
- ClassDoc[] remoteInterfaces() {
- return remoteInterfaces.clone();
- }
-
- /**
- * Returns an array of RemoteClass.Method objects representing all
- * of the remote methods of this remote implementation class (all
- * of the member methods of the class's remote interfaces).
- *
- * The methods in the array are ordered according to a comparison
- * of strings consisting of their name followed by their
- * descriptor, so each method's index in the array corresponds to
- * its "operation number" in the JDK 1.1 version of the JRMP
- * stub/skeleton protocol.
- **/
- Method[] remoteMethods() {
- return remoteMethods.clone();
- }
-
- /**
- * Returns the "interface hash" used to match a stub/skeleton pair
- * for this remote implementation class in the JDK 1.1 version of
- * the JRMP stub/skeleton protocol.
- **/
- long interfaceHash() {
- return interfaceHash;
- }
-
- /**
- * Validates this remote implementation class and computes the
- * RMI-specific information. Returns true if successful, or false
- * if an error occurred.
- **/
- private boolean init() {
- /*
- * Verify that it is really a class, not an interface.
- */
- if (implClass.isInterface()) {
- env.error("rmic.cant.make.stubs.for.interface",
- implClass.qualifiedName());
- return false;
- }
-
- /*
- * Find all of the remote interfaces of our remote
- * implementation class-- for each class up the superclass
- * chain, add each directly-implemented interface that somehow
- * extends Remote to a list.
- */
- List<ClassDoc> remotesImplemented = new ArrayList<ClassDoc>();
- for (ClassDoc cl = implClass; cl != null; cl = cl.superclass()) {
- for (ClassDoc intf : cl.interfaces()) {
- /*
- * Add interface to the list if it extends Remote and
- * it is not already there.
- */
- if (!remotesImplemented.contains(intf) &&
- intf.subclassOf(env.docRemote()))
- {
- remotesImplemented.add(intf);
- if (env.verbose()) {
- env.output("[found remote interface: " +
- intf.qualifiedName() + "]");
- }
- }
- }
-
- /*
- * Verify that the candidate remote implementation class
- * implements at least one remote interface directly.
- */
- if (cl == implClass && remotesImplemented.isEmpty()) {
- if (implClass.subclassOf(env.docRemote())) {
- /*
- * This error message is used if the class does
- * implement a remote interface through one of its
- * superclasses, but not directly.
- */
- env.error("rmic.must.implement.remote.directly",
- implClass.qualifiedName());
- } else {
- /*
- * This error message is used if the class does
- * not implement a remote interface at all.
- */
- env.error("rmic.must.implement.remote",
- implClass.qualifiedName());
- }
- return false;
- }
- }
-
- /*
- * Convert list of remote interfaces to an array
- * (order is not important for this array).
- */
- remoteInterfaces =
- remotesImplemented.toArray(
- new ClassDoc[remotesImplemented.size()]);
-
- /*
- * Collect the methods from all of the remote interfaces into
- * a table, which maps from method name-and-descriptor string
- * to Method object.
- */
- Map<String,Method> methods = new HashMap<String,Method>();
- boolean errors = false;
- for (ClassDoc intf : remotesImplemented) {
- if (!collectRemoteMethods(intf, methods)) {
- /*
- * Continue iterating despite errors in order to
- * generate more complete error report.
- */
- errors = true;
- }
- }
- if (errors) {
- return false;
- }
-
- /*
- * Sort table of remote methods into an array. The elements
- * are sorted in ascending order of the string of the method's
- * name and descriptor, so that each elements index is equal
- * to its operation number in the JDK 1.1 version of the JRMP
- * stub/skeleton protocol.
- */
- String[] orderedKeys =
- methods.keySet().toArray(new String[methods.size()]);
- Arrays.sort(orderedKeys);
- remoteMethods = new Method[methods.size()];
- for (int i = 0; i < remoteMethods.length; i++) {
- remoteMethods[i] = methods.get(orderedKeys[i]);
- if (env.verbose()) {
- String msg = "[found remote method <" + i + ">: " +
- remoteMethods[i].operationString();
- ClassDoc[] exceptions = remoteMethods[i].exceptionTypes();
- if (exceptions.length > 0) {
- msg += " throws ";
- for (int j = 0; j < exceptions.length; j++) {
- if (j > 0) {
- msg += ", ";
- }
- msg += exceptions[j].qualifiedName();
- }
- }
- msg += "\n\tname and descriptor = \"" +
- remoteMethods[i].nameAndDescriptor();
- msg += "\n\tmethod hash = " +
- remoteMethods[i].methodHash() + "]";
- env.output(msg);
- }
- }
-
- /*
- * Finally, pre-compute the interface hash to be used by
- * stubs/skeletons for this remote class in the JDK 1.1
- * version of the JRMP stub/skeleton protocol.
- */
- interfaceHash = computeInterfaceHash();
-
- return true;
- }
-
- /**
- * Collects and validates all methods from the specified interface
- * and all of its superinterfaces as remote methods. Remote
- * methods are added to the supplied table. Returns true if
- * successful, or false if an error occurred.
- **/
- private boolean collectRemoteMethods(ClassDoc intf,
- Map<String,Method> table)
- {
- if (!intf.isInterface()) {
- throw new AssertionError(
- intf.qualifiedName() + " not an interface");
- }
-
- boolean errors = false;
-
- /*
- * Search interface's declared methods.
- */
- nextMethod:
- for (MethodDoc method : intf.methods()) {
-
- /*
- * Verify that each method throws RemoteException (or a
- * superclass of RemoteException).
- */
- boolean hasRemoteException = false;
- for (ClassDoc ex : method.thrownExceptions()) {
- if (env.docRemoteException().subclassOf(ex)) {
- hasRemoteException = true;
- break;
- }
- }
-
- /*
- * If this method did not throw RemoteException as required,
- * generate the error but continue, so that multiple such
- * errors can be reported.
- */
- if (!hasRemoteException) {
- env.error("rmic.must.throw.remoteexception",
- intf.qualifiedName(),
- method.name() + method.signature());
- errors = true;
- continue nextMethod;
- }
-
- /*
- * Verify that the implementation of this method throws only
- * java.lang.Exception or its subclasses (fix bugid 4092486).
- * JRMP does not support remote methods throwing
- * java.lang.Throwable or other subclasses.
- */
- MethodDoc implMethod = findImplMethod(method);
- if (implMethod != null) { // should not be null
- for (ClassDoc ex : implMethod.thrownExceptions()) {
- if (!ex.subclassOf(env.docException())) {
- env.error("rmic.must.only.throw.exception",
- implMethod.name() + implMethod.signature(),
- ex.qualifiedName());
- errors = true;
- continue nextMethod;
- }
- }
- }
-
- /*
- * Create RemoteClass.Method object to represent this method
- * found in a remote interface.
- */
- Method newMethod = new Method(method);
-
- /*
- * Store remote method's representation in the table of
- * remote methods found, keyed by its name and descriptor.
- *
- * If the table already contains an entry with the same
- * method name and descriptor, then we must replace the
- * old entry with a Method object that represents a legal
- * combination of the old and the new methods;
- * specifically, the combined method must have a throws
- * clause that contains (only) all of the checked
- * exceptions that can be thrown by both the old and the
- * new method (see bugid 4070653).
- */
- String key = newMethod.nameAndDescriptor();
- Method oldMethod = table.get(key);
- if (oldMethod != null) {
- newMethod = newMethod.mergeWith(oldMethod);
- }
- table.put(key, newMethod);
- }
-
- /*
- * Recursively collect methods for all superinterfaces.
- */
- for (ClassDoc superintf : intf.interfaces()) {
- if (!collectRemoteMethods(superintf, table)) {
- errors = true;
- }
- }
-
- return !errors;
- }
-
- /**
- * Returns the MethodDoc for the method of this remote
- * implementation class that implements the specified remote
- * method of a remote interface. Returns null if no matching
- * method was found in this remote implementation class.
- **/
- private MethodDoc findImplMethod(MethodDoc interfaceMethod) {
- String name = interfaceMethod.name();
- String desc = Util.methodDescriptorOf(interfaceMethod);
- for (MethodDoc implMethod : implClass.methods()) {
- if (name.equals(implMethod.name()) &&
- desc.equals(Util.methodDescriptorOf(implMethod)))
- {
- return implMethod;
- }
- }
- return null;
- }
-
- /**
- * Computes the "interface hash" of the stub/skeleton pair for
- * this remote implementation class. This is the 64-bit value
- * used to enforce compatibility between a stub class and a
- * skeleton class in the JDK 1.1 version of the JRMP stub/skeleton
- * protocol.
- *
- * It is calculated using the first 64 bits of an SHA digest. The
- * digest is of a stream consisting of the following data:
- * (int) stub version number, always 1
- * for each remote method, in order of operation number:
- * (UTF-8) method name
- * (UTF-8) method descriptor
- * for each declared exception, in alphabetical name order:
- * (UTF-8) name of exception class
- * (where "UTF-8" includes a 16-bit length prefix as written by
- * java.io.DataOutput.writeUTF).
- **/
- private long computeInterfaceHash() {
- long hash = 0;
- ByteArrayOutputStream sink = new ByteArrayOutputStream(512);
- try {
- MessageDigest md = MessageDigest.getInstance("SHA");
- DataOutputStream out = new DataOutputStream(
- new DigestOutputStream(sink, md));
-
- out.writeInt(INTERFACE_HASH_STUB_VERSION);
-
- for (Method method : remoteMethods) {
- MethodDoc methodDoc = method.methodDoc();
-
- out.writeUTF(methodDoc.name());
- out.writeUTF(Util.methodDescriptorOf(methodDoc));
- // descriptors already use binary names
-
- ClassDoc exceptions[] = methodDoc.thrownExceptions();
- Arrays.sort(exceptions, new ClassDocComparator());
- for (ClassDoc ex : exceptions) {
- out.writeUTF(Util.binaryNameOf(ex));
- }
- }
- out.flush();
-
- // use only the first 64 bits of the digest for the hash
- byte hashArray[] = md.digest();
- for (int i = 0; i < Math.min(8, hashArray.length); i++) {
- hash += ((long) (hashArray[i] & 0xFF)) << (i * 8);
- }
- } catch (IOException e) {
- throw new AssertionError(e);
- } catch (NoSuchAlgorithmException e) {
- throw new AssertionError(e);
- }
-
- return hash;
- }
-
- /**
- * Compares ClassDoc instances according to the lexicographic
- * order of their binary names.
- **/
- private static class ClassDocComparator implements Comparator<ClassDoc> {
- public int compare(ClassDoc o1, ClassDoc o2) {
- return Util.binaryNameOf(o1).compareTo(Util.binaryNameOf(o2));
- }
- }
-
- /**
- * Encapsulates RMI-specific information about a particular remote
- * method in the remote implementation class represented by the
- * enclosing RemoteClass.
- **/
- final class Method implements Cloneable {
-
- /**
- * MethodDoc for this remove method, from one of the remote
- * interfaces that this method was found in.
- *
- * Note that this MethodDoc may be only one of multiple that
- * correspond to this remote method object, if multiple of
- * this class's remote interfaces contain methods with the
- * same name and descriptor. Therefore, this MethodDoc may
- * declare more exceptions thrown that this remote method
- * does.
- **/
- private final MethodDoc methodDoc;
-
- /** java.rmi.server.Operation string for this remote method */
- private final String operationString;
-
- /** name and descriptor of this remote method */
- private final String nameAndDescriptor;
-
- /** JRMP "method hash" for this remote method */
- private final long methodHash;
-
- /**
- * Exceptions declared to be thrown by this remote method.
- *
- * This list may include superfluous entries, such as
- * unchecked exceptions and subclasses of other entries.
- **/
- private ClassDoc[] exceptionTypes;
-
- /**
- * Creates a new Method instance for the specified method.
- **/
- Method(MethodDoc methodDoc) {
- this.methodDoc = methodDoc;
- exceptionTypes = methodDoc.thrownExceptions();
- /*
- * Sort exception types to improve consistency with
- * previous implementations.
- */
- Arrays.sort(exceptionTypes, new ClassDocComparator());
- operationString = computeOperationString();
- nameAndDescriptor =
- methodDoc.name() + Util.methodDescriptorOf(methodDoc);
- methodHash = computeMethodHash();
- }
-
- /**
- * Returns the MethodDoc object corresponding to this method
- * of a remote interface.
- **/
- MethodDoc methodDoc() {
- return methodDoc;
- }
-
- /**
- * Returns the parameter types declared by this method.
- **/
- Type[] parameterTypes() {
- Parameter[] parameters = methodDoc.parameters();
- Type[] paramTypes = new Type[parameters.length];
- for (int i = 0; i < paramTypes.length; i++) {
- paramTypes[i] = parameters[i].type();
- }
- return paramTypes;
- }
-
- /**
- * Returns the exception types declared to be thrown by this
- * remote method.
- *
- * For methods with the same name and descriptor inherited
- * from multiple remote interfaces, the array will contain the
- * set of exceptions declared in all of the interfaces'
- * methods that can be legally thrown by all of them.
- **/
- ClassDoc[] exceptionTypes() {
- return exceptionTypes.clone();
- }
-
- /**
- * Returns the JRMP "method hash" used to identify this remote
- * method in the JDK 1.2 version of the stub protocol.
- **/
- long methodHash() {
- return methodHash;
- }
-
- /**
- * Returns the string representation of this method
- * appropriate for the construction of a
- * java.rmi.server.Operation object.
- **/
- String operationString() {
- return operationString;
- }
-
- /**
- * Returns a string consisting of this method's name followed
- * by its descriptor.
- **/
- String nameAndDescriptor() {
- return nameAndDescriptor;
- }
-
- /**
- * Returns a new Method object that is a legal combination of
- * this Method object and another one.
- *
- * Doing this requires determining the exceptions declared by
- * the combined method, which must be (only) all of the
- * exceptions declared in both old Methods that may thrown in
- * either of them.
- **/
- Method mergeWith(Method other) {
- if (!nameAndDescriptor().equals(other.nameAndDescriptor())) {
- throw new AssertionError(
- "attempt to merge method \"" +
- other.nameAndDescriptor() + "\" with \"" +
- nameAndDescriptor());
- }
-
- List<ClassDoc> legalExceptions = new ArrayList<ClassDoc>();
- collectCompatibleExceptions(
- other.exceptionTypes, exceptionTypes, legalExceptions);
- collectCompatibleExceptions(
- exceptionTypes, other.exceptionTypes, legalExceptions);
-
- Method merged = clone();
- merged.exceptionTypes =
- legalExceptions.toArray(new ClassDoc[legalExceptions.size()]);
-
- return merged;
- }
-
- /**
- * Cloning is supported by returning a shallow copy of this
- * object.
- **/
- protected Method clone() {
- try {
- return (Method) super.clone();
- } catch (CloneNotSupportedException e) {
- throw new AssertionError(e);
- }
- }
-
- /**
- * Adds to the supplied list all exceptions in the "froms"
- * array that are subclasses of an exception in the "withs"
- * array.
- **/
- private void collectCompatibleExceptions(ClassDoc[] froms,
- ClassDoc[] withs,
- List<ClassDoc> list)
- {
- for (ClassDoc from : froms) {
- if (!list.contains(from)) {
- for (ClassDoc with : withs) {
- if (from.subclassOf(with)) {
- list.add(from);
- break;
- }
- }
- }
- }
- }
-
- /**
- * Computes the JRMP "method hash" of this remote method. The
- * method hash is a long containing the first 64 bits of the
- * SHA digest from the UTF-8 encoded string of the method name
- * and descriptor.
- **/
- private long computeMethodHash() {
- long hash = 0;
- ByteArrayOutputStream sink = new ByteArrayOutputStream(512);
- try {
- MessageDigest md = MessageDigest.getInstance("SHA");
- DataOutputStream out = new DataOutputStream(
- new DigestOutputStream(sink, md));
-
- String methodString = nameAndDescriptor();
- out.writeUTF(methodString);
-
- // use only the first 64 bits of the digest for the hash
- out.flush();
- byte hashArray[] = md.digest();
- for (int i = 0; i < Math.min(8, hashArray.length); i++) {
- hash += ((long) (hashArray[i] & 0xFF)) << (i * 8);
- }
- } catch (IOException e) {
- throw new AssertionError(e);
- } catch (NoSuchAlgorithmException e) {
- throw new AssertionError(e);
- }
-
- return hash;
- }
-
- /**
- * Computes the string representation of this method
- * appropriate for the construction of a
- * java.rmi.server.Operation object.
- **/
- private String computeOperationString() {
- /*
- * To be consistent with previous implementations, we use
- * the deprecated style of placing the "[]" for the return
- * type (if any) after the parameter list.
- */
- Type returnType = methodDoc.returnType();
- String op = returnType.qualifiedTypeName() + " " +
- methodDoc.name() + "(";
- Parameter[] parameters = methodDoc.parameters();
- for (int i = 0; i < parameters.length; i++) {
- if (i > 0) {
- op += ", ";
- }
- op += parameters[i].type().toString();
- }
- op += ")" + returnType.dimension();
- return op;
- }
- }
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/jrmp/StubSkeletonWriter.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1079 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic.jrmp;
-
-import com.sun.javadoc.ClassDoc;
-import com.sun.javadoc.MethodDoc;
-import com.sun.javadoc.Type;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import sun.rmi.rmic.newrmic.BatchEnvironment;
-import sun.rmi.rmic.newrmic.IndentingWriter;
-
-import static sun.rmi.rmic.newrmic.Constants.*;
-import static sun.rmi.rmic.newrmic.jrmp.Constants.*;
-
-/**
- * Writes the source code for the stub class and (optionally) skeleton
- * class for a particular remote implementation class.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API. Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-class StubSkeletonWriter {
-
- /** rmic environment for this object */
- private final BatchEnvironment env;
-
- /** the remote implementation class to generate code for */
- private final RemoteClass remoteClass;
-
- /** version of the JRMP stub protocol to generate code for */
- private final StubVersion version;
-
- /*
- * binary names of the stub and skeleton classes to generate for
- * the remote class
- */
- private final String stubClassName;
- private final String skeletonClassName;
-
- /* package name and simple names of the stub and skeleton classes */
- private final String packageName;
- private final String stubClassSimpleName;
- private final String skeletonClassSimpleName;
-
- /** remote methods of class, indexed by operation number */
- private final RemoteClass.Method[] remoteMethods;
-
- /**
- * Names to use for the java.lang.reflect.Method static fields in
- * the generated stub class corresponding to each remote method.
- **/
- private final String[] methodFieldNames;
-
- /**
- * Creates a StubSkeletonWriter instance for the specified remote
- * implementation class. The generated code will implement the
- * specified JRMP stub protocol version.
- **/
- StubSkeletonWriter(BatchEnvironment env,
- RemoteClass remoteClass,
- StubVersion version)
- {
- this.env = env;
- this.remoteClass = remoteClass;
- this.version = version;
-
- stubClassName = Util.binaryNameOf(remoteClass.classDoc()) + "_Stub";
- skeletonClassName =
- Util.binaryNameOf(remoteClass.classDoc()) + "_Skel";
-
- int i = stubClassName.lastIndexOf('.');
- packageName = (i != -1 ? stubClassName.substring(0, i) : "");
- stubClassSimpleName = stubClassName.substring(i + 1);
- skeletonClassSimpleName = skeletonClassName.substring(i + 1);
-
- remoteMethods = remoteClass.remoteMethods();
- methodFieldNames = nameMethodFields(remoteMethods);
- }
-
- /**
- * Returns the binary name of the stub class to generate for the
- * remote implementation class.
- **/
- String stubClassName() {
- return stubClassName;
- }
-
- /**
- * Returns the binary name of the skeleton class to generate for
- * the remote implementation class.
- **/
- String skeletonClassName() {
- return skeletonClassName;
- }
-
- /**
- * Writes the stub class for the remote class to a stream.
- **/
- void writeStub(IndentingWriter p) throws IOException {
-
- /*
- * Write boiler plate comment.
- */
- p.pln("// Stub class generated by rmic, do not edit.");
- p.pln("// Contents subject to change without notice.");
- p.pln();
-
- /*
- * If remote implementation class was in a particular package,
- * declare the stub class to be in the same package.
- */
- if (!packageName.equals("")) {
- p.pln("package " + packageName + ";");
- p.pln();
- }
-
- /*
- * Declare the stub class; implement all remote interfaces.
- */
- p.plnI("public final class " + stubClassSimpleName);
- p.pln("extends " + REMOTE_STUB);
- ClassDoc[] remoteInterfaces = remoteClass.remoteInterfaces();
- if (remoteInterfaces.length > 0) {
- p.p("implements ");
- for (int i = 0; i < remoteInterfaces.length; i++) {
- if (i > 0) {
- p.p(", ");
- }
- p.p(remoteInterfaces[i].qualifiedName());
- }
- p.pln();
- }
- p.pOlnI("{");
-
- if (version == StubVersion.V1_1 ||
- version == StubVersion.VCOMPAT)
- {
- writeOperationsArray(p);
- p.pln();
- writeInterfaceHash(p);
- p.pln();
- }
-
- if (version == StubVersion.VCOMPAT ||
- version == StubVersion.V1_2)
- {
- p.pln("private static final long serialVersionUID = " +
- STUB_SERIAL_VERSION_UID + ";");
- p.pln();
-
- /*
- * We only need to declare and initialize the static fields of
- * Method objects for each remote method if there are any remote
- * methods; otherwise, skip this code entirely, to avoid generating
- * a try/catch block for a checked exception that cannot occur
- * (see bugid 4125181).
- */
- if (methodFieldNames.length > 0) {
- if (version == StubVersion.VCOMPAT) {
- p.pln("private static boolean useNewInvoke;");
- }
- writeMethodFieldDeclarations(p);
- p.pln();
-
- /*
- * Initialize java.lang.reflect.Method fields for each remote
- * method in a static initializer.
- */
- p.plnI("static {");
- p.plnI("try {");
- if (version == StubVersion.VCOMPAT) {
- /*
- * Fat stubs must determine whether the API required for
- * the JDK 1.2 stub protocol is supported in the current
- * runtime, so that it can use it if supported. This is
- * determined by using the Reflection API to test if the
- * new invoke method on RemoteRef exists, and setting the
- * static boolean "useNewInvoke" to true if it does, or
- * to false if a NoSuchMethodException is thrown.
- */
- p.plnI(REMOTE_REF + ".class.getMethod(\"invoke\",");
- p.plnI("new java.lang.Class[] {");
- p.pln(REMOTE + ".class,");
- p.pln("java.lang.reflect.Method.class,");
- p.pln("java.lang.Object[].class,");
- p.pln("long.class");
- p.pOln("});");
- p.pO();
- p.pln("useNewInvoke = true;");
- }
- writeMethodFieldInitializers(p);
- p.pOlnI("} catch (java.lang.NoSuchMethodException e) {");
- if (version == StubVersion.VCOMPAT) {
- p.pln("useNewInvoke = false;");
- } else {
- p.plnI("throw new java.lang.NoSuchMethodError(");
- p.pln("\"stub class initialization failed\");");
- p.pO();
- }
- p.pOln("}"); // end try/catch block
- p.pOln("}"); // end static initializer
- p.pln();
- }
- }
-
- writeStubConstructors(p);
- p.pln();
-
- /*
- * Write each stub method.
- */
- if (remoteMethods.length > 0) {
- p.pln("// methods from remote interfaces");
- for (int i = 0; i < remoteMethods.length; ++i) {
- p.pln();
- writeStubMethod(p, i);
- }
- }
-
- p.pOln("}"); // end stub class
- }
-
- /**
- * Writes the constructors for the stub class.
- **/
- private void writeStubConstructors(IndentingWriter p)
- throws IOException
- {
- p.pln("// constructors");
-
- /*
- * Only stubs compatible with the JDK 1.1 stub protocol need
- * a no-arg constructor; later versions use reflection to find
- * the constructor that directly takes a RemoteRef argument.
- */
- if (version == StubVersion.V1_1 ||
- version == StubVersion.VCOMPAT)
- {
- p.plnI("public " + stubClassSimpleName + "() {");
- p.pln("super();");
- p.pOln("}");
- }
-
- p.plnI("public " + stubClassSimpleName + "(" + REMOTE_REF + " ref) {");
- p.pln("super(ref);");
- p.pOln("}");
- }
-
- /**
- * Writes the stub method for the remote method with the given
- * operation number.
- **/
- private void writeStubMethod(IndentingWriter p, int opnum)
- throws IOException
- {
- RemoteClass.Method method = remoteMethods[opnum];
- MethodDoc methodDoc = method.methodDoc();
- String methodName = methodDoc.name();
- Type[] paramTypes = method.parameterTypes();
- String paramNames[] = nameParameters(paramTypes);
- Type returnType = methodDoc.returnType();
- ClassDoc[] exceptions = method.exceptionTypes();
-
- /*
- * Declare stub method; throw exceptions declared in remote
- * interface(s).
- */
- p.pln("// implementation of " +
- Util.getFriendlyUnqualifiedSignature(methodDoc));
- p.p("public " + returnType.toString() + " " + methodName + "(");
- for (int i = 0; i < paramTypes.length; i++) {
- if (i > 0) {
- p.p(", ");
- }
- p.p(paramTypes[i].toString() + " " + paramNames[i]);
- }
- p.plnI(")");
- if (exceptions.length > 0) {
- p.p("throws ");
- for (int i = 0; i < exceptions.length; i++) {
- if (i > 0) {
- p.p(", ");
- }
- p.p(exceptions[i].qualifiedName());
- }
- p.pln();
- }
- p.pOlnI("{");
-
- /*
- * The RemoteRef.invoke methods throw Exception, but unless
- * this stub method throws Exception as well, we must catch
- * Exceptions thrown from the invocation. So we must catch
- * Exception and rethrow something we can throw:
- * UnexpectedException, which is a subclass of
- * RemoteException. But for any subclasses of Exception that
- * we can throw, like RemoteException, RuntimeException, and
- * any of the exceptions declared by this stub method, we want
- * them to pass through unmodified, so first we must catch any
- * such exceptions and rethrow them directly.
- *
- * We have to be careful generating the rethrowing catch
- * blocks here, because javac will flag an error if there are
- * any unreachable catch blocks, i.e. if the catch of an
- * exception class follows a previous catch of it or of one of
- * its superclasses. The following method invocation takes
- * care of these details.
- */
- List<ClassDoc> catchList = computeUniqueCatchList(exceptions);
-
- /*
- * If we need to catch any particular exceptions (i.e. this method
- * does not declare java.lang.Exception), put the entire stub
- * method in a try block.
- */
- if (catchList.size() > 0) {
- p.plnI("try {");
- }
-
- if (version == StubVersion.VCOMPAT) {
- p.plnI("if (useNewInvoke) {");
- }
- if (version == StubVersion.VCOMPAT ||
- version == StubVersion.V1_2)
- {
- if (!Util.isVoid(returnType)) {
- p.p("Object $result = "); // REMIND: why $?
- }
- p.p("ref.invoke(this, " + methodFieldNames[opnum] + ", ");
- if (paramTypes.length > 0) {
- p.p("new java.lang.Object[] {");
- for (int i = 0; i < paramTypes.length; i++) {
- if (i > 0)
- p.p(", ");
- p.p(wrapArgumentCode(paramTypes[i], paramNames[i]));
- }
- p.p("}");
- } else {
- p.p("null");
- }
- p.pln(", " + method.methodHash() + "L);");
- if (!Util.isVoid(returnType)) {
- p.pln("return " +
- unwrapArgumentCode(returnType, "$result") + ";");
- }
- }
- if (version == StubVersion.VCOMPAT) {
- p.pOlnI("} else {");
- }
- if (version == StubVersion.V1_1 ||
- version == StubVersion.VCOMPAT)
- {
- p.pln(REMOTE_CALL + " call = ref.newCall((" + REMOTE_OBJECT +
- ") this, operations, " + opnum + ", interfaceHash);");
-
- if (paramTypes.length > 0) {
- p.plnI("try {");
- p.pln("java.io.ObjectOutput out = call.getOutputStream();");
- writeMarshalArguments(p, "out", paramTypes, paramNames);
- p.pOlnI("} catch (java.io.IOException e) {");
- p.pln("throw new " + MARSHAL_EXCEPTION +
- "(\"error marshalling arguments\", e);");
- p.pOln("}");
- }
-
- p.pln("ref.invoke(call);");
-
- if (Util.isVoid(returnType)) {
- p.pln("ref.done(call);");
- } else {
- p.pln(returnType.toString() + " $result;");
- // REMIND: why $?
- p.plnI("try {");
- p.pln("java.io.ObjectInput in = call.getInputStream();");
- boolean objectRead =
- writeUnmarshalArgument(p, "in", returnType, "$result");
- p.pln(";");
- p.pOlnI("} catch (java.io.IOException e) {");
- p.pln("throw new " + UNMARSHAL_EXCEPTION +
- "(\"error unmarshalling return\", e);");
- /*
- * If any only if readObject has been invoked, we must catch
- * ClassNotFoundException as well as IOException.
- */
- if (objectRead) {
- p.pOlnI("} catch (java.lang.ClassNotFoundException e) {");
- p.pln("throw new " + UNMARSHAL_EXCEPTION +
- "(\"error unmarshalling return\", e);");
- }
- p.pOlnI("} finally {");
- p.pln("ref.done(call);");
- p.pOln("}");
- p.pln("return $result;");
- }
- }
- if (version == StubVersion.VCOMPAT) {
- p.pOln("}"); // end if/else (useNewInvoke) block
- }
-
- /*
- * If we need to catch any particular exceptions, finally write
- * the catch blocks for them, rethrow any other Exceptions with an
- * UnexpectedException, and end the try block.
- */
- if (catchList.size() > 0) {
- for (ClassDoc catchClass : catchList) {
- p.pOlnI("} catch (" + catchClass.qualifiedName() + " e) {");
- p.pln("throw e;");
- }
- p.pOlnI("} catch (java.lang.Exception e) {");
- p.pln("throw new " + UNEXPECTED_EXCEPTION +
- "(\"undeclared checked exception\", e);");
- p.pOln("}"); // end try/catch block
- }
-
- p.pOln("}"); // end stub method
- }
-
- /**
- * Computes the exceptions that need to be caught and rethrown in
- * a stub method before wrapping Exceptions in
- * UnexpectedExceptions, given the exceptions declared in the
- * throws clause of the method. Returns a list containing the
- * exception to catch. Each exception is guaranteed to be unique,
- * i.e. not a subclass of any of the other exceptions in the list,
- * so the catch blocks for these exceptions may be generated in
- * any order relative to each other.
- *
- * RemoteException and RuntimeException are each automatically
- * placed in the returned list (unless any of their superclasses
- * are already present), since those exceptions should always be
- * directly rethrown by a stub method.
- *
- * The returned list will be empty if java.lang.Exception or one
- * of its superclasses is in the throws clause of the method,
- * indicating that no exceptions need to be caught.
- **/
- private List<ClassDoc> computeUniqueCatchList(ClassDoc[] exceptions) {
- List<ClassDoc> uniqueList = new ArrayList<ClassDoc>();
-
- uniqueList.add(env.docRuntimeException());
- uniqueList.add(env.docRemoteException()); // always catch/rethrow these
-
- /* For each exception declared by the stub method's throws clause: */
- nextException:
- for (ClassDoc ex : exceptions) {
- if (env.docException().subclassOf(ex)) {
- /*
- * If java.lang.Exception (or a superclass) was declared
- * in the throws clause of this stub method, then we don't
- * have to bother catching anything; clear the list and
- * return.
- */
- uniqueList.clear();
- break;
- } else if (!ex.subclassOf(env.docException())) {
- /*
- * Ignore other Throwables that do not extend Exception,
- * because they cannot be thrown by the invoke methods.
- */
- continue;
- }
- /*
- * Compare this exception against the current list of
- * exceptions that need to be caught:
- */
- for (Iterator<ClassDoc> i = uniqueList.iterator(); i.hasNext();) {
- ClassDoc ex2 = i.next();
- if (ex.subclassOf(ex2)) {
- /*
- * If a superclass of this exception is already on
- * the list to catch, then ignore this one and continue;
- */
- continue nextException;
- } else if (ex2.subclassOf(ex)) {
- /*
- * If a subclass of this exception is on the list
- * to catch, then remove it;
- */
- i.remove();
- }
- }
- /* This exception is unique: add it to the list to catch. */
- uniqueList.add(ex);
- }
- return uniqueList;
- }
-
- /**
- * Writes the skeleton for the remote class to a stream.
- **/
- void writeSkeleton(IndentingWriter p) throws IOException {
- if (version == StubVersion.V1_2) {
- throw new AssertionError(
- "should not generate skeleton for version " + version);
- }
-
- /*
- * Write boiler plate comment.
- */
- p.pln("// Skeleton class generated by rmic, do not edit.");
- p.pln("// Contents subject to change without notice.");
- p.pln();
-
- /*
- * If remote implementation class was in a particular package,
- * declare the skeleton class to be in the same package.
- */
- if (!packageName.equals("")) {
- p.pln("package " + packageName + ";");
- p.pln();
- }
-
- /*
- * Declare the skeleton class.
- */
- p.plnI("public final class " + skeletonClassSimpleName);
- p.pln("implements " + SKELETON);
- p.pOlnI("{");
-
- writeOperationsArray(p);
- p.pln();
-
- writeInterfaceHash(p);
- p.pln();
-
- /*
- * Define the getOperations() method.
- */
- p.plnI("public " + OPERATION + "[] getOperations() {");
- p.pln("return (" + OPERATION + "[]) operations.clone();");
- p.pOln("}");
- p.pln();
-
- /*
- * Define the dispatch() method.
- */
- p.plnI("public void dispatch(" + REMOTE + " obj, " +
- REMOTE_CALL + " call, int opnum, long hash)");
- p.pln("throws java.lang.Exception");
- p.pOlnI("{");
-
- if (version == StubVersion.VCOMPAT) {
- p.plnI("if (opnum < 0) {");
- if (remoteMethods.length > 0) {
- for (int opnum = 0; opnum < remoteMethods.length; opnum++) {
- if (opnum > 0)
- p.pO("} else ");
- p.plnI("if (hash == " +
- remoteMethods[opnum].methodHash() + "L) {");
- p.pln("opnum = " + opnum + ";");
- }
- p.pOlnI("} else {");
- }
- /*
- * Skeleton throws UnmarshalException if it does not recognize
- * the method hash; this is what UnicastServerRef.dispatch()
- * would do.
- */
- p.pln("throw new " +
- UNMARSHAL_EXCEPTION + "(\"invalid method hash\");");
- if (remoteMethods.length > 0) {
- p.pOln("}");
- }
- /*
- * Ignore the validation of the interface hash if the
- * operation number was negative, since it is really a
- * method hash instead.
- */
- p.pOlnI("} else {");
- }
-
- p.plnI("if (hash != interfaceHash)");
- p.pln("throw new " +
- SKELETON_MISMATCH_EXCEPTION + "(\"interface hash mismatch\");");
- p.pO();
-
- if (version == StubVersion.VCOMPAT) {
- p.pOln("}"); // end if/else (opnum < 0) block
- }
- p.pln();
-
- /*
- * Cast remote object reference to the remote implementation
- * class, if it's not private. We don't use the binary name
- * of the class like previous implementations did because that
- * would not compile with javac (since 1.4.1). If the remote
- * implementation class is private, then we can't cast to it
- * like previous implementations did because that also would
- * not compile with javac-- so instead, we'll have to try to
- * cast to the remote interface for each remote method.
- */
- if (!remoteClass.classDoc().isPrivate()) {
- p.pln(remoteClass.classDoc().qualifiedName() + " server = (" +
- remoteClass.classDoc().qualifiedName() + ") obj;");
- }
-
- /*
- * Process call according to the operation number.
- */
- p.plnI("switch (opnum) {");
- for (int opnum = 0; opnum < remoteMethods.length; opnum++) {
- writeSkeletonDispatchCase(p, opnum);
- }
- p.pOlnI("default:");
- /*
- * Skeleton throws UnmarshalException if it does not recognize
- * the operation number; this is consistent with the case of an
- * unrecognized method hash.
- */
- p.pln("throw new " + UNMARSHAL_EXCEPTION +
- "(\"invalid method number\");");
- p.pOln("}"); // end switch statement
-
- p.pOln("}"); // end dispatch() method
-
- p.pOln("}"); // end skeleton class
- }
-
- /**
- * Writes the case block for the skeleton's dispatch method for
- * the remote method with the given "opnum".
- **/
- private void writeSkeletonDispatchCase(IndentingWriter p, int opnum)
- throws IOException
- {
- RemoteClass.Method method = remoteMethods[opnum];
- MethodDoc methodDoc = method.methodDoc();
- String methodName = methodDoc.name();
- Type paramTypes[] = method.parameterTypes();
- String paramNames[] = nameParameters(paramTypes);
- Type returnType = methodDoc.returnType();
-
- p.pOlnI("case " + opnum + ": // " +
- Util.getFriendlyUnqualifiedSignature(methodDoc));
- /*
- * Use nested block statement inside case to provide an independent
- * namespace for local variables used to unmarshal parameters for
- * this remote method.
- */
- p.pOlnI("{");
-
- if (paramTypes.length > 0) {
- /*
- * Declare local variables to hold arguments.
- */
- for (int i = 0; i < paramTypes.length; i++) {
- p.pln(paramTypes[i].toString() + " " + paramNames[i] + ";");
- }
-
- /*
- * Unmarshal arguments from call stream.
- */
- p.plnI("try {");
- p.pln("java.io.ObjectInput in = call.getInputStream();");
- boolean objectsRead = writeUnmarshalArguments(p, "in",
- paramTypes, paramNames);
- p.pOlnI("} catch (java.io.IOException e) {");
- p.pln("throw new " + UNMARSHAL_EXCEPTION +
- "(\"error unmarshalling arguments\", e);");
- /*
- * If any only if readObject has been invoked, we must catch
- * ClassNotFoundException as well as IOException.
- */
- if (objectsRead) {
- p.pOlnI("} catch (java.lang.ClassNotFoundException e) {");
- p.pln("throw new " + UNMARSHAL_EXCEPTION +
- "(\"error unmarshalling arguments\", e);");
- }
- p.pOlnI("} finally {");
- p.pln("call.releaseInputStream();");
- p.pOln("}");
- } else {
- p.pln("call.releaseInputStream();");
- }
-
- if (!Util.isVoid(returnType)) {
- /*
- * Declare variable to hold return type, if not void.
- */
- p.p(returnType.toString() + " $result = ");
- // REMIND: why $?
- }
-
- /*
- * Invoke the method on the server object. If the remote
- * implementation class is private, then we don't have a
- * reference cast to it, and so we try to cast to the remote
- * object reference to the method's declaring interface here.
- */
- String target = remoteClass.classDoc().isPrivate() ?
- "((" + methodDoc.containingClass().qualifiedName() + ") obj)" :
- "server";
- p.p(target + "." + methodName + "(");
- for (int i = 0; i < paramNames.length; i++) {
- if (i > 0)
- p.p(", ");
- p.p(paramNames[i]);
- }
- p.pln(");");
-
- /*
- * Always invoke getResultStream(true) on the call object to send
- * the indication of a successful invocation to the caller. If
- * the return type is not void, keep the result stream and marshal
- * the return value.
- */
- p.plnI("try {");
- if (!Util.isVoid(returnType)) {
- p.p("java.io.ObjectOutput out = ");
- }
- p.pln("call.getResultStream(true);");
- if (!Util.isVoid(returnType)) {
- writeMarshalArgument(p, "out", returnType, "$result");
- p.pln(";");
- }
- p.pOlnI("} catch (java.io.IOException e) {");
- p.pln("throw new " +
- MARSHAL_EXCEPTION + "(\"error marshalling return\", e);");
- p.pOln("}");
-
- p.pln("break;"); // break from switch statement
-
- p.pOlnI("}"); // end nested block statement
- p.pln();
- }
-
- /**
- * Writes declaration and initializer for "operations" static array.
- **/
- private void writeOperationsArray(IndentingWriter p)
- throws IOException
- {
- p.plnI("private static final " + OPERATION + "[] operations = {");
- for (int i = 0; i < remoteMethods.length; i++) {
- if (i > 0)
- p.pln(",");
- p.p("new " + OPERATION + "(\"" +
- remoteMethods[i].operationString() + "\")");
- }
- p.pln();
- p.pOln("};");
- }
-
- /**
- * Writes declaration and initializer for "interfaceHash" static field.
- **/
- private void writeInterfaceHash(IndentingWriter p)
- throws IOException
- {
- p.pln("private static final long interfaceHash = " +
- remoteClass.interfaceHash() + "L;");
- }
-
- /**
- * Writes declaration for java.lang.reflect.Method static fields
- * corresponding to each remote method in a stub.
- **/
- private void writeMethodFieldDeclarations(IndentingWriter p)
- throws IOException
- {
- for (String name : methodFieldNames) {
- p.pln("private static java.lang.reflect.Method " + name + ";");
- }
- }
-
- /**
- * Writes code to initialize the static fields for each method
- * using the Java Reflection API.
- **/
- private void writeMethodFieldInitializers(IndentingWriter p)
- throws IOException
- {
- for (int i = 0; i < methodFieldNames.length; i++) {
- p.p(methodFieldNames[i] + " = ");
- /*
- * Look up the Method object in the somewhat arbitrary
- * interface that we find in the Method object.
- */
- RemoteClass.Method method = remoteMethods[i];
- MethodDoc methodDoc = method.methodDoc();
- String methodName = methodDoc.name();
- Type paramTypes[] = method.parameterTypes();
-
- p.p(methodDoc.containingClass().qualifiedName() + ".class.getMethod(\"" +
- methodName + "\", new java.lang.Class[] {");
- for (int j = 0; j < paramTypes.length; j++) {
- if (j > 0)
- p.p(", ");
- p.p(paramTypes[j].toString() + ".class");
- }
- p.pln("});");
- }
- }
-
-
- /*
- * Following are a series of static utility methods useful during
- * the code generation process:
- */
-
- /**
- * Generates an array of names for fields correspondins to the
- * given array of remote methods. Each name in the returned array
- * is guaranteed to be unique.
- *
- * The name of a method is included in its corresponding field
- * name to enhance readability of the generated code.
- **/
- private static String[] nameMethodFields(RemoteClass.Method[] methods) {
- String[] names = new String[methods.length];
- for (int i = 0; i < names.length; i++) {
- names[i] = "$method_" + methods[i].methodDoc().name() + "_" + i;
- }
- return names;
- }
-
- /**
- * Generates an array of names for parameters corresponding to the
- * given array of types for the parameters. Each name in the
- * returned array is guaranteed to be unique.
- *
- * A representation of the type of a parameter is included in its
- * corresponding parameter name to enhance the readability of the
- * generated code.
- **/
- private static String[] nameParameters(Type[] types) {
- String[] names = new String[types.length];
- for (int i = 0; i < names.length; i++) {
- names[i] = "$param_" +
- generateNameFromType(types[i]) + "_" + (i + 1);
- }
- return names;
- }
-
- /**
- * Generates a readable string representing the given type
- * suitable for embedding within a Java identifier.
- **/
- private static String generateNameFromType(Type type) {
- String name = type.typeName().replace('.', '$');
- int dimensions = type.dimension().length() / 2;
- for (int i = 0; i < dimensions; i++) {
- name = "arrayOf_" + name;
- }
- return name;
- }
-
- /**
- * Writes a snippet of Java code to marshal a value named "name"
- * of type "type" to the java.io.ObjectOutput stream named
- * "stream".
- *
- * Primitive types are marshalled with their corresponding methods
- * in the java.io.DataOutput interface, and objects (including
- * arrays) are marshalled using the writeObject method.
- **/
- private static void writeMarshalArgument(IndentingWriter p,
- String streamName,
- Type type, String name)
- throws IOException
- {
- if (type.dimension().length() > 0 || type.asClassDoc() != null) {
- p.p(streamName + ".writeObject(" + name + ")");
- } else if (type.typeName().equals("boolean")) {
- p.p(streamName + ".writeBoolean(" + name + ")");
- } else if (type.typeName().equals("byte")) {
- p.p(streamName + ".writeByte(" + name + ")");
- } else if (type.typeName().equals("char")) {
- p.p(streamName + ".writeChar(" + name + ")");
- } else if (type.typeName().equals("short")) {
- p.p(streamName + ".writeShort(" + name + ")");
- } else if (type.typeName().equals("int")) {
- p.p(streamName + ".writeInt(" + name + ")");
- } else if (type.typeName().equals("long")) {
- p.p(streamName + ".writeLong(" + name + ")");
- } else if (type.typeName().equals("float")) {
- p.p(streamName + ".writeFloat(" + name + ")");
- } else if (type.typeName().equals("double")) {
- p.p(streamName + ".writeDouble(" + name + ")");
- } else {
- throw new AssertionError(type);
- }
- }
-
- /**
- * Writes Java statements to marshal a series of values in order
- * as named in the "names" array, with types as specified in the
- * "types" array, to the java.io.ObjectOutput stream named
- * "stream".
- **/
- private static void writeMarshalArguments(IndentingWriter p,
- String streamName,
- Type[] types, String[] names)
- throws IOException
- {
- assert types.length == names.length;
-
- for (int i = 0; i < types.length; i++) {
- writeMarshalArgument(p, streamName, types[i], names[i]);
- p.pln(";");
- }
- }
-
- /**
- * Writes a snippet of Java code to unmarshal a value of type
- * "type" from the java.io.ObjectInput stream named "stream" into
- * a variable named "name" (if "name" is null, the value is
- * unmarshalled and discarded).
- *
- * Primitive types are unmarshalled with their corresponding
- * methods in the java.io.DataInput interface, and objects
- * (including arrays) are unmarshalled using the readObject
- * method.
- *
- * Returns true if code to invoke readObject was written, and
- * false otherwise.
- **/
- private static boolean writeUnmarshalArgument(IndentingWriter p,
- String streamName,
- Type type, String name)
- throws IOException
- {
- boolean readObject = false;
-
- if (name != null) {
- p.p(name + " = ");
- }
-
- if (type.dimension().length() > 0 || type.asClassDoc() != null) {
- p.p("(" + type.toString() + ") " + streamName + ".readObject()");
- readObject = true;
- } else if (type.typeName().equals("boolean")) {
- p.p(streamName + ".readBoolean()");
- } else if (type.typeName().equals("byte")) {
- p.p(streamName + ".readByte()");
- } else if (type.typeName().equals("char")) {
- p.p(streamName + ".readChar()");
- } else if (type.typeName().equals("short")) {
- p.p(streamName + ".readShort()");
- } else if (type.typeName().equals("int")) {
- p.p(streamName + ".readInt()");
- } else if (type.typeName().equals("long")) {
- p.p(streamName + ".readLong()");
- } else if (type.typeName().equals("float")) {
- p.p(streamName + ".readFloat()");
- } else if (type.typeName().equals("double")) {
- p.p(streamName + ".readDouble()");
- } else {
- throw new AssertionError(type);
- }
-
- return readObject;
- }
-
- /**
- * Writes Java statements to unmarshal a series of values in order
- * of types as in the "types" array from the java.io.ObjectInput
- * stream named "stream" into variables as named in "names" (for
- * any element of "names" that is null, the corresponding value is
- * unmarshalled and discarded).
- **/
- private static boolean writeUnmarshalArguments(IndentingWriter p,
- String streamName,
- Type[] types,
- String[] names)
- throws IOException
- {
- assert types.length == names.length;
-
- boolean readObject = false;
- for (int i = 0; i < types.length; i++) {
- if (writeUnmarshalArgument(p, streamName, types[i], names[i])) {
- readObject = true;
- }
- p.pln(";");
- }
- return readObject;
- }
-
- /**
- * Returns a snippet of Java code to wrap a value named "name" of
- * type "type" into an object as appropriate for use by the Java
- * Reflection API.
- *
- * For primitive types, an appropriate wrapper class is
- * instantiated with the primitive value. For object types
- * (including arrays), no wrapping is necessary, so the value is
- * named directly.
- **/
- private static String wrapArgumentCode(Type type, String name) {
- if (type.dimension().length() > 0 || type.asClassDoc() != null) {
- return name;
- } else if (type.typeName().equals("boolean")) {
- return ("(" + name +
- " ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE)");
- } else if (type.typeName().equals("byte")) {
- return "new java.lang.Byte(" + name + ")";
- } else if (type.typeName().equals("char")) {
- return "new java.lang.Character(" + name + ")";
- } else if (type.typeName().equals("short")) {
- return "new java.lang.Short(" + name + ")";
- } else if (type.typeName().equals("int")) {
- return "new java.lang.Integer(" + name + ")";
- } else if (type.typeName().equals("long")) {
- return "new java.lang.Long(" + name + ")";
- } else if (type.typeName().equals("float")) {
- return "new java.lang.Float(" + name + ")";
- } else if (type.typeName().equals("double")) {
- return "new java.lang.Double(" + name + ")";
- } else {
- throw new AssertionError(type);
- }
- }
-
- /**
- * Returns a snippet of Java code to unwrap a value named "name"
- * into a value of type "type", as appropriate for the Java
- * Reflection API.
- *
- * For primitive types, the value is assumed to be of the
- * corresponding wrapper class, and a method is called on the
- * wrapper to retrieve the primitive value. For object types
- * (include arrays), no unwrapping is necessary; the value is
- * simply cast to the expected real object type.
- **/
- private static String unwrapArgumentCode(Type type, String name) {
- if (type.dimension().length() > 0 || type.asClassDoc() != null) {
- return "((" + type.toString() + ") " + name + ")";
- } else if (type.typeName().equals("boolean")) {
- return "((java.lang.Boolean) " + name + ").booleanValue()";
- } else if (type.typeName().equals("byte")) {
- return "((java.lang.Byte) " + name + ").byteValue()";
- } else if (type.typeName().equals("char")) {
- return "((java.lang.Character) " + name + ").charValue()";
- } else if (type.typeName().equals("short")) {
- return "((java.lang.Short) " + name + ").shortValue()";
- } else if (type.typeName().equals("int")) {
- return "((java.lang.Integer) " + name + ").intValue()";
- } else if (type.typeName().equals("long")) {
- return "((java.lang.Long) " + name + ").longValue()";
- } else if (type.typeName().equals("float")) {
- return "((java.lang.Float) " + name + ").floatValue()";
- } else if (type.typeName().equals("double")) {
- return "((java.lang.Double) " + name + ").doubleValue()";
- } else {
- throw new AssertionError(type);
- }
- }
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/jrmp/Util.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic.jrmp;
-
-import com.sun.javadoc.ClassDoc;
-import com.sun.javadoc.MethodDoc;
-import com.sun.javadoc.Parameter;
-import com.sun.javadoc.Type;
-
-/**
- * Provides static utility methods.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API. Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-final class Util {
-
- private Util() { throw new AssertionError(); }
-
- /**
- * Returns the binary name of the class or interface represented
- * by the specified ClassDoc.
- **/
- static String binaryNameOf(ClassDoc cl) {
- String flat = cl.name().replace('.', '$');
- String packageName = cl.containingPackage().name();
- return packageName.equals("") ? flat : packageName + "." + flat;
- }
-
- /**
- * Returns the method descriptor for the specified method.
- *
- * See section 4.3.3 of The Java Virtual Machine Specification
- * Second Edition for the definition of a "method descriptor".
- **/
- static String methodDescriptorOf(MethodDoc method) {
- String desc = "(";
- Parameter[] parameters = method.parameters();
- for (int i = 0; i < parameters.length; i++) {
- desc += typeDescriptorOf(parameters[i].type());
- }
- desc += ")" + typeDescriptorOf(method.returnType());
- return desc;
- }
-
- /**
- * Returns the descriptor for the specified type, as appropriate
- * for either a parameter or return type in a method descriptor.
- **/
- private static String typeDescriptorOf(Type type) {
- String desc;
- ClassDoc classDoc = type.asClassDoc();
- if (classDoc == null) {
- /*
- * Handle primitive types.
- */
- String name = type.typeName();
- if (name.equals("boolean")) {
- desc = "Z";
- } else if (name.equals("byte")) {
- desc = "B";
- } else if (name.equals("char")) {
- desc = "C";
- } else if (name.equals("short")) {
- desc = "S";
- } else if (name.equals("int")) {
- desc = "I";
- } else if (name.equals("long")) {
- desc = "J";
- } else if (name.equals("float")) {
- desc = "F";
- } else if (name.equals("double")) {
- desc = "D";
- } else if (name.equals("void")) {
- desc = "V";
- } else {
- throw new AssertionError(
- "unrecognized primitive type: " + name);
- }
- } else {
- /*
- * Handle non-array reference types.
- */
- desc = "L" + binaryNameOf(classDoc).replace('.', '/') + ";";
- }
-
- /*
- * Handle array types.
- */
- int dimensions = type.dimension().length() / 2;
- for (int i = 0; i < dimensions; i++) {
- desc = "[" + desc;
- }
-
- return desc;
- }
-
- /**
- * Returns a reader-friendly string representation of the
- * specified method's signature. Names of reference types are not
- * package-qualified.
- **/
- static String getFriendlyUnqualifiedSignature(MethodDoc method) {
- String sig = method.name() + "(";
- Parameter[] parameters = method.parameters();
- for (int i = 0; i < parameters.length; i++) {
- if (i > 0) {
- sig += ", ";
- }
- Type paramType = parameters[i].type();
- sig += paramType.typeName() + paramType.dimension();
- }
- sig += ")";
- return sig;
- }
-
- /**
- * Returns true if the specified type is void.
- **/
- static boolean isVoid(Type type) {
- return type.asClassDoc() == null && type.typeName().equals("void");
- }
-}
--- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java Wed Nov 08 16:03:35 2017 -0500
@@ -25,7 +25,6 @@
package jdk.nashorn.tools.jjs;
-import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -69,7 +68,7 @@
});
in.addCompleter(completer);
Runtime.getRuntime().addShutdownHook(new Thread((Runnable)this::saveHistory));
- bind(DOCUMENTATION_SHORTCUT, (ActionListener)evt -> showDocumentation(docHelper));
+ bind(DOCUMENTATION_SHORTCUT, (Runnable) ()->showDocumentation(docHelper));
try {
Signal.handle(new Signal("CONT"), new Handler() {
@Override public void handle(Signal sig) {
--- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/EditObject.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/EditObject.java Wed Nov 08 16:03:35 2017 -0500
@@ -117,7 +117,7 @@
final SaveHandler saveHandler = new SaveHandler(initText);
if (editor != null && !editor.isEmpty()) {
ExternalEditor.edit(editor, errorHandler, initText, saveHandler, console);
- } else if (! Main.HEADLESS) {
+ } else {
try {
ServiceLoader<BuildInEditorProvider> sl
= ServiceLoader.load(BuildInEditorProvider.class);
@@ -136,8 +136,6 @@
} catch (RuntimeException ex) {
errorHandler.accept(Main.getMessage("jjs.err.cant.launch.editor"));
}
- } else {
- errorHandler.accept(Main.getMessage("no.editor"));
}
return UNDEFINED;
}
--- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java Wed Nov 08 16:03:35 2017 -0500
@@ -27,8 +27,6 @@
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-import java.awt.Desktop;
-import java.awt.GraphicsEnvironment;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
@@ -65,7 +63,6 @@
private static final String DOC_PROPERTY_NAME = "__doc__";
static final boolean DEBUG = Boolean.getBoolean("nashorn.jjs.debug");
- static final boolean HEADLESS = GraphicsEnvironment.isHeadless();
// file where history is persisted.
private static final File HIST_FILE = new File(new File(System.getProperty("user.home")), ".jjs.history");
@@ -120,7 +117,49 @@
final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global);
final PropertiesHelper propsHelper = new PropertiesHelper(context);
- final NashornCompleter completer = new NashornCompleter(context, global, this, propsHelper);
+
+ if (globalChanged) {
+ Context.setGlobal(global);
+ }
+
+ // Check if java.desktop module is available and we're running in non-headless mode.
+ // We access AWT via script to avoid direct dependency on java.desktop module.
+ final boolean isHeadless = (boolean) context.eval(global,
+ "(function() { \n" +
+ " var env = java.awt.GraphicsEnvironment; \n" +
+ " return env && typeof env.isHeadless == 'function'? \n" +
+ " env.isHeadless() : true; \n" +
+ "})()",
+ global, "<headless-check>");
+
+ // Function that shows a JFileChooser dialog and returns the file name chosen (if chosen).
+ // We access swing from script to avoid direct dependency on java.desktop module.
+ final ScriptFunction fileChooserFunc = isHeadless? null : (ScriptFunction) context.eval(global,
+ "(function() { \n" +
+ " var ExtensionFilter = javax.swing.filechooser.FileNameExtensionFilter; \n" +
+ " var JFileChooser = javax.swing.JFileChooser; \n" +
+ " function run() { \n" +
+ " var chooser = new JFileChooser(); \n" +
+ " chooser.fileFilter = new ExtensionFilter('JavaScript Files', 'js'); \n" +
+ " var retVal = chooser.showOpenDialog(null); \n" +
+ " return retVal == JFileChooser.APPROVE_OPTION ? \n" +
+ " chooser.selectedFile.absolutePath : null; \n" +
+ " }; \n" +
+ " var fileChooserTask = new java.util.concurrent.FutureTask(run); \n" +
+ " javax.swing.SwingUtilities.invokeLater(fileChooserTask); \n" +
+ " return fileChooserTask.get(); \n" +
+ "})",
+ global, "<file-chooser>");
+
+ final NashornCompleter completer = new NashornCompleter(context, global, this, propsHelper, fileChooserFunc);
+
+ // Function that opens up the desktop browser application with the given URI.
+ // We access AWT from script to avoid direct dependency on java.desktop module.
+ final ScriptFunction browseFunc = isHeadless? null : (ScriptFunction) context.eval(global,
+ "(function(uri) { \n" +
+ " java.awt.Desktop.desktop.browse(uri); \n" +
+ "})",
+ global, "<browse>");
try (final Console in = new Console(System.in, System.out, HIST_FILE, completer,
str -> {
@@ -128,14 +167,14 @@
final Object res = context.eval(global, str, global, "<shell>");
if (res != null && res != UNDEFINED) {
// Special case Java types: show the javadoc for the class.
- if (NativeJava.isType(UNDEFINED, res)) {
+ if (!isHeadless && NativeJava.isType(UNDEFINED, res)) {
final String typeName = NativeJava.typeName(UNDEFINED, res).toString();
final String url = typeName.replace('.', '/').replace('$', '.') + ".html";
- openBrowserForJavadoc(url);
- } else if (res instanceof NativeJavaPackage) {
+ openBrowserForJavadoc(browseFunc, url);
+ } else if (!isHeadless && res instanceof NativeJavaPackage) {
final String pkgName = ((NativeJavaPackage)res).getName();
final String url = pkgName.replace('.', '/') + "/package-summary.html";
- openBrowserForJavadoc(url);
+ openBrowserForJavadoc(browseFunc, url);
} else if (res instanceof ScriptObject) {
final ScriptObject sobj = (ScriptObject)res;
if (sobj.has(DOC_PROPERTY_NAME)) {
@@ -153,10 +192,6 @@
return null;
})) {
- if (globalChanged) {
- Context.setGlobal(global);
- }
-
global.addShellBuiltins();
// redefine readLine to use jline Console's readLine!
@@ -282,11 +317,10 @@
}
private static String JAVADOC_BASE = "https://docs.oracle.com/javase/9/docs/api/";
-
- private static void openBrowserForJavadoc(String relativeUrl) {
+ private static void openBrowserForJavadoc(ScriptFunction browse, String relativeUrl) {
try {
final URI uri = new URI(JAVADOC_BASE + relativeUrl);
- Desktop.getDesktop().browse(uri);
+ ScriptRuntime.apply(browse, null, uri);
} catch (Exception ignored) {
}
}
--- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/NashornCompleter.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/NashornCompleter.java Wed Nov 08 16:03:35 2017 -0500
@@ -29,12 +29,8 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.FutureTask;
+import java.util.Objects;
import java.util.regex.Pattern;
-import javax.swing.JFileChooser;
-import javax.swing.filechooser.FileNameExtensionFilter;
-import javax.swing.SwingUtilities;
import jdk.internal.jline.console.completer.Completer;
import jdk.internal.jline.console.UserInterruptException;
import jdk.nashorn.api.tree.AssignmentTree;
@@ -60,6 +56,7 @@
import jdk.nashorn.internal.runtime.ECMAException;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ScriptEnvironment;
+import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptRuntime;
/**
@@ -72,16 +69,19 @@
private final ScriptEnvironment env;
private final PartialParser partialParser;
private final PropertiesHelper propsHelper;
+ private final ScriptFunction fileChooserFunc;
private final Parser parser;
private static final boolean BACKSLASH_FILE_SEPARATOR = File.separatorChar == '\\';
NashornCompleter(final Context context, final Global global,
- final PartialParser partialParser, final PropertiesHelper propsHelper) {
+ final PartialParser partialParser, final PropertiesHelper propsHelper,
+ final ScriptFunction fileChooserFunc) {
this.context = context;
this.global = global;
this.env = context.getEnv();
this.partialParser = partialParser;
this.propsHelper = propsHelper;
+ this.fileChooserFunc = fileChooserFunc;
this.parser = createParser(env);
}
@@ -236,8 +236,9 @@
final ExpressionTree topExpr = getTopLevelExpression(parser, completeExpr);
if (topExpr == null) {
- // special case for load call that looks like "load(" with optional whitespaces
- if (LOAD_CALL.matcher(test).matches()) {
+ // Special case for load call that looks like "load(" with optional whitespaces.
+ // If we have a fileChooserFunc then call it, so that the user can select a file.
+ if (fileChooserFunc != null && LOAD_CALL.matcher(test).matches()) {
String name = readFileName(context.getErr());
if (name != null) {
// handle '\' file separator
@@ -269,26 +270,11 @@
// Internals only below this point
// read file name from the user using by showing a swing file chooser diablog
- private static String readFileName(final PrintWriter err) {
- // if running on AWT Headless mode, don't attempt swing dialog box!
- if (Main.HEADLESS) {
- return null;
- }
-
- final FutureTask<String> fileChooserTask = new FutureTask<String>(() -> {
- // show a file chooser dialog box
- final JFileChooser chooser = new JFileChooser();
- chooser.setFileFilter(new FileNameExtensionFilter("JavaScript Files", "js"));
- final int retVal = chooser.showOpenDialog(null);
- return retVal == JFileChooser.APPROVE_OPTION ?
- chooser.getSelectedFile().getAbsolutePath() : null;
- });
-
- SwingUtilities.invokeLater(fileChooserTask);
-
+ private String readFileName(final PrintWriter err) {
try {
- return fileChooserTask.get();
- } catch (final ExecutionException | InterruptedException e) {
+ final Object res = ScriptRuntime.apply(fileChooserFunc, null);
+ return res instanceof String? (String)res : null;
+ } catch (final Exception e) {
err.println(e);
if (Main.DEBUG) {
e.printStackTrace();
--- a/src/jdk.scripting.nashorn.shell/share/classes/module-info.java Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.scripting.nashorn.shell/share/classes/module-info.java Wed Nov 08 16:03:35 2017 -0500
@@ -39,7 +39,6 @@
*/
module jdk.scripting.nashorn.shell {
requires java.compiler;
- requires java.desktop;
requires jdk.internal.le;
requires jdk.scripting.nashorn;
requires jdk.internal.ed;
--- a/test/TestCommon.gmk Mon Nov 06 19:45:47 2017 +0100
+++ b/test/TestCommon.gmk Wed Nov 08 16:03:35 2017 -0500
@@ -188,6 +188,16 @@
CLEAN_ARCHIVE_BUNDLE = @$(RM) $(ARCHIVE_BUNDLE)
endif
+# AddressSanitizer
+ifeq ($(ASAN_ENABLED), yes)
+ export ASAN_OPTIONS="handle_segv=0 detect_leaks=0"
+ JTREG_BASIC_OPTIONS += -e:ASAN_OPTIONS=$(ASAN_OPTIONS)
+ ifneq ($(DEVKIT_LIB_DIR),)
+ export LD_LIBRARY_PATH:=$(LD_LIBRARY_PATH):$(DEVKIT_LIB_DIR)
+ JTREG_BASIC_OPTIONS += -e:LD_LIBRARY_PATH=$(LD_LIBRARY_PATH)
+ endif
+endif
+
# important results files
SUMMARY_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport/text/summary.txt")
STATS_TXT_NAME = Stats.txt
--- a/test/hotspot/jtreg/TEST.groups Mon Nov 06 19:45:47 2017 +0100
+++ b/test/hotspot/jtreg/TEST.groups Wed Nov 08 16:03:35 2017 -0500
@@ -107,15 +107,11 @@
-compiler/loopopts/Test7052494.java \
-compiler/runtime/Test6826736.java
-hotspot_tier1_compiler_closed = \
- sanity/ExecuteInternalVMTests.java
-
hotspot_not_fast_compiler = \
:hotspot_compiler \
-:hotspot_tier1_compiler_1 \
-:hotspot_tier1_compiler_2 \
-:hotspot_tier1_compiler_3 \
- -:hotspot_tier1_compiler_closed
hotspot_tier1_gc_1 = \
gc/g1/
@@ -130,9 +126,6 @@
-gc/cms/TestMBeanCMS.java \
-gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java
-hotspot_tier1_gc_closed = \
- sanity/ExecuteInternalVMTests.java
-
hotspot_tier1_gc_gcold = \
gc/stress/gcold/TestGCOldWithG1.java
gc/stress/gcold/TestGCOldWithCMS.java
@@ -204,10 +197,8 @@
:hotspot_tier1_compiler_1 \
:hotspot_tier1_compiler_2 \
:hotspot_tier1_compiler_3 \
- :hotspot_tier1_compiler_closed \
:hotspot_tier1_gc_1 \
:hotspot_tier1_gc_2 \
- :hotspot_tier1_gc_closed \
:hotspot_tier1_gc_gcold \
:hotspot_tier1_runtime \
:hotspot_tier1_serviceability
--- a/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGC.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGC.java Wed Nov 08 16:03:35 2017 -0500
@@ -103,6 +103,8 @@
}
public class TestSystemGC {
+ private static long endTime;
+
private static final int numGroups = 7;
private static final int numGCsPerGroup = 4;
@@ -133,8 +135,11 @@
for (int i = 0; i < numGroups; i++) {
for (int j = 0; j < numGCsPerGroup; j++) {
- System.gc();
- ThreadUtils.sleep(getDelayMS(i));
+ System.gc();
+ if (System.currentTimeMillis() >= endTime) {
+ return;
+ }
+ ThreadUtils.sleep(getDelayMS(i));
}
}
}
@@ -159,7 +164,7 @@
}
private static void runAllPhases() {
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < 4 && System.currentTimeMillis() < endTime; i++) {
SystemGCTask gcTask =
(i % 2 == 1) ? createSystemGCTask(numGroups / 3) : null;
ShortLivedAllocationTask shortTask =
@@ -181,12 +186,15 @@
}
}
- public static void main(String[] args) {
+ public static void main(String[] args) throws Exception {
+ if (args.length == 0) {
+ throw new IllegalArgumentException("Must specify timeout in seconds as first argument");
+ }
+ int timeout = Integer.parseInt(args[0]) * 1000;
+ System.out.println("Running with timeout of " + timeout + "ms");
+ endTime = System.currentTimeMillis() + timeout;
// First allocate the long lived objects and then run all phases.
populateLongLived();
runAllPhases();
- if (args.length > 0 && args[0].equals("long")) {
- runAllPhases();
- }
}
}
--- a/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithCMS.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithCMS.java Wed Nov 08 16:03:35 2017 -0500
@@ -24,14 +24,15 @@
/*
* @test TestSystemGCWithCMS
+ * @bug 8190703
* @key gc
* @key stress
* @requires vm.gc.ConcMarkSweep
* @summary Stress the CMS GC full GC by allocating objects of different lifetimes concurrently with System.gc().
- * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseConcMarkSweepGC TestSystemGCWithCMS
+ * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseConcMarkSweepGC TestSystemGCWithCMS 270
*/
public class TestSystemGCWithCMS {
- public static void main(String[] args) {
+ public static void main(String[] args) throws Exception {
TestSystemGC.main(args);
}
}
--- a/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithG1.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithG1.java Wed Nov 08 16:03:35 2017 -0500
@@ -24,14 +24,15 @@
/*
* @test TestSystemGCWithG1
+ * @bug 8190703
* @key gc
* @key stress
* @requires vm.gc.G1
* @summary Stress the G1 GC full GC by allocating objects of different lifetimes concurrently with System.gc().
- * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseG1GC TestSystemGCWithG1
+ * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseG1GC TestSystemGCWithG1 270
*/
public class TestSystemGCWithG1 {
- public static void main(String[] args) {
+ public static void main(String[] args) throws Exception {
TestSystemGC.main(args);
}
}
--- a/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithParallel.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithParallel.java Wed Nov 08 16:03:35 2017 -0500
@@ -24,14 +24,15 @@
/*
* @test TestSystemGCWithParallel
+ * @bug 8190703
* @key gc
* @key stress
* @requires vm.gc.Parallel
* @summary Stress the Parallel GC full GC by allocating objects of different lifetimes concurrently with System.gc().
- * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseParallelGC TestSystemGCWithParallel
+ * @run main/othervm/timeout=300 -Xlog:gc=info -Xmx512m -XX:+UseParallelGC TestSystemGCWithParallel 270
*/
public class TestSystemGCWithParallel {
- public static void main(String[] args) {
+ public static void main(String[] args) throws Exception {
TestSystemGC.main(args);
}
}
--- a/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithSerial.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithSerial.java Wed Nov 08 16:03:35 2017 -0500
@@ -24,14 +24,15 @@
/*
* @test TestSystemGCWithSerial
+ * @bug 8190703
* @key gc
* @key stress
* @requires vm.gc.Serial
* @summary Stress the Serial GC full GC by allocating objects of different lifetimes concurrently with System.gc().
- * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseSerialGC TestSystemGCWithSerial
+ * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseSerialGC TestSystemGCWithSerial 270
*/
public class TestSystemGCWithSerial {
- public static void main(String[] args) {
+ public static void main(String[] args) throws Exception {
TestSystemGC.main(args);
}
}
--- a/test/hotspot/jtreg/runtime/constantPool/ConstModule.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/hotspot/jtreg/runtime/constantPool/ConstModule.java Wed Nov 08 16:03:35 2017 -0500
@@ -47,13 +47,13 @@
// 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,
+ ConstModule.write_and_load(Opcodes.V9,
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,
+ ConstModule.write_and_load(Opcodes.V9,
Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC + ACC_MODULE,
"jdk.fooModACC", "FooModACC", MODULE_TEST, NCDFE_EXCEPTION);
@@ -65,13 +65,13 @@
// 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,
+ ConstModule.write_and_load(Opcodes.V9,
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,
+ ConstModule.write_and_load(Opcodes.V9,
Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC + ACC_MODULE,
"jdk.fooModACC", "FooModACC", PACKAGE_TEST, NCDFE_EXCEPTION);
--- a/test/jdk/ProblemList.txt Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/ProblemList.txt Wed Nov 08 16:03:35 2017 -0500
@@ -200,6 +200,8 @@
java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup.java 8169569 windows-all
+java/rmi/activation/rmidViaInheritedChannel/InheritedChannelNotServerSocket.java 8170562 generic-all
+
java/rmi/registry/readTest/CodebaseTest.java 8173324 windows-all
############################################################################
@@ -308,8 +310,12 @@
com/sun/jndi/ldap/DeadSSLLdapTimeoutTest.java 8169942 linux-i586,macosx-all,windows-x64
-javax/rmi/PortableRemoteObject/8146975/RmiIiopReturnValueTest.java 8169737 linux-all
-
+javax/rmi/PortableRemoteObject/8146975/RmiIiopReturnValueTest.java 8169737 generic-all
+
org/omg/CORBA/OrbPropertiesTest.java 8175177 generic-all
+javax/rmi/PortableRemoteObject/ConcurrentHashMapTest.java 8080643 generic-all
+
+javax/rmi/ssl/SSLSocketParametersTest.sh 8162906 generic-all
+
############################################################################
--- a/test/jdk/com/sun/awt/Translucency/WindowOpacity.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,467 +0,0 @@
-/*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- @test %W% %E%
- @key headful
- @bug 6594131
- @summary Tests the AWTUtilities.get/setWindowOpacity() methods
- @author anthony.petrov@...: area=awt.toplevel
- @modules java.desktop/com.sun.awt
- @run main WindowOpacity
-*/
-
-import java.awt.*;
-import java.awt.event.*;
-
-import com.sun.awt.AWTUtilities;
-
-public class WindowOpacity
-{
- //*** test-writer defined static variables go here ***
-
- private static Robot robot;
-
-
- private static void init()
- {
- //*** Create instructions for the user here ***
- String[] instructions =
- {
- "This is an AUTOMATIC test, simply wait until it is done.",
- "The result (passed or failed) will be shown in the",
- "message window below."
- };
- Sysout.createDialog( );
- Sysout.printInstructions( instructions );
-
- if (!AWTUtilities.isTranslucencySupported(AWTUtilities.Translucency.TRANSLUCENT)) {
- System.out.println("Either the Toolkit or the native system does not support controlling the window opacity level.");
- pass();
- }
- try {
- robot = new Robot();
- }catch(Exception ex) {
- ex.printStackTrace();
- throw new RuntimeException ("Unexpected failure");
- }
-
- boolean passed;
-
- Frame f = new Frame("Opacity test");
- f.setUndecorated(true);
-
- passed = false;
- try {
- AWTUtilities.getWindowOpacity(null);
- } catch (NullPointerException e) {
- passed = true;
- }
- if (!passed) {
- fail("getWindowOpacity() allows passing null.");
- }
-
-
- passed = false;
- try {
- AWTUtilities.setWindowOpacity(null, 0.5f);
- } catch (NullPointerException e) {
- passed = true;
- }
- if (!passed) {
- fail("setWindowOpacity() allows passing null.");
- }
-
-
- float curOpacity = AWTUtilities.getWindowOpacity(f);
- if (curOpacity < 1.0f || curOpacity > 1.0f) {
- fail("getWindowOpacity() reports the initial opacity level other than 1.0: " + curOpacity);
- }
-
-
-
- passed = false;
- try {
- AWTUtilities.setWindowOpacity(f, -0.5f);
- } catch (IllegalArgumentException e) {
- passed = true;
- }
- if (!passed) {
- fail("setWindowOpacity() allows passing negative opacity level.");
- }
-
-
-
- passed = false;
- try {
- AWTUtilities.setWindowOpacity(f, 1.5f);
- } catch (IllegalArgumentException e) {
- passed = true;
- }
- if (!passed) {
- fail("setWindowOpacity() allows passing opacity level greater than 1.0.");
- }
-
-
- AWTUtilities.setWindowOpacity(f, 0.5f);
-
- curOpacity = AWTUtilities.getWindowOpacity(f);
- if (curOpacity < 0.5f || curOpacity > 0.5f) {
- fail("getWindowOpacity() reports the opacity level that differs from the value set with setWindowOpacity: " + curOpacity);
- }
-
-
- AWTUtilities.setWindowOpacity(f, 0.75f);
-
- curOpacity = AWTUtilities.getWindowOpacity(f);
- if (curOpacity < 0.75f || curOpacity > 0.75f) {
- fail("getWindowOpacity() reports the opacity level that differs from the value set with setWindowOpacity the second time: " + curOpacity);
- }
-
-
- f.setBounds(100, 100, 300, 200);
- f.setVisible(true);
-
- robot.waitForIdle();
-
- curOpacity = AWTUtilities.getWindowOpacity(f);
- if (curOpacity < 0.75f || curOpacity > 0.75f) {
- fail("getWindowOpacity() reports the opacity level that differs from the value set with setWindowOpacity before showing the frame: " + curOpacity);
- }
-
-
-
- AWTUtilities.setWindowOpacity(f, 0.5f);
- robot.waitForIdle();
-
- curOpacity = AWTUtilities.getWindowOpacity(f);
- if (curOpacity < 0.5f || curOpacity > 0.5f) {
- fail("getWindowOpacity() reports the opacity level that differs from the value set with setWindowOpacity after showing the frame: " + curOpacity);
- }
-
- WindowOpacity.pass();
-
- }//End init()
-
-
-
- /*****************************************************
- * Standard Test Machinery Section
- * DO NOT modify anything in this section -- it's a
- * standard chunk of code which has all of the
- * synchronisation necessary for the test harness.
- * By keeping it the same in all tests, it is easier
- * to read and understand someone else's test, as
- * well as insuring that all tests behave correctly
- * with the test harness.
- * There is a section following this for test-
- * classes
- ******************************************************/
- private static boolean theTestPassed = false;
- private static boolean testGeneratedInterrupt = false;
- private static String failureMessage = "";
-
- private static Thread mainThread = null;
-
- private static int sleepTime = 300000;
-
- // Not sure about what happens if multiple of this test are
- // instantiated in the same VM. Being static (and using
- // static vars), it aint gonna work. Not worrying about
- // it for now.
- public static void main( String args[] ) throws InterruptedException
- {
- mainThread = Thread.currentThread();
- try
- {
- init();
- }
- catch( TestPassedException e )
- {
- //The test passed, so just return from main and harness will
- // interepret this return as a pass
- return;
- }
- //At this point, neither test pass nor test fail has been
- // called -- either would have thrown an exception and ended the
- // test, so we know we have multiple threads.
-
- //Test involves other threads, so sleep and wait for them to
- // called pass() or fail()
- try
- {
- Thread.sleep( sleepTime );
- //Timed out, so fail the test
- throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
- }
- catch (InterruptedException e)
- {
- //The test harness may have interrupted the test. If so, rethrow the exception
- // so that the harness gets it and deals with it.
- if( ! testGeneratedInterrupt ) throw e;
-
- //reset flag in case hit this code more than once for some reason (just safety)
- testGeneratedInterrupt = false;
-
- if ( theTestPassed == false )
- {
- throw new RuntimeException( failureMessage );
- }
- }
-
- }//main
-
- public static synchronized void setTimeoutTo( int seconds )
- {
- sleepTime = seconds * 1000;
- }
-
- public static synchronized void pass()
- {
- Sysout.println( "The test passed." );
- Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
- //first check if this is executing in main thread
- if ( mainThread == Thread.currentThread() )
- {
- //Still in the main thread, so set the flag just for kicks,
- // and throw a test passed exception which will be caught
- // and end the test.
- theTestPassed = true;
- throw new TestPassedException();
- }
- theTestPassed = true;
- testGeneratedInterrupt = true;
- mainThread.interrupt();
- }//pass()
-
- public static synchronized void fail()
- {
- //test writer didn't specify why test failed, so give generic
- fail( "it just plain failed! :-)" );
- }
-
- public static synchronized void fail( String whyFailed )
- {
- Sysout.println( "The test failed: " + whyFailed );
- Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
- //check if this called from main thread
- if ( mainThread == Thread.currentThread() )
- {
- //If main thread, fail now 'cause not sleeping
- throw new RuntimeException( whyFailed );
- }
- theTestPassed = false;
- testGeneratedInterrupt = true;
- failureMessage = whyFailed;
- mainThread.interrupt();
- }//fail()
-
-}// class WindowOpacity
-
-//This exception is used to exit from any level of call nesting
-// when it's determined that the test has passed, and immediately
-// end the test.
-class TestPassedException extends RuntimeException
-{
-}
-
-//*********** End Standard Test Machinery Section **********
-
-
-//************ Begin classes defined for the test ****************
-
-// if want to make listeners, here is the recommended place for them, then instantiate
-// them in init()
-
-/* Example of a class which may be written as part of a test
-class NewClass implements anInterface
- {
- static int newVar = 0;
-
- public void eventDispatched(AWTEvent e)
- {
- //Counting events to see if we get enough
- eventCount++;
-
- if( eventCount == 20 )
- {
- //got enough events, so pass
-
- WindowOpacity.pass();
- }
- else if( tries == 20 )
- {
- //tried too many times without getting enough events so fail
-
- WindowOpacity.fail();
- }
-
- }// eventDispatched()
-
- }// NewClass class
-
-*/
-
-
-//************** End classes defined for the test *******************
-
-
-
-
-/****************************************************
- Standard Test Machinery
- DO NOT modify anything below -- it's a standard
- chunk of code whose purpose is to make user
- interaction uniform, and thereby make it simpler
- to read and understand someone else's test.
- ****************************************************/
-
-/**
- This is part of the standard test machinery.
- It creates a dialog (with the instructions), and is the interface
- for sending text messages to the user.
- To print the instructions, send an array of strings to Sysout.createDialog
- WithInstructions method. Put one line of instructions per array entry.
- To display a message for the tester to see, simply call Sysout.println
- with the string to be displayed.
- This mimics System.out.println but works within the test harness as well
- as standalone.
- */
-
-class Sysout
-{
- private static TestDialog dialog;
-
- public static void createDialogWithInstructions( String[] instructions )
- {
- dialog = new TestDialog( new Frame(), "Instructions" );
- dialog.printInstructions( instructions );
- dialog.setVisible(true);
- println( "Any messages for the tester will display here." );
- }
-
- public static void createDialog( )
- {
- dialog = new TestDialog( new Frame(), "Instructions" );
- String[] defInstr = { "Instructions will appear here. ", "" } ;
- dialog.printInstructions( defInstr );
- dialog.setVisible(true);
- println( "Any messages for the tester will display here." );
- }
-
-
- public static void printInstructions( String[] instructions )
- {
- dialog.printInstructions( instructions );
- }
-
-
- public static void println( String messageIn )
- {
- dialog.displayMessage( messageIn );
- System.out.println(messageIn);
- }
-
-}// Sysout class
-
-/**
- This is part of the standard test machinery. It provides a place for the
- test instructions to be displayed, and a place for interactive messages
- to the user to be displayed.
- To have the test instructions displayed, see Sysout.
- To have a message to the user be displayed, see Sysout.
- Do not call anything in this dialog directly.
- */
-class TestDialog extends Dialog
-{
-
- TextArea instructionsText;
- TextArea messageText;
- int maxStringLength = 80;
-
- //DO NOT call this directly, go through Sysout
- public TestDialog( Frame frame, String name )
- {
- super( frame, name );
- int scrollBoth = TextArea.SCROLLBARS_BOTH;
- instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
- add( "North", instructionsText );
-
- messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
- add("Center", messageText);
-
- pack();
-
- setVisible(true);
- }// TestDialog()
-
- //DO NOT call this directly, go through Sysout
- public void printInstructions( String[] instructions )
- {
- //Clear out any current instructions
- instructionsText.setText( "" );
-
- //Go down array of instruction strings
-
- String printStr, remainingStr;
- for( int i=0; i < instructions.length; i++ )
- {
- //chop up each into pieces maxSringLength long
- remainingStr = instructions[ i ];
- while( remainingStr.length() > 0 )
- {
- //if longer than max then chop off first max chars to print
- if( remainingStr.length() >= maxStringLength )
- {
- //Try to chop on a word boundary
- int posOfSpace = remainingStr.
- lastIndexOf( ' ', maxStringLength - 1 );
-
- if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
-
- printStr = remainingStr.substring( 0, posOfSpace + 1 );
- remainingStr = remainingStr.substring( posOfSpace + 1 );
- }
- //else just print
- else
- {
- printStr = remainingStr;
- remainingStr = "";
- }
-
- instructionsText.append( printStr + "\n" );
-
- }// while
-
- }// for
-
- }//printInstructions()
-
- //DO NOT call this directly, go through Sysout
- public void displayMessage( String messageIn )
- {
- messageText.append( messageIn + "\n" );
- System.out.println(messageIn);
- }
-
-}// TestDialog class
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/Dialog/SiblingChildOrder/SiblingChildOrderTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,79 @@
+/*
+ * 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 8190230
+ * @summary [macosx] Order of overlapping of modal dialogs is wrong
+ * @run main SiblingChildOrderTest
+ */
+
+import javax.swing.*;
+import java.awt.*;
+
+public class SiblingChildOrderTest
+
+{
+ static Color[] colors = new Color[]{Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW};
+ static int[] x = new int[]{200, 150, 100, 50};
+ static int[] y = new int[]{200, 150, 100, 50};
+ static JDialog[] dlgs = new JDialog[4];
+ private static JFrame frame;
+
+ public static void main(String args[]) throws Exception {
+ SwingUtilities.invokeAndWait(() -> {
+ frame = new JFrame("FRAME");
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.setBounds(50, 50, 400, 400);
+ frame.setVisible(true);
+ });
+
+ for (int i = 0; i < colors.length; i++) {
+ int finalI = i;
+ SwingUtilities.invokeLater(() -> {
+ dlgs[finalI] = new JDialog(frame, "DLG " + finalI, true);
+ dlgs[finalI].getContentPane().setBackground(colors[finalI]);
+ dlgs[finalI].setBounds(x[finalI], y[finalI], 200, 200);
+ dlgs[finalI].setVisible(true);
+
+ });
+ }
+
+ Robot robot = new Robot();
+ robot.waitForIdle();
+ robot.delay(200);
+
+ for (int i = 0; i < colors.length; i++) {
+ Color c = robot.getPixelColor(x[i] + 190, y[i] + 190);
+ if (!c.equals(colors[i])) {
+ throw new RuntimeException("Expected " + colors[i] + " got " + c);
+ }
+ }
+
+ for (int i = 0; i < colors.length; i++) {
+ SwingUtilities.invokeLater(dlgs[i]::dispose);
+ }
+
+ SwingUtilities.invokeLater(frame::dispose);
+
+ }
+}
--- a/test/jdk/java/awt/Window/ScreenLocation/ScreenLocationTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/java/awt/Window/ScreenLocation/ScreenLocationTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 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
@@ -24,7 +24,7 @@
/*
* @test
* @key headful
- * @bug 8011616
+ * @bug 8011616 8145795
* @summary JWindow.getLocation and JWindow.getLocationOnScreen return different
* values on Unity
* @author Semyon Sadetsky
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/Window/ShapedAndTranslucentWindows/WindowOpacity.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,139 @@
+/*
+ * 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
+ * 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
+ @key headful
+ @bug 6594131 8186617
+ @summary Tests the Window.get/setOpacity() methods
+*/
+
+import java.awt.AWTException;
+import java.awt.Frame;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Robot;
+
+public class WindowOpacity {
+
+ public static void main(String[] args) throws Exception {
+ GraphicsDevice gd =
+ GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice();
+ if (!gd.isWindowTranslucencySupported(
+ GraphicsDevice.WindowTranslucency.TRANSLUCENT)) {
+ System.out.println(
+ "Either the Toolkit or the native system does not support"
+ + " controlling the window opacity level.");
+ return;
+ }
+ Frame f = new Frame("Opacity test");
+ try {
+ test(f);
+ } finally {
+ f.dispose();
+ }
+ }
+
+ private static void test(final Frame f) throws AWTException {
+ boolean passed;
+
+ f.setUndecorated(true);
+ float curOpacity = f.getOpacity();
+ if (curOpacity < 1.0f || curOpacity > 1.0f) {
+ throw new RuntimeException(
+ "getOpacity() reports the initial opacity level "
+ + "other than 1.0: " + curOpacity);
+ }
+
+
+ passed = false;
+ try {
+ f.setOpacity(-0.5f);
+ } catch (IllegalArgumentException e) {
+ passed = true;
+ }
+ if (!passed) {
+ throw new RuntimeException(
+ "setOpacity() allows passing negative opacity level.");
+ }
+
+
+ passed = false;
+ try {
+ f.setOpacity(1.5f);
+ } catch (IllegalArgumentException e) {
+ passed = true;
+ }
+ if (!passed) {
+ throw new RuntimeException(
+ "setOpacity() allows passing opacity level greater than 1.0.");
+ }
+
+
+ f.setOpacity(0.5f);
+ curOpacity = f.getOpacity();
+ if (curOpacity < 0.5f || curOpacity > 0.5f) {
+ throw new RuntimeException(
+ "setOpacity() reports the opacity level that "
+ + "differs from the value set with "
+ + "setWindowOpacity: " + curOpacity);
+ }
+
+
+ f.setOpacity(0.75f);
+ curOpacity = f.getOpacity();
+ if (curOpacity < 0.75f || curOpacity > 0.75f) {
+ throw new RuntimeException(
+ "getOpacity() reports the opacity level that "
+ + "differs from the value set with "
+ + "setWindowOpacity the second time: "
+ + curOpacity);
+ }
+
+
+ f.setBounds(100, 100, 300, 200);
+ f.setVisible(true);
+ Robot robot = new Robot();
+ robot.waitForIdle();
+
+ curOpacity = f.getOpacity();
+ if (curOpacity < 0.75f || curOpacity > 0.75f) {
+ throw new RuntimeException(
+ "getOpacity() reports the opacity level that "
+ + "differs from the value set with "
+ + "setWindowOpacity before showing the frame: "
+ + curOpacity);
+ }
+ f.setOpacity(0.5f);
+ robot.waitForIdle();
+ curOpacity = f.getOpacity();
+ if (curOpacity < 0.5f || curOpacity > 0.5f) {
+ throw new RuntimeException(
+ "getOpacity() reports the opacity level that "
+ + "differs from the value set with "
+ + "setWindowOpacity after showing the frame: "
+ + curOpacity);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/dnd/DnDTestWithHIDPI/DragTestWithHIDPI.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,209 @@
+/*
+ * 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
+ * @key headful
+ * @bug 8159062
+ * @summary Tests DnD property with HIDPI scale set to non-interger value 2.5
+ * @run main/othervm -Dsun.java2d.uiScale=2.5 DragTestWithHIDPI
+ */
+
+import javax.swing.JList;
+import javax.swing.TransferHandler;
+import javax.swing.JFrame;
+import javax.swing.JComponent;
+import javax.swing.SwingUtilities;
+
+import java.awt.Robot;
+import java.awt.BorderLayout;
+import java.awt.Point;
+import java.awt.Dimension;
+import java.awt.MouseInfo;
+import java.awt.event.InputEvent;
+
+public class DragTestWithHIDPI extends TransferHandler {
+
+ private static boolean didDrag = false;
+ private static int threshold = 10;
+ private static int DEFAULT_DELAY = 550;
+
+ private Robot robot = null;
+ private static JList list = null;
+ private static Point listLocation = null;
+ private static Dimension listSize = null;
+ private static JFrame f = null;
+
+ private enum Direction {
+ RIGHT, LEFT, BOTTOM, TOP
+ }
+
+ public static void main(String[] args) throws Exception {
+ DragTestWithHIDPI test = new DragTestWithHIDPI();
+
+ // set the mouse move drag threshold
+ System.setProperty("awt.dnd.drag.threshold", String.valueOf(threshold));
+
+ test.createGUI();
+ test.doTest();
+ System.out.println("Test Passed");
+ test.disposeGUI();
+ }
+
+ public void exportAsDrag(JComponent comp, InputEvent e, int action) {
+ didDrag = true;
+ }
+
+ public DragTestWithHIDPI() {
+ super("foreground");
+ }
+
+ private void createGUI() throws Exception{
+ SwingUtilities.invokeAndWait(() -> {
+ String[] listData =
+ new String[]{"Pacific Ocean", "Atlantic Ocean", "Indian Ocean",
+ "Arctic Ocean"};
+ list = new JList(listData);
+ list.setDragEnabled(true);
+ list.setTransferHandler(new DragTestWithHIDPI());
+
+ f = new JFrame("DragTestWithHIDPI");
+ f.getContentPane().add(list, BorderLayout.CENTER);
+ f.pack();
+ f.toFront();
+ f.setVisible(true);
+
+ listLocation = list.getLocationOnScreen();
+ listSize = list.getSize();
+ });
+ }
+
+ private void disposeGUI () throws Exception {
+ SwingUtilities.invokeAndWait(() -> {
+ f.dispose();
+ });
+ }
+
+ private void doTest() throws Exception {
+
+ robot = new Robot();
+ robot.waitForIdle();
+
+ for (Direction direction : Direction.values()) {
+ //Drag should not start only by moving (threshold - 1) pixels
+ didDrag = false;
+ test(threshold - 1, direction);
+ if (didDrag) {
+ disposeGUI();
+ throw new RuntimeException(
+ "Shouldn't start drag until > " + threshold +
+ " pixels " + " while moving " + direction);
+ }
+
+ // Drag should not start only by moving threshold pixels
+ didDrag = false;
+ test(threshold, direction);
+ if (didDrag) {
+ disposeGUI();
+ throw new RuntimeException(
+ "Shouldn't start drag until > " + threshold +
+ " pixels" + " while moving " + direction);
+ }
+
+ // Drag should start after moving threshold + 1 pixel
+ didDrag = false;
+ test(threshold + 1, direction);
+ if (!didDrag) {
+ disposeGUI();
+ throw new RuntimeException(
+ "Should start drag after > " + threshold + " pixels" +
+ " while moving " + direction);
+ }
+ }
+ }
+
+ private void test(int threshold, Direction direction) {
+ clickMouseOnList(InputEvent.BUTTON1_DOWN_MASK);
+ Point p = MouseInfo.getPointerInfo().getLocation();
+ robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+ robot.delay(DEFAULT_DELAY);
+ glide(p, direction, threshold);
+ robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+ }
+
+ private void glide(Point p, Direction direction, int toAdd) {
+ switch (direction) {
+ case RIGHT:
+ // move towards right
+ glide(p.x, p.y, p.x + toAdd, p.y);
+ break;
+ case LEFT:
+ // move towards left
+ glide(p.x, p.y, p.x - toAdd, p.y);
+ break;
+ case BOTTOM:
+ // move towards bottom
+ glide(p.x, p.y, p.x, p.y + toAdd);
+ break;
+ case TOP:
+ // move towards top
+ glide(p.x, p.y, p.x, p.y - toAdd);
+ break;
+
+ }
+ }
+
+ /*
+ Some utilities functions from JRobot class.
+ */
+ private void moveMouseToList() {
+ int x = listLocation.x + listSize.width/2;
+ int y = listLocation.y + listSize.height/2;
+ robot.mouseMove(x, y);
+ robot.delay(DEFAULT_DELAY);
+ }
+
+ private void clickMouse(int buttons) {
+ robot.mousePress(buttons);
+ robot.mouseRelease(buttons);
+ robot.delay(DEFAULT_DELAY);
+ }
+
+ private void clickMouseOnList(int buttons) {
+ moveMouseToList();
+ clickMouse(buttons);
+ }
+
+ private void glide(int x0, int y0, int x1, int y1) {
+ float dmax = (float)Math.max(Math.abs(x1 - x0), Math.abs(y1 - y0));
+ float dx = (x1 - x0) / dmax;
+ float dy = (y1 - y0) / dmax;
+
+ robot.mouseMove(x0, y0);
+ for (int i=1; i<=dmax; i++) {
+ robot.mouseMove((int)(x0 + dx*i), (int)(y0 + dy*i));
+ }
+ robot.delay(DEFAULT_DELAY);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/image/RescaleOp/RescaleOpExceptionTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -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.
+ */
+
+/*
+ * @test
+ * @bug 8180501
+ * @summary Verify RescaleOp.filter() throws exception for different sized
+ source and destination.
+ * @run main RescaleOpExceptionTest
+ */
+
+import java.awt.image.BufferedImage;
+import static java.awt.image.BufferedImage.TYPE_INT_RGB;
+import java.awt.image.RescaleOp;
+import java.awt.image.WritableRaster;
+
+public class RescaleOpExceptionTest {
+
+ public static void main(String[] args) throws Exception {
+
+ RescaleOp op = new RescaleOp(1.0f, 0.0f, null);
+
+ BufferedImage srcI = new BufferedImage(1, 1, TYPE_INT_RGB);
+ BufferedImage dstI = new BufferedImage(1, 2, TYPE_INT_RGB);
+
+ boolean caughtIAE = false;
+ try {
+ op.filter(srcI, dstI);
+ } catch (IllegalArgumentException e) {
+ caughtIAE = true;
+ }
+ if (!caughtIAE) {
+ throw new RuntimeException("Expected IllegalArgumentException");
+ }
+
+ WritableRaster srcR = srcI.getRaster();
+ WritableRaster dstR = dstI.getRaster();
+
+ caughtIAE = false;
+ try {
+ op.filter(srcR, dstR);
+ } catch (IllegalArgumentException e) {
+ caughtIAE = true;
+ }
+ if (!caughtIAE) {
+ throw new RuntimeException("Expected IllegalArgumentException");
+ }
+ }
+}
--- a/test/jdk/java/lang/ModuleTests/AnnotationsTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/java/lang/ModuleTests/AnnotationsTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -34,13 +34,13 @@
import java.util.List;
import java.util.Set;
-import jdk.internal.module.ClassFileAttributes;
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
import jdk.internal.org.objectweb.asm.Attribute;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.commons.ModuleTargetAttribute;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
@@ -48,6 +48,7 @@
/**
* @test
* @modules java.base/jdk.internal.org.objectweb.asm
+ * java.base/jdk.internal.org.objectweb.asm.commons
* java.base/jdk.internal.module
* java.xml
* @run testng AnnotationsTest
@@ -113,14 +114,11 @@
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
+ ClassWriter.COMPUTE_FRAMES);
- ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, cw) { };
+ ClassVisitor cv = new ClassVisitor(Opcodes.ASM6, cw) { };
ClassReader cr = new ClassReader(in);
-
List<Attribute> attrs = new ArrayList<>();
- attrs.add(new ClassFileAttributes.ModuleAttribute());
- attrs.add(new ClassFileAttributes.ModulePackagesAttribute());
- attrs.add(new ClassFileAttributes.ModuleTargetAttribute());
+ attrs.add(new ModuleTargetAttribute());
cr.accept(cv, attrs.toArray(new Attribute[0]), 0);
AnnotationVisitor annotationVisitor
--- a/test/jdk/java/lang/invoke/DefineClassTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/java/lang/invoke/DefineClassTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -243,7 +243,7 @@
byte[] generateClass(String className) {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
+ ClassWriter.COMPUTE_FRAMES);
- cw.visit(V1_9,
+ cw.visit(V9,
ACC_PUBLIC + ACC_SUPER,
className.replace(".", "/"),
null,
@@ -272,7 +272,7 @@
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
+ ClassWriter.COMPUTE_FRAMES);
- cw.visit(V1_9,
+ cw.visit(V9,
ACC_PUBLIC + ACC_SUPER,
className.replace(".", "/"),
null,
@@ -309,7 +309,7 @@
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
+ ClassWriter.COMPUTE_FRAMES);
- cw.visit(V1_9,
+ cw.visit(V9,
ACC_PUBLIC + ACC_SUPER,
className.replace(".", "/"),
null,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/management/RuntimeMXBean/ProcessIdTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,49 @@
+/*
+ * 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 8044122
+ * @summary check the correctness of process ID returned by RuntimeMXBean.getPid()
+ * @run main ProcessIdTest
+ */
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.lang.ProcessHandle;
+
+public class ProcessIdTest {
+ public static void main(String args[]) {
+ RuntimeMXBean mbean = ManagementFactory.getRuntimeMXBean();
+ long mbeanPid = mbean.getPid();
+ long pid = ProcessHandle.current().pid();
+ long pid1 = Long.parseLong(mbean.getName().split("@")[0]);
+ if(mbeanPid != pid || mbeanPid != pid1) {
+ throw new RuntimeException("Incorrect process ID returned");
+ }
+
+ System.out.println("Test Passed");
+ }
+
+}
+
--- a/test/jdk/java/nio/channels/Channels/Basic.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/java/nio/channels/Channels/Basic.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2008, 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
@@ -167,6 +167,11 @@
readAndCheck(blah);
blah.delete();
+ testNewChannelWriteAfterClose(blah);
+
+ testNewChannelReadAfterClose(blah);
+ blah.delete();
+
writeOut(blah, ITERATIONS);
testNewChannelIn(blah);
test4481572(blah);
@@ -255,6 +260,7 @@
private static void testNewChannelOut(File blah) throws Exception {
ExtendedFileOutputStream fos = new ExtendedFileOutputStream(blah);
WritableByteChannel wbc = Channels.newChannel(fos);
+
for (int i=0; i<ITERATIONS; i++)
wbc.write(ByteBuffer.wrap(message.getBytes(encoding)));
wbc.close();
@@ -287,6 +293,37 @@
fis.close();
}
+ private static void testNewChannelWriteAfterClose(File blah)
+ throws Exception {
+ try (ExtendedFileOutputStream fos =
+ new ExtendedFileOutputStream(blah)) {
+ WritableByteChannel wbc = Channels.newChannel(fos);
+
+ wbc.close();
+ try {
+ wbc.write(ByteBuffer.allocate(0));
+ throw new RuntimeException
+ ("No ClosedChannelException on WritableByteChannel::write");
+ } catch (ClosedChannelException expected) {
+ }
+ }
+ }
+
+ private static void testNewChannelReadAfterClose(File blah)
+ throws Exception {
+ try (ExtendedFileInputStream fis = new ExtendedFileInputStream(blah)) {
+ ReadableByteChannel rbc = Channels.newChannel(fis);
+
+ rbc.close();
+ try {
+ rbc.read(ByteBuffer.allocate(0));
+ throw new RuntimeException
+ ("No ClosedChannelException on ReadableByteChannel::read");
+ } catch (ClosedChannelException expected) {
+ }
+ }
+ }
+
// Causes BufferOverflowException if bug 4481572 is present.
private static void test4481572(File blah) throws Exception {
ExtendedFileInputStream fis = new ExtendedFileInputStream(blah);
--- a/test/jdk/java/nio/file/Files/probeContentType/Basic.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/java/nio/file/Files/probeContentType/Basic.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -114,7 +114,7 @@
failures++;
} else if (!type.equals(expectedTypes[i])) {
System.err.printf("Content type: %s; expected: %s%n",
- type, expectedTypes);
+ type, expectedTypes[i]);
failures++;
}
} finally {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/util/Properties/InitialCapacity.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,40 @@
+/*
+ * 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 java.util.Properties;
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @bug 8189319
+ * @summary Test that Properties(int initialCapacity) throws exceptions (or
+ doesn't) as expected
+ * @run testng InitialCapacity
+ */
+public class InitialCapacity {
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void negativeInitCap() { Properties p = new Properties(-1); }
+
+ @Test
+ public void positiveInitCap() { Properties p = new Properties(10); }
+}
--- a/test/jdk/java/util/ServiceLoader/BadProvidersTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/java/util/ServiceLoader/BadProvidersTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -209,7 +209,7 @@
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
+ ClassWriter.COMPUTE_FRAMES);
- cw.visit(V1_9,
+ cw.visit(V9,
ACC_PUBLIC + ACC_SUPER,
"p/ProviderFactory",
null,
--- a/test/jdk/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectAndSummaryStatisticsTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectAndSummaryStatisticsTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -24,7 +24,7 @@
/*
* @test
* @summary primtive stream collection with summary statistics
- * @bug 8044047
+ * @bug 8044047 8178117
*/
package org.openjdk.tests.java.util.stream;
@@ -91,11 +91,19 @@
instances.add(countTo(1000).stream().mapToInt(i -> i).collect(IntSummaryStatistics::new,
IntSummaryStatistics::accept,
IntSummaryStatistics::combine));
+ instances.add(countTo(1000).stream().mapToInt(i -> i).collect(() -> new IntSummaryStatistics(0, -1, 1001, 2),
+ IntSummaryStatistics::accept,
+ IntSummaryStatistics::combine));
instances.add(countTo(1000).parallelStream().collect(Collectors.summarizingInt(i -> i)));
instances.add(countTo(1000).parallelStream().mapToInt(i -> i).summaryStatistics());
instances.add(countTo(1000).parallelStream().mapToInt(i -> i).collect(IntSummaryStatistics::new,
IntSummaryStatistics::accept,
IntSummaryStatistics::combine));
+ instances.add(countTo(1000).parallelStream().mapToInt(i -> i).collect(() -> new IntSummaryStatistics(0, -1, 1001, 2),
+ IntSummaryStatistics::accept,
+ IntSummaryStatistics::combine));
+ IntSummaryStatistics original = instances.get(0);
+ instances.add(new IntSummaryStatistics(original.getCount(), original.getMin(), original.getMax(), original.getSum()));
for (IntSummaryStatistics stats : instances) {
assertEquals(stats.getCount(), 1000);
@@ -104,6 +112,9 @@
assertEquals(stats.getMax(), 1000);
assertEquals(stats.getMin(), 1);
}
+
+ expectThrows(IllegalArgumentException.class, () -> new IntSummaryStatistics(-1, 0, 0, 0));
+ expectThrows(IllegalArgumentException.class, () -> new IntSummaryStatistics(1, 3, 2, 0));
}
@@ -114,11 +125,19 @@
instances.add(countTo(1000).stream().mapToLong(i -> i).collect(LongSummaryStatistics::new,
LongSummaryStatistics::accept,
LongSummaryStatistics::combine));
+ instances.add(countTo(1000).stream().mapToInt(i -> i).collect(() -> new LongSummaryStatistics(0, -1, 1001, 2),
+ LongSummaryStatistics::accept,
+ LongSummaryStatistics::combine));
instances.add(countTo(1000).parallelStream().collect(Collectors.summarizingLong(i -> i)));
instances.add(countTo(1000).parallelStream().mapToLong(i -> i).summaryStatistics());
instances.add(countTo(1000).parallelStream().mapToLong(i -> i).collect(LongSummaryStatistics::new,
LongSummaryStatistics::accept,
LongSummaryStatistics::combine));
+ instances.add(countTo(1000).parallelStream().mapToInt(i -> i).collect(() -> new LongSummaryStatistics(0, -1, 1001, 2),
+ LongSummaryStatistics::accept,
+ LongSummaryStatistics::combine));
+ LongSummaryStatistics original = instances.get(0);
+ instances.add(new LongSummaryStatistics(original.getCount(), original.getMin(), original.getMax(), original.getSum()));
for (LongSummaryStatistics stats : instances) {
assertEquals(stats.getCount(), 1000);
@@ -127,6 +146,9 @@
assertEquals(stats.getMax(), 1000L);
assertEquals(stats.getMin(), 1L);
}
+
+ expectThrows(IllegalArgumentException.class, () -> new LongSummaryStatistics(-1, 0, 0, 0));
+ expectThrows(IllegalArgumentException.class, () -> new LongSummaryStatistics(1, 3, 2, 0));
}
public void testDoubleStatistics() {
@@ -136,11 +158,19 @@
instances.add(countTo(1000).stream().mapToDouble(i -> i).collect(DoubleSummaryStatistics::new,
DoubleSummaryStatistics::accept,
DoubleSummaryStatistics::combine));
+ instances.add(countTo(1000).stream().mapToInt(i -> i).collect(() -> new DoubleSummaryStatistics(0, -1, 1001, 2),
+ DoubleSummaryStatistics::accept,
+ DoubleSummaryStatistics::combine));
instances.add(countTo(1000).parallelStream().collect(Collectors.summarizingDouble(i -> i)));
instances.add(countTo(1000).parallelStream().mapToDouble(i -> i).summaryStatistics());
instances.add(countTo(1000).parallelStream().mapToDouble(i -> i).collect(DoubleSummaryStatistics::new,
DoubleSummaryStatistics::accept,
DoubleSummaryStatistics::combine));
+ instances.add(countTo(1000).parallelStream().mapToInt(i -> i).collect(() -> new DoubleSummaryStatistics(0, -1, 1001, 2),
+ DoubleSummaryStatistics::accept,
+ DoubleSummaryStatistics::combine));
+ DoubleSummaryStatistics original = instances.get(0);
+ instances.add(new DoubleSummaryStatistics(original.getCount(), original.getMin(), original.getMax(), original.getSum()));
for (DoubleSummaryStatistics stats : instances) {
assertEquals(stats.getCount(), 1000);
@@ -149,5 +179,18 @@
assertEquals(stats.getMax(), 1000.0);
assertEquals(stats.getMin(), 1.0);
}
+
+ expectThrows(IllegalArgumentException.class, () -> new DoubleSummaryStatistics(-1, 0, 0, 0));
+ expectThrows(IllegalArgumentException.class, () -> new DoubleSummaryStatistics(1, 3, 2, 0));
+ double[] values = {1.0, Double.NaN};
+ for (var min : values) {
+ for (var max : values) {
+ for (var sum : values) {
+ if (Double.isNaN(min) && Double.isNaN(max) && Double.isNaN(sum)) continue;
+ if (!Double.isNaN(min) && !Double.isNaN(max) && !Double.isNaN(sum)) continue;
+ expectThrows(IllegalArgumentException.class, () -> new DoubleSummaryStatistics(1, min, max, sum));
+ }
+ }
+ }
}
}
--- a/test/jdk/javax/swing/JComponent/6683775/bug6683775.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/javax/swing/JComponent/6683775/bug6683775.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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,19 +24,23 @@
/*
* @test
* @key headful
- * @bug 6683775 6794764
- * @summary Painting artifacts is seen when panel is made setOpaque(false) for a translucent window
- * @author Alexander Potochkin
- * @modules java.desktop/com.sun.awt
- * java.desktop/sun.awt
- * @run main bug6683775
+ * @bug 6683775 6794764 8186617
+ * @summary Painting artifacts is seen when panel is made setOpaque(false) for a
+ * translucent window
*/
-import com.sun.awt.AWTUtilities;
+import java.awt.Color;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.Window;
+import java.awt.image.BufferedImage;
-import javax.swing.*;
-import java.awt.*;
-import java.awt.image.BufferedImage;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
public class bug6683775 {
static final int LOC = 100,
@@ -44,9 +48,8 @@
public static void main(String[] args) throws Exception {
GraphicsConfiguration gc = getGC();
- if (!AWTUtilities.isTranslucencySupported(
- AWTUtilities.Translucency.PERPIXEL_TRANSLUCENT)
- || gc == null) {
+ if (gc == null || !gc.getDevice().isWindowTranslucencySupported(
+ GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSLUCENT)) {
return;
}
Robot robot = new Robot();
@@ -65,7 +68,7 @@
JPanel p = new JPanel();
p.setOpaque(false);
testFrame.add(p);
- AWTUtilities.setWindowOpaque(testFrame, false);
+ setOpaque(testFrame, false);
testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
testFrame.setBounds(LOC, LOC, SIZE, SIZE);
testFrame.setVisible(true);
@@ -78,17 +81,28 @@
BufferedImage capture =
robot.createScreenCapture(new Rectangle(LOC, LOC, SIZE, SIZE));
+ SwingUtilities.invokeAndWait(testFrame::dispose);
+
int redRGB = Color.RED.getRGB();
if (redRGB != capture.getRGB(SIZE/2, SIZE/2)) {
throw new RuntimeException("Transparent frame is not transparent!");
}
}
+ public static void setOpaque(Window window, boolean opaque) {
+ Color bg = window.getBackground();
+ if (bg == null) {
+ bg = new Color(0, 0, 0, 0);
+ }
+ window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(),
+ opaque ? 255 : 0));
+ }
+
private static GraphicsConfiguration getGC() {
GraphicsConfiguration transparencyCapableGC =
GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration();
- if (!AWTUtilities.isTranslucencyCapable(transparencyCapableGC)) {
+ if (!transparencyCapableGC.isTranslucencyCapable()) {
transparencyCapableGC = null;
GraphicsEnvironment env =
@@ -98,7 +112,7 @@
for (int i = 0; i < devices.length && transparencyCapableGC == null; i++) {
GraphicsConfiguration[] configs = devices[i].getConfigurations();
for (int j = 0; j < configs.length && transparencyCapableGC == null; j++) {
- if (AWTUtilities.isTranslucencyCapable(configs[j])) {
+ if (configs[j].isTranslucencyCapable()) {
transparencyCapableGC = configs[j];
}
}
--- a/test/jdk/javax/swing/JInternalFrame/6726866/bug6726866.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/javax/swing/JInternalFrame/6726866/bug6726866.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -22,15 +22,20 @@
*/
/* @test
- @bug 6726866
- @summary Repainting artifacts when resizing or dragging JInternalFrames in non-opaque toplevel
- @author Alexander Potochkin
+ @bug 6726866 8186617
+ @summary Repainting artifacts when resizing or dragging JInternalFrames in
+ non-opaque toplevel
@run applet/manual=yesno bug6726866.html
*/
-import javax.swing.*;
-import java.awt.*;
-import java.lang.reflect.Method;
+import java.awt.Color;
+import java.awt.Window;
+
+import javax.swing.JApplet;
+import javax.swing.JDesktopPane;
+import javax.swing.JFrame;
+import javax.swing.JInternalFrame;
+import javax.swing.JLabel;
public class bug6726866 extends JApplet {
@@ -54,14 +59,12 @@
frame.toFront();
}
- private void setWindowNonOpaque(Window w) {
- try {
- Class<?> c = Class.forName("com.sun.awt.AWTUtilities");
- Method m = c.getMethod("setWindowOpaque", Window.class, boolean.class);
- m.invoke(null, w, false);
+ public static void setWindowNonOpaque(Window window) {
+ Color bg = window.getBackground();
+ if (bg == null) {
+ bg = new Color(0, 0, 0, 0);
}
- catch (Exception e) {
- e.printStackTrace();
- }
+ window.setBackground(
+ new Color(bg.getRed(), bg.getGreen(), bg.getBlue(), 0));
}
}
--- a/test/jdk/javax/swing/JPopupMenu/7156657/bug7156657.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/javax/swing/JPopupMenu/7156657/bug7156657.java Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, 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
@@ -21,23 +21,33 @@
* questions.
*/
-import com.sun.awt.AWTUtilities;
-import sun.awt.SunToolkit;
-
-import javax.swing.*;
-import java.awt.*;
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.Toolkit;
+import java.awt.Window;
import java.awt.image.BufferedImage;
import java.util.concurrent.Callable;
+import javax.swing.JFrame;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.SwingUtilities;
+
+import sun.awt.SunToolkit;
+
/*
@test
- @key headful
- @bug 7156657
- @summary Version 7 doesn't support translucent popup menus against a translucent window
+ @key headful
+ @bug 7156657 8186617
+ @summary Version 7 doesn't support translucent popup menus against a
+ translucent window
@library ../../regtesthelpers
- @author Pavel Porvatov
- @modules java.desktop/com.sun.awt
- java.desktop/sun.awt
+ @modules java.desktop/sun.awt
*/
public class bug7156657 {
private static JFrame lowerFrame;
@@ -54,8 +64,7 @@
@Override
public Boolean call() throws Exception {
frame = createFrame();
-
- if (!AWTUtilities.isTranslucencyCapable(frame.getGraphicsConfiguration())) {
+ if (!frame.getGraphicsConfiguration().isTranslucencyCapable()) {
System.out.println("Translucency is not supported, the test skipped");
return true;
@@ -71,7 +80,7 @@
popupMenu.add(new TransparentMenuItem("2222"));
popupMenu.add(new TransparentMenuItem("3333"));
- AWTUtilities.setWindowOpaque(frame, false);
+ setOpaque(frame, false);
JPanel pnContent = new JPanel();
pnContent.setBackground(new Color(255, 255, 255, 128));
frame.add(pnContent);
@@ -132,6 +141,14 @@
System.out.println("The test passed");
}
+ public static void setOpaque(Window window, boolean opaque) {
+ Color bg = window.getBackground();
+ if (bg == null) {
+ bg = new Color(0, 0, 0, 0);
+ }
+ window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(),
+ opaque ? 255 : 0));
+ }
private static JFrame createFrame() {
JFrame result = new JFrame();
--- a/test/jdk/javax/swing/JTextPane/bug8025082.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +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.
- *
- * 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
- * @key headful
- * @bug 8025082
- * @summary The behaviour of the highlight will be lost after clicking the set
- * button.
- * @run main bug8025082
- */
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.InputEvent;
-import javax.swing.*;
-
-public class bug8025082 {
-
- private static JButton button;
- private static JFrame frame;
-
- public static void main(String[] args) throws Exception {
- Robot robo = new Robot();
- robo.delay(500);
-
- SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- createUI();
- }
- });
-
- robo.waitForIdle();
- Point point = getButtonLocationOnScreen();
- robo.mouseMove(point.x, point.y);
- robo.mousePress(InputEvent.BUTTON1_MASK);
- robo.mouseRelease(InputEvent.BUTTON1_MASK);
- robo.waitForIdle();
-
- SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- frame.dispose();
- }
- });
- }
-
- private static void createUI() {
- frame = new JFrame();
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- frame.setSize(500, 500);
- JTextPane textpane = new JTextPane();
- textpane.setText("Select Me");
- textpane.selectAll();
-
- JPanel panel = new JPanel(new BorderLayout());
- panel.add(textpane, BorderLayout.CENTER);
- button = new JButton("Press Me");
- panel.add(button, BorderLayout.SOUTH);
-
- button.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- if (!textpane.getCaret().isSelectionVisible()) {
- throw new RuntimeException("Highlight removed after "
- + "button click");
- }
- }
- });
-
- frame.getContentPane().add(panel);
- frame.setLocationRelativeTo(null);
- frame.setVisible(true);
- }
-
- private static Point getButtonLocationOnScreen() throws Exception {
- final Point[] result = new Point[1];
-
- SwingUtilities.invokeAndWait(new Runnable() {
- @Override
- public void run() {
- Point point = button.getLocationOnScreen();
- point.x += button.getWidth() / 2;
- point.y += button.getHeight() / 2;
- result[0] = point;
- }
- });
- return result[0];
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/swing/text/DefaultCaret/HidingSelection/HidingSelectionTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,152 @@
+/*
+ * 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 javax.swing.*;
+import java.awt.*;
+import java.awt.event.InputEvent;
+import java.awt.image.BufferedImage;
+
+/**
+ * @test
+ * @bug 8188081
+ * @summary Text selection does not clear after focus is lost
+ * @run main HidingSelectionTest
+ */
+
+public class HidingSelectionTest {
+
+ private static JTextField field1;
+ private static JTextField field2;
+ private static JFrame frame;
+ private static Rectangle bounds;
+ private static JMenu menu;
+ private static JTextField anotherWindow;
+ private static Point menuLoc;
+ private static JFrame frame2;
+
+ public static void main(String[] args) throws Exception {
+ SwingUtilities.invokeAndWait(() -> {
+ frame = new JFrame();
+ field1 = new JTextField("field1 ");
+ field2 = new JTextField("field2 ");
+ field1.setEditable(false);
+ field2.setEditable(false);
+ frame.getContentPane().setLayout(new FlowLayout());
+ frame.getContentPane().add(field1);
+ frame.getContentPane().add(field2);
+ JMenuBar menuBar = new JMenuBar();
+ menu = new JMenu("menu");
+ menu.add(new JMenuItem("item"));
+ menuBar.add(menu);
+ frame.setJMenuBar(menuBar);
+ frame.pack();
+ frame.setVisible(true);
+ });
+
+ Robot robot = new Robot();
+ robot.waitForIdle();
+ robot.delay(200);
+ SwingUtilities.invokeAndWait(() -> {
+ bounds = field2.getBounds();
+ bounds.setLocation(field2.getLocationOnScreen());
+ });
+ BufferedImage nosel = robot.createScreenCapture(bounds);
+
+ SwingUtilities.invokeAndWait(field2::requestFocus);
+ SwingUtilities.invokeAndWait(field2::selectAll);
+ robot.waitForIdle();
+ robot.delay(200);
+ BufferedImage sel = robot.createScreenCapture(bounds);
+
+ SwingUtilities.invokeAndWait(() -> {
+ menuLoc = menu.getLocationOnScreen();
+ menuLoc.translate(10, 10);
+ });
+ robot.mouseMove(menuLoc.x, menuLoc.y);
+ robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+ robot.delay(50);
+ robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+ robot.waitForIdle();
+ robot.delay(200);
+ if (!biEqual(robot.createScreenCapture(bounds), sel)) {
+ throw new RuntimeException("Test fails: menu hides selection");
+ }
+
+ SwingUtilities.invokeAndWait(
+ MenuSelectionManager.defaultManager()::clearSelectedPath);
+ SwingUtilities.invokeAndWait(field1::requestFocus);
+ robot.waitForIdle();
+ robot.delay(200);
+ if (!biEqual(robot.createScreenCapture(bounds), nosel)) {
+ throw new RuntimeException(
+ "Test fails: focus lost doesn't hide selection");
+ }
+
+ SwingUtilities.invokeAndWait(field2::requestFocus);
+ robot.waitForIdle();
+ SwingUtilities.invokeAndWait(() ->{
+ frame2 = new JFrame();
+ Point loc = frame.getLocationOnScreen();
+ loc.translate(0, frame.getHeight());
+ frame2.setLocation(loc);
+ anotherWindow = new JTextField("textField3");
+ frame2.add(anotherWindow);
+ frame2.pack();
+ frame2.setVisible(true);
+ });
+ robot.waitForIdle();
+ SwingUtilities.invokeAndWait(anotherWindow::requestFocus);
+ robot.waitForIdle();
+ robot.delay(200);
+ if (biEqual(robot.createScreenCapture(bounds), nosel)) {
+ throw new RuntimeException(
+ "Test fails: switch window hides selection");
+ }
+
+ SwingUtilities.invokeAndWait(anotherWindow::selectAll);
+ robot.waitForIdle();
+ robot.delay(200);
+ if (biEqual(robot.createScreenCapture(bounds), sel)) {
+ throw new RuntimeException(
+ "Test fails: selection ownership is lost selection is shown");
+ }
+
+ SwingUtilities.invokeLater(frame2::dispose);
+ SwingUtilities.invokeLater(frame::dispose);
+ }
+
+ static boolean biEqual(BufferedImage i1, BufferedImage i2) {
+ if (i1.getWidth() == i2.getWidth() &&
+ i1.getHeight() == i2.getHeight()) {
+ for (int x = 0; x < i1.getWidth(); x++) {
+ for (int y = 0; y < i1.getHeight(); y++) {
+ if (i1.getRGB(x, y) != i2.getRGB(x, y)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+}
--- a/test/jdk/lib/testlibrary/ModuleTargetHelper.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/lib/testlibrary/ModuleTargetHelper.java Wed Nov 08 16:03:35 2017 -0500
@@ -29,13 +29,9 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-import jdk.internal.module.ClassFileConstants;
-import jdk.internal.module.ClassFileAttributes;
-import jdk.internal.module.ClassFileAttributes.ModuleTargetAttribute;
-import jdk.internal.org.objectweb.asm.Attribute;
-import jdk.internal.org.objectweb.asm.ClassReader;
-import jdk.internal.org.objectweb.asm.ClassVisitor;
-import jdk.internal.org.objectweb.asm.Opcodes;
+
+import jdk.internal.module.ModuleInfo;
+import jdk.internal.module.ModuleInfo.Attributes;
public class ModuleTargetHelper {
private ModuleTargetHelper() {}
@@ -60,29 +56,12 @@
}
public static ModuleTarget read(InputStream in) throws IOException {
- ModuleTargetAttribute[] modTargets = new ModuleTargetAttribute[1];
- ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) {
- @Override
- public void visitAttribute(Attribute attr) {
- if (attr instanceof ModuleTargetAttribute) {
- modTargets[0] = (ModuleTargetAttribute)attr;
- }
- }
- };
-
- // prototype of attributes that should be parsed
- Attribute[] attrs = new Attribute[] {
- new ModuleTargetAttribute()
- };
-
- // parse module-info.class
- ClassReader cr = new ClassReader(in);
- cr.accept(cv, attrs, 0);
- if (modTargets[0] != null) {
- return new ModuleTarget(modTargets[0].targetPlatform());
+ ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
+ if (attrs.target() != null) {
+ return new ModuleTarget(attrs.target().targetPlatform());
+ } else {
+ return null;
}
-
- return null;
}
public static ModuleTarget read(ModuleReference modRef) throws IOException {
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/Agent.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.util.*;
-import java.io.*;
-
-/**
- * Object interface for agent
- */
-
-public interface Agent extends Serializable, Runnable {
-
- /**
- * Run method controls the execution of agent and is called by servers.
- */
- void run();
-
- /**
- * getInfo method is called by home server to collect the information
- * that the agent has collected.
- */
- Vector getInfo();
-
- /**
- * getErrors returns String of errors encountered by Agent
- */
- String getErrors();
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/AgentServer.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.rmi.*;
-
-/**
- * Define the remote interface
- */
-public interface AgentServer extends Remote {
-
- /**
- * Accepts the agent, creates new thread and starts it.
- */
- void accept (Agent agent)
- throws RemoteException; //, InvalidAgentException;
-
- /**
- * Method for home server to accept agent returning home and
- * report gathered information to STDOUT.
- */
- void returnHome (Agent agent)
- throws RemoteException; //, InvalidAgentException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/AgentServerImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.rmi.*;
-import java.rmi.server.*;
-import java.util.*;
-import java.io.*;
-
-
-/**
- * Server accepts agents and could test for validity. Acts as both a home
- * server and a regular server. The agent will jump to this host and
- * the server will create a thread and allow the agent to run inside of
- * it. The agent just queries the system.properties for machine info.
- */
-public class AgentServerImpl
- extends UnicastRemoteObject
- implements AgentServer
-{
-
- /**
- * Constructor
- *
- * @exception RemoteException If a network problem occurs.
- */
- public AgentServerImpl() throws RemoteException {
- // Could use to set up state of server
- }
-
- /**
- * Instantiates Agent Server Implementation and sets security
- * manager
- */
- public static void main(String args[]) {
-
- // Set the security Manager
- //System.setSecurityManager(new MyRMISecurityManager());
-
- try {
- AgentServerImpl server = new AgentServerImpl();
- Naming.rebind("/AgentServer", server);
- System.out.println("Ready to receive agents.");
- System.err.println("DTI_DoneInitializing");
- } catch (Exception e) {
- System.err.println("DTI_Error");
- System.err.println("Did not establish server");
- e.printStackTrace();
- }
- }
-
- /**
- * Remote method called by Agent to have server accept it.
- */
- public synchronized void accept(Agent agent)
- throws RemoteException //, InvalidAgentException
- {
- Thread t;
-
- // Could check validity of agent here
- // checkValid(agent);
-
- // Create new thread to run agent
- t = new Thread(agent);
-
- System.out.println("Agent Accepted: " + t);
-
- // Start agent
- t.start();
- }
-
- /**
- * Remote method called by Agent to return to final server.
- */
- public synchronized void returnHome(Agent agent)
- throws RemoteException //, InvalidAgentException
- {
- Enumeration info = null;
- boolean bErrorsOccurred = false;
-
- // Could check validity of agent here
- // checkValid(agent);
-
- // Grab and print collected info from agent
- info = agent.getInfo().elements();
- System.out.println("Collected information:");
- while (info.hasMoreElements()) {
- System.out.println(" " + (String) info.nextElement());
- }
-
- System.out.println("\nErrors:");
- System.out.println(agent.getErrors());
- if(!(agent.getErrors()).equals(""))
- bErrorsOccurred = true;
-
- if(bErrorsOccurred)
- {
- System.err.println("DTI_Error");
- System.err.println("DTI_DoneExecuting");
- }
- else
- {
- System.err.println("DTI_DoneExecuting");
- }
-
- }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/Apple.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-public interface Apple extends java.rmi.Remote {
-
- public void notify(AppleEvent[] e) throws java.rmi.RemoteException;
-
- public Orange newOrange(String name) throws java.rmi.RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/AppleEvent.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.util.Date;
-
-/**
- * The AppleEvent class is simply an object to be passed back to a
- * remote objct exported by an applet to verify proper object
- * serialization.
- */
-public class AppleEvent implements java.io.Serializable {
-
- public static final int BUY = 0;
- public static final int EAT = 1;
- public static final int THROW = 2;
-
- private int what;
-
- private java.util.Date when;
-
- public AppleEvent(int what)
- {
- this.what = what;
- this.when = new Date();
- }
-
- public String toString()
- {
- String desc = "[";
- switch (what) {
- case BUY:
- desc += "BUY";
- break;
- case EAT:
- desc += "EAT";
- break;
- case THROW:
- desc += "THROW";
- break;
- }
- desc += " @ " + when + "]";
- return desc;
- }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/AppleImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.logging.Logger;
-import java.util.logging.Level;
-
-/**
- * The AppleImpl class implements the behavior of the remote "apple"
- * objects exported by the application.
- */
-public class AppleImpl
- extends UnicastRemoteObject
- implements Apple
-{
-
- private static Logger logger = Logger.getLogger("reliability.apple");
- private String name;
-
- public AppleImpl(String name) throws RemoteException {
- this.name = name;
- }
-
- /**
- * Receive an array of AppleEvent objects.
- */
- public void notify(AppleEvent[] events) {
- try {
- String threadName = Thread.currentThread().getName();
- logger.log(Level.FINEST,
- threadName + ": " + toString() + ".notify: BEGIN");
-
- for (int i = 0; i < events.length; ++ i) {
- logger.log(Level.FINEST,
- threadName + ": " + toString() +
- ".notify(): events[" + i + "] = " +
- events[i].toString());
- }
-
- logger.log(Level.FINEST,
- threadName + ": " + toString() + ".notify(): END");
- } catch (RuntimeException e) {
- logger.log(Level.SEVERE, toString() + ".notify():", e);
- throw e;
- }
- }
-
- /**
- * Return a newly created and exported orange implementation.
- */
- public Orange newOrange(String name) throws RemoteException {
- try {
- String threadName = Thread.currentThread().getName();
- logger.log(Level.FINEST,
- threadName + ": " + toString() +
- ".newOrange(" + name + "): BEGIN");
-
- Orange orange = new OrangeImpl(name);
-
- logger.log(Level.FINEST,
- threadName + ": " + toString() +
- ".newOrange(" + name + "): END");
-
- return orange;
- } catch (RuntimeException e) {
- logger.log(Level.SEVERE, toString() + ".newOrange():", e);
- throw e;
- }
- }
-
- public String toString() {
- return name;
- }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/AppleUser.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-public interface AppleUser extends Remote {
- public void startTest() throws RemoteException;
- public void reportException(Exception status) throws RemoteException;
- public void useApple(Apple apple) throws RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/AppleUserImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,317 +0,0 @@
-/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.rmi.RemoteException;
-import java.rmi.Naming;
-import java.rmi.server.UnicastRemoteObject;
-import java.rmi.registry.LocateRegistry;
-import java.rmi.registry.Registry;
-import java.util.Random;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.logging.Logger;
-import java.util.logging.Level;
-
-/**
- * The AppleUserImpl class implements the behavior of the remote
- * "apple user" objects exported by the server. The application server
- * passes each of its remote "apple" objects to an apple user, and an
- * AppleUserThread is created for each apple.
- */
-public class AppleUserImpl
- extends UnicastRemoteObject
- implements AppleUser
-{
- private static Logger logger = Logger.getLogger("reliability.appleuser");
- private static int threadNum = 0;
- private static long testDuration = 0;
- private static int maxLevel = 7;
- private static Thread server = null;
- private static Exception status = null;
- private static Random random = new Random();
-
- public AppleUserImpl() throws RemoteException {
- }
-
- /**
- * Allows the other server process to indicate that it is ready
- * to start "juicing".
- */
- public synchronized void startTest() throws RemoteException {
- this.notifyAll();
- }
-
- /**
- * Allows the other server process to report an exception to this
- * process and thereby terminate the test.
- */
- public void reportException(Exception status) throws RemoteException {
- synchronized (AppleUserImpl.class) {
- this.status = status;
- AppleUserImpl.class.notifyAll();
- }
- }
-
- /**
- * "Use" supplied apple object. Create an AppleUserThread to
- * stress it out.
- */
- public synchronized void useApple(Apple apple) throws RemoteException {
- String threadName = Thread.currentThread().getName();
- logger.log(Level.FINEST,
- threadName + ": AppleUserImpl.useApple(): BEGIN");
-
- AppleUserThread t =
- new AppleUserThread("AppleUserThread-" + (++threadNum), apple);
- t.start();
-
- logger.log(Level.FINEST,
- threadName + ": AppleUserImpl.useApple(): END");
- }
-
- /**
- * The AppleUserThread class repeatedly invokes calls on its associated
- * Apple object to stress the RMI system.
- */
- class AppleUserThread extends Thread {
-
- Apple apple;
-
- public AppleUserThread(String name, Apple apple) {
- super(name);
- this.apple = apple;
- }
-
- public void run() {
- int orangeNum = 0;
- long stopTime = System.currentTimeMillis() + testDuration;
- Logger logger = Logger.getLogger("reliability.appleuserthread");
-
- try {
- do { // loop until stopTime is reached
-
- /*
- * Notify apple with some apple events. This tests
- * serialization of arrays.
- */
- int numEvents = Math.abs(random.nextInt() % 5);
- AppleEvent[] events = new AppleEvent[numEvents];
- for (int i = 0; i < events.length; ++ i) {
- events[i] = new AppleEvent(orangeNum % 3);
- }
- apple.notify(events);
-
- /*
- * Request a new orange object be created in
- * the application server.
- */
- Orange orange = apple.newOrange(
- "Orange(" + getName() + ")-" + (++orangeNum));
-
- /*
- * Create a large message of random ints to pass to orange.
- */
- int msgLength = 1000 + Math.abs(random.nextInt() % 3000);
- int[] message = new int[msgLength];
- for (int i = 0; i < message.length; ++ i) {
- message[i] = random.nextInt();
- }
-
- /*
- * Invoke recursive call on the orange. Base case
- * of recursion inverts messgage.
- */
- OrangeEchoImpl echo = new OrangeEchoImpl(
- "OrangeEcho(" + getName() + ")-" + orangeNum);
- int[] response = orange.recurse(echo, message,
- 2 + Math.abs(random.nextInt() % (maxLevel + 1)));
-
- /*
- * Verify message was properly inverted and not corrupted
- * through all the recursive method invocations.
- */
- if (response.length != message.length) {
- throw new RuntimeException(
- "ERROR: CORRUPTED RESPONSE: " +
- "wrong length of returned array " + "(should be " +
- message.length + ", is " + response.length + ")");
- }
- for (int i = 0; i < message.length; ++ i) {
- if (~message[i] != response[i]) {
- throw new RuntimeException(
- "ERROR: CORRUPTED RESPONSE: " +
- "at element " + i + "/" + message.length +
- " of returned array (should be " +
- Integer.toHexString(~message[i]) + ", is " +
- Integer.toHexString(response[i]) + ")");
- }
- }
-
- try {
- Thread.sleep(Math.abs(random.nextInt() % 10) * 1000);
- } catch (InterruptedException e) {
- }
-
- } while (System.currentTimeMillis() < stopTime);
-
- } catch (Exception e) {
- status = e;
- }
- synchronized (AppleUserImpl.class) {
- AppleUserImpl.class.notifyAll();
- }
- }
- }
-
- private static void usage() {
- System.out.println("Usage: AppleUserImpl [-hours <hours> | " +
- "-seconds <seconds>]");
- System.out.println(" [-maxLevel <maxLevel>]");
- System.out.println(" hours The number of hours to run the juicer.");
- System.out.println(" The default is 0 hours.");
- System.out.println(" seconds The number of seconds to run the juicer.");
- System.out.println(" The default is 0 seconds.");
- System.out.println(" maxLevel The maximum number of levels to ");
- System.out.println(" recurse on each call.");
- System.out.println(" The default is 7 levels.");
- //TestLibrary.bomb("Bad argument");
- }
-
- /**
- * Entry point for the "juicer" server process. Create and export
- * an apple user implementation in an rmiregistry running on localhost.
- */
- public static void main(String[] args)
-
- {
- //TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager");
- long startTime = 0;
- String durationString = null;
-
- // parse command line args
- try {
- for (int i = 0; i < args.length ; i++ ) {
- String arg = args[i];
- if (arg.equals("-hours")) {
- if (durationString != null) {
- usage();
- }
- i++;
- int hours = Integer.parseInt(args[i]);
- durationString = hours + " hours";
- testDuration = hours * 60 * 60 * 1000;
- } else if (arg.equals("-seconds")) {
- if (durationString != null) {
- usage();
- }
- i++;
- long seconds = Long.parseLong(args[i]);
- durationString = seconds + " seconds";
- testDuration = seconds * 1000;
- } else if (arg.equals("-maxLevel")) {
- i++;
- maxLevel = Integer.parseInt(args[i]);
- } else {
- usage();
- }
- }
- if (durationString == null) {
- durationString = testDuration + " milliseconds";
- }
- } catch (Throwable t) {
- usage();
- }
-
- AppleUserImpl user = null;
- try {
- user = new AppleUserImpl();
- } catch (RemoteException e) {
- //TestLibrary.bomb("Failed to create AppleUser", e);
- }
-
- synchronized (user) {
- int port = -1;
- // create new registry and bind new AppleUserImpl in registry
- try {
- Registry registry = TestLibrary.createRegistryOnEphemeralPort();
- port = TestLibrary.getRegistryPort(registry);
- Naming.rebind("rmi://localhost:" + port + "/AppleUser",user);
- } catch (RemoteException e) {
- //TestLibrary.bomb("Failed to bind AppleUser", e);
- } catch (java.net.MalformedURLException e) {
- //TestLibrary.bomb("Failed to bind AppleUser", e);
- }
-
- // start the other server if available
- try {
- Class app = Class.forName("ApplicationServer");
- java.lang.reflect.Constructor appConstructor =
- app.getDeclaredConstructor(new Class[] {Integer.TYPE});
- server = new Thread((Runnable) appConstructor.newInstance(port));
- } catch (ClassNotFoundException e) {
- // assume the other server is running in a separate process
- logger.log(Level.INFO, "Application server must be " +
- "started in separate process");
- } catch (Exception ie) {
- //TestLibrary.bomb("Could not instantiate server", ie);
- }
-
- // wait for other server to call startTest method
- try {
- logger.log(Level.INFO, "Waiting for application server " +
- "process to start");
- user.wait();
- } catch (InterruptedException ie) {
- //TestLibrary.bomb("AppleUserImpl interrupted", ie);
- }
- }
-
- startTime = System.currentTimeMillis();
- logger.log(Level.INFO, "Test starting");
-
- // wait for exception to be reported or first thread to complete
- try {
- logger.log(Level.INFO, "Waiting " + durationString + " for " +
- "test to complete or exception to be thrown");
-
- synchronized (AppleUserImpl.class) {
- AppleUserImpl.class.wait();
- }
-
- if (status != null) {
- //TestLibrary.bomb("juicer server reported an exception", status);
- } else {
- logger.log(Level.INFO, "TEST PASSED");
- }
- } catch (Exception e) {
- logger.log(Level.INFO, "TEST FAILED");
- //TestLibrary.bomb("unexpected exception", e);
- } finally {
- logger.log(Level.INFO, "Test finished");
- long actualDuration = System.currentTimeMillis() - startTime;
- logger.log(Level.INFO, "Test duration was " +
- (actualDuration/1000) + " seconds " +
- "(" + (actualDuration/3600000) + " hours)");
- }
- }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/Callback.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.rmi.*;
-import java.rmi.registry.*;
-import java.rmi.server.*;
-
-
-
-public interface Callback extends Remote
-{
- void callback() throws RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/ComputeServer.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.rmi.*;
-
-/**
- * Remote interface for the Compute Server
- */
-public interface ComputeServer extends Remote {
-
- /**
- * Called by the task and passes itself as an object
- */
- Object compute(Task task) throws RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/ComputeServerImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.rmi.*;
-import java.rmi.server.*;
-import java.io.*;
-
-/**
- * Class accepts a task and runs it in its own space.
- */
-public class ComputeServerImpl
- extends UnicastRemoteObject
- implements ComputeServer
-{
- public ComputeServerImpl() throws RemoteException
- {
-
- }
-
- /**
- * Accepts task and runs it
- */
- public Object compute(Task task) {
- return task.run();
- }
-
- /**
- * Binds compute server and waits for tasks
- */
- public static void main(String args[]) throws Exception
- {
- // use the default, restrictive security manager
- System.setSecurityManager(new RMISecurityManager());
-
- Naming.rebind("/ComputeServer", new ComputeServerImpl());
- System.out.println("Ready to receive tasks.");
-
- System.err.println("DTI_DoneInitializing");
- }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/CountInterface.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-// RMI Activation Functional Test
-
-import java.rmi.*;
-import java.rmi.activation.*;
-
-// CountInterface
-
-public interface CountInterface extends Remote {
-
- public void ping() throws RemoteException;
-
- public int incrementCount() throws RemoteException;
-
- public int decrementCount() throws RemoteException;
-
- public int getCount() throws RemoteException;
-
- public int getClassCount() throws RemoteException;
-
- public String getProperty(String s) throws RemoteException;
-
- public void exit() throws RemoteException;
-
- // Methods specific to dealing with activatable objects
-
- public boolean unexportObject(boolean b) throws RemoteException;
-
- public ActivationID getActivationID() throws RemoteException;
-
- public ActivationGroupID getCurrentGroupID() throws RemoteException;
-
- public void inactive()
- throws RemoteException, UnknownObjectException, ActivationException;
-
- public void register()
- throws RemoteException, UnknownObjectException, ActivationException;
-
- public void unregister()
- throws RemoteException, UnknownObjectException, ActivationException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/CountServerImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-// RMI Activation Functional Test
-
-import java.rmi.*;
-import java.rmi.server.*;
-import java.rmi.activation.*;
-import java.util.*;
-
-// CountServerImpl
-
-public class CountServerImpl
- extends Activatable
- implements CountInterface {
-
- private static final String PROG_NAME = "CountServerImpl";
- private static final String SERVER_OBJECT = "CountServer";
- private static final String CLASS_NAME = "activation.CountServerImpl";
-
- private static final String POLICY_FILE = "policy_file";
-
- private static final String USER_DIR =
- System.getProperty("user.dir").replace('\\', '/');
-
- private static final String CODE_LOCATION = "file:"+USER_DIR+"/";
-
- private static final MarshalledObject DATA = null;
- private static ActivationDesc ACTIVATION_DESC = null;
-
- // Class variable
- private static int classCount = 0;
-
- // Instance variable
- private int instanceCount;
- private TestInterface ref;
-
- public CountServerImpl(ActivationID id, MarshalledObject data)
- throws RemoteException {
- super(id, 0);
- instanceCount = 0;
- classCount++;
- if (data != null) {
- try {
- ref = (TestInterface)data.get();
- ref.ping(SERVER_OBJECT);
- }
- catch (Exception e) {
- System.err.println("Exception: " + e);
- }
- }
- }
-
- public void ping() throws RemoteException {}
-
- public int getCount() throws RemoteException {
- return instanceCount;
- }
-
- public int incrementCount() throws RemoteException {
- return ++instanceCount;
- }
-
- public int decrementCount() throws RemoteException {
- return --instanceCount;
- }
-
- public int getClassCount() throws RemoteException {
- return classCount;
- }
-
- public String getProperty(String s) throws RemoteException {
- return System.getProperty(s);
- }
-
- public void exit() throws RemoteException {
- System.exit(0);
- }
-
- public boolean unexportObject(boolean force) {
- boolean succeeded = false;
- try {
- succeeded = Activatable.unexportObject(this, force);
- }
- catch (Exception e) {
- System.err.println("Exception: " + e);
- e.printStackTrace();
- }
- return succeeded;
- }
-
- public ActivationID getActivationID() throws RemoteException {
- return super.getID();
- }
-
- public void inactive()
- throws RemoteException, ActivationException, UnknownObjectException {
-
- //ShutDown s = new ShutDown(super.getID(),this,ShutDown.NORMAL_SHUTDOWN);
- }
-
- public void unregister()
- throws RemoteException, ActivationException, UnknownObjectException {
- unregister(super.getID());
- }
-
- public void register()
- throws RemoteException, ActivationException, UnknownObjectException {
- register(ACTIVATION_DESC);
- }
-
- public ActivationGroupID getCurrentGroupID() throws RemoteException {
- return ActivationGroup.currentGroupID();
- }
-
- private static void setup() {
-
- try {
-
- CountInterface rsi; // Remote server interface
-
- System.setSecurityManager(new RMISecurityManager());
-
- rsi = (CountInterface)Activatable.register(ACTIVATION_DESC);
- System.out.println("Got stub for "+SERVER_OBJECT+" implementation");
-
- Naming.rebind(SERVER_OBJECT, rsi);
- System.out.println("Exported "+SERVER_OBJECT+" implementation");
-
- } catch (Exception e) {
- System.err.println("Exception: " + e);
- e.printStackTrace();
- }
- }
-
- public static void main(String[] args) {
-
- try {
- Properties props = new Properties();
- props.setProperty("java.security.policy", POLICY_FILE);
-
- ActivationGroupDesc agd = new ActivationGroupDesc(props, null);
-
- ActivationGroupID agid = ActivationGroup.getSystem().registerGroup(agd);
-
- ACTIVATION_DESC = new ActivationDesc(agid,
- CLASS_NAME, CODE_LOCATION, DATA, false);
- }
- catch (Exception e) {
- System.err.println("Exception: " + e);
- e.printStackTrace();
- }
-
- setup();
- }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/DayTimeInterface.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-// RMI Activation Functional Test
-
-import java.rmi.*;
-import java.rmi.activation.*;
-
-// DayTimeInterface
-
-public interface DayTimeInterface extends Remote {
-
- public void ping() throws RemoteException;
-
- public java.util.Date getDayTime() throws java.rmi.RemoteException;
-
- public void exit() throws RemoteException;
-
- public ActivationID getActivationID() throws RemoteException;
-
- public ActivationGroupID getCurrentGroupID() throws RemoteException;
-
- public void inactive()
- throws RemoteException, UnknownObjectException, ActivationException;
-
- public void register()
- throws RemoteException, UnknownObjectException, ActivationException;
-
- public void unregister()
- throws RemoteException, UnknownObjectException, ActivationException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/DayTimeServerImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-// RMI Activation Functional Test
-
-import java.rmi.*;
-import java.rmi.activation.*;
-import java.util.*;
-
-// DayTimeServerImpl
-
-public class DayTimeServerImpl
- extends Activatable
- implements DayTimeInterface {
-
- private static final String PROG_NAME = "DayTimeServerImpl";
- private static final String SERVER_OBJECT = "DayTimeServer";
- private static final String CLASS_NAME = "activation.DayTimeServerImpl";
-
- private static final String POLICY_FILE = "policy_file";
-
- private static final String USER_DIR =
- System.getProperty("user.dir").replace('\\', '/');
-
- private static final String CODE_LOCATION = "file:"+USER_DIR+"/";
-
- private static final MarshalledObject DATA = null;
- private static ActivationDesc ACTIVATION_DESC = null;
-
- private TestInterface ref;
-
- public void ping() throws RemoteException {}
-
- public ActivationID getActivationID() throws RemoteException {
- return super.getID();
- }
-
- public DayTimeServerImpl(ActivationID id, MarshalledObject data)
- throws RemoteException {
- super(id, 0);
- if (data != null) {
- try {
- ref = (TestInterface)data.get();
- ref.ping(SERVER_OBJECT);
- }
- catch (Exception e) {
- System.err.println("Exception: " + e);
- }
- }
- }
-
- public Date getDayTime() throws RemoteException {
- return new Date();
- }
-
- public void exit() throws RemoteException {
- System.exit(0);
- }
-
- public void inactive()
- throws RemoteException, ActivationException, UnknownObjectException {
-
- //ShutDown s = new ShutDown(super.getID(),this,ShutDown.NORMAL_SHUTDOWN);
- }
-
- public void unregister()
- throws RemoteException, ActivationException, UnknownObjectException {
- unregister(super.getID());
- }
-
- public void register()
- throws RemoteException, ActivationException, UnknownObjectException {
- register(ACTIVATION_DESC);
- }
-
- public ActivationGroupID getCurrentGroupID() throws RemoteException {
- return ActivationGroup.currentGroupID();
- }
-
- private static void setup() {
-
- try {
-
- DayTimeInterface rsi; // Remote server interface
-
- System.setSecurityManager(new RMISecurityManager());
-
- rsi = (DayTimeInterface)Activatable.register(ACTIVATION_DESC);
- System.out.println("Got stub for "+SERVER_OBJECT+" implementation");
-
- Naming.rebind(SERVER_OBJECT, rsi);
- System.out.println("Exported "+SERVER_OBJECT+" implementation");
-
- } catch (Exception e) {
- System.err.println("Exception: " + e);
- e.printStackTrace();
- }
- }
-
- public static void main(String[] args) {
-
- try {
- Properties props = new Properties();
- props.setProperty("java.security.policy", POLICY_FILE);
-
- ActivationGroupDesc agd = new ActivationGroupDesc(props, null);
-
- ActivationGroupID agid = ActivationGroup.getSystem().registerGroup(agd);
-
- ACTIVATION_DESC = new ActivationDesc(agid,
- CLASS_NAME, CODE_LOCATION, DATA, false);
- }
- catch (Exception e) {
- System.err.println("Exception: " + e);
- e.printStackTrace();
- }
-
- setup();
- }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/G1.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-public interface G1 extends Remote {
- void m() throws RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/G1Impl.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-public class G1Impl implements G1 {
- public void m() { }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/MyObject.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.rmi.*;
-
-public interface MyObject extends Remote {
- public void method1(MyObject obj) throws RemoteException;
-
- public void method2(MyObject[] objs) throws RemoteException;
-
- public void method3() throws RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/MyObjectImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.rmi.*;
-import java.rmi.server.*;
-
-public class MyObjectImpl extends UnicastRemoteObject implements MyObject {
- private int clientNum = -1;
- private byte[] data = null;
- //private MyObjectFactory mof = null;
- private boolean AliveMyObjectsCounterWasIncremented = false;
-
- public MyObjectImpl() throws RemoteException {
- super();
- }
-
- public MyObjectImpl(int c, int size) //MyObjectFactory mof, int c, int size)
- throws RemoteException {
- super();
- //this.mof = mof;
- this.clientNum = c;
- this.data = new byte[size];
- //mof.incAliveMyObjects(1);
- AliveMyObjectsCounterWasIncremented = true;
- }
-
- public void method1(MyObject obj) throws RemoteException {
- }
-
- public void method2(MyObject[] objs) throws RemoteException {
- }
-
- public void method3() throws RemoteException {
- }
-
- protected void finalize() throws Throwable {
- if(AliveMyObjectsCounterWasIncremented)
- ; //mof.decAliveMyObjects(1);
- super.finalize();
- }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/NotActivatableInterface.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-// RMI Activation Functional Test
-
-// NotActivatableInterface
-
-public interface NotActivatableInterface extends java.rmi.Remote {
-
- public void ping() throws java.rmi.RemoteException;
-
- public void exit() throws java.rmi.RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/NotActivatableServerImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-// RMI Activation Functional Test
-
-import java.rmi.*;
-import java.rmi.activation.*;
-import java.rmi.server.*;
-import java.util.*;
-
-// NotActivatableServerImpl
-
-public class NotActivatableServerImpl
- extends UnicastRemoteObject
- implements NotActivatableInterface {
-
- private static final String PROG_NAME = "NotActivatableServerImpl";
- private static final String SERVER_OBJECT = "NotActivatableServer";
- private static final String CLASS_NAME = "activation.NotActivatableServerImpl";
-
- private static final String POLICY_FILE = "policy_file";
-
- private static final String USER_DIR =
- System.getProperty("user.dir").replace('\\', '/');
-
- private static final String CODE_LOCATION = "file:"+USER_DIR+"/";
-
- private static final MarshalledObject DATA = null;
- private static ActivationDesc ACTIVATION_DESC = null;
-
- public NotActivatableServerImpl() throws RemoteException {}
-
- public void ping() throws RemoteException {}
-
- public void exit() throws RemoteException {
- System.exit(0);
- }
-
- private static void setup() {
-
- try {
-
- NotActivatableInterface rsi; // Remote server interface
-
- System.setSecurityManager(new RMISecurityManager());
-
- rsi = (NotActivatableInterface)Activatable.register(ACTIVATION_DESC);
- System.out.println("Got stub for "+SERVER_OBJECT+" implementation");
-
- Naming.rebind(SERVER_OBJECT, rsi);
- System.out.println("Exported "+SERVER_OBJECT+" implementation");
-
- } catch (Exception e) {
- System.err.println("Exception: " + e);
- e.printStackTrace();
- }
- }
-
- public static void main(String[] args) {
-
- try {
- Properties props = new Properties();
- props.setProperty("java.security.policy", POLICY_FILE);
-
- ActivationGroupDesc agd = new ActivationGroupDesc(props, null);
-
- ActivationGroupID agid = ActivationGroup.getSystem().registerGroup(agd);
-
- ACTIVATION_DESC = new ActivationDesc(agid,
- CLASS_NAME, CODE_LOCATION, DATA, false);
- }
- catch (Exception e) {
- System.err.println("Exception: " + e);
- e.printStackTrace();
- }
-
- setup();
- }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/Orange.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-public interface Orange extends java.rmi.Remote {
-
- public int[] recurse(OrangeEcho echo, int[] message, int level)
- throws java.rmi.RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/OrangeEcho.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-public interface OrangeEcho extends java.rmi.Remote {
-
- public int[] recurse(Orange orange, int[] message, int level)
- throws java.rmi.RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/OrangeEchoImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.logging.Logger;
-import java.util.logging.Level;
-
-/**
- * The OrangeEchoImpl class implements the behavior of the remote "orange
- * echo" objects exported by the server. The purpose of these objects
- * is simply to recursively call back to their caller.
- */
-public class OrangeEchoImpl
- extends UnicastRemoteObject
- implements OrangeEcho
-{
-
- private static Logger logger = Logger.getLogger("reliability.orangeecho");
- String name;
-
- public OrangeEchoImpl(String name) throws RemoteException {
- this.name = name;
- }
-
- /**
- * Call back on supplied "orange" object (presumably the caller)
- * with the same message data and a decremented recursion level.
- */
- public int[] recurse(Orange orange, int[] message, int level)
- throws RemoteException
- {
- String threadName = Thread.currentThread().getName();
-
- logger.log(Level.FINEST,
- threadName + ": " + toString() +
- ".recurse(message[" + message.length + "], " +
- level + "): BEGIN");
-
- int[] response = orange.recurse(this, message, level - 1);
-
- logger.log(Level.FINEST,
- threadName + ": " + toString() +
- ".recurse(message[" + message.length + "], " +
- level + "): END");
-
- return response;
- }
-
- public String toString() {
- return name;
- }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/OrangeImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.logging.Logger;
-import java.util.logging.Level;
-
-/**
- * The OrangeImpl class implements the behavior of the remote "orange"
- * objects exported by the appplication.
- */
-public class OrangeImpl
- extends UnicastRemoteObject
- implements Orange
-{
-
- private static Logger logger = Logger.getLogger("reliability.orange");
- private String name;
-
- public OrangeImpl(String name) throws RemoteException {
- this.name = name;
- }
-
- /**
- * Return inverted message data, call through supplied OrangeEcho
- * object if not at recursion level zero.
- */
- public int[] recurse(OrangeEcho echo, int[] message, int level)
- throws RemoteException
- {
- try {
- String threadName = Thread.currentThread().getName();
- logger.log(Level.FINEST,
- threadName + ": " + toString() +
- ".recurse(message[" + message.length + "], " +
- level + "): BEGIN");
-
- int[] response;
- if (level > 0)
- response = echo.recurse(this, message, level);
- else {
- for (int i = 0; i < message.length; ++ i)
- message[i] = ~message[i];
- response = message;
- }
-
- logger.log(Level.FINEST,
- threadName + ": " + toString() +
- ".recurse(message[" + message.length + "], " +
- level + "): END");
-
- return response;
- } catch (RuntimeException e) {
- logger.log(Level.SEVERE, toString() + ".recurse():", e);
- throw e;
- }
- }
-
- public String toString() {
- return name;
- }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/Server.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.rmi.*;
-import java.rmi.registry.*;
-import java.rmi.server.*;
-
-
-
-public interface Server extends Remote
-{
- public String sayHello(Callback c) throws RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/ServerImpl.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.io.*;
-import java.rmi.*;
-import java.rmi.server.UnicastRemoteObject;
-
-public class ServerImpl
- extends UnicastRemoteObject
- implements Server
-{
- private String name;
- Callback cLocal;
-
- public ServerImpl(String s) throws java.rmi.RemoteException {
- super();
- name = s;
- }
-
- public String sayHello(Callback c) throws RemoteException {
- System.out.println("Calling Callback method from the ServerImpl");
- cLocal = c;
- new Thread(new Runnable() {
- public void run() {
- System.out.println(
- "+ running a new thread in sayHello method!");
- try {
- cLocal.callback();
- } catch(RemoteException e) {
- System.out.println(
- "ServerImpl.main: exception while calling callback " +
- "method:");
- e.printStackTrace();
- }
- }
- }).start();
- return "Hello Callback!";
- }
-
- public static void main(String args[]) {
- // Create and install the security manager
- System.setSecurityManager(new RMISecurityManager());
-
- ServerImpl obj = null;
-
- try {
- obj = new ServerImpl("ServerImpl");
- Naming.rebind("/ServerImpl", obj);
- System.out.println("ServerImpl created and bound in the registry" +
- " to the name ServerImpl");
- System.err.println("DTI_DoneInitializing");
- } catch (Exception e) {
- System.out.println("ServerImpl.main: an exception occurred:");
- e.printStackTrace();
- System.err.println("DTI_Error");
- }
-
- }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/Task.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-/**
- * Interface Task that must be serializable so that the task can be
- * passed to the compute server.
- */
-public interface Task extends java.io.Serializable {
-
- /**
- * Called by compute server and returns an object.
- */
- Object run();
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/TestInterface.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-// RMI Activation Functional Test
-
-import java.rmi.*;
-import java.rmi.activation.*;
-
-// TestInterface
-
-public interface TestInterface extends Remote {
-
- public void ping(String s) throws RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/batch.sh Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
-# 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: batch.sh classpath classes...
-#
-
-if [ $# -lt 2 ]
-then
- echo "Usage: `basename $0` classpath classes..."
- exit 1
-fi
-
-if [ "${TESTJAVA}" = "" ]
-then
- echo "TESTJAVA not set. Test cannot execute. Failed."
- exit 1
-fi
-
-refv11dir=./ref-v1.1-output
-refvcompatdir=./ref-vcompat-output
-refv12dir=./ref-v1.2-output
-
-newv11dir=./new-v1.1-output
-newvcompatdir=./new-vcompat-output
-newv12dir=./new-v1.2-output
-
-v11diffs=./diffs-v1.1
-vcompatdiffs=./diffs-vcompat
-v12diffs=./diffs-v1.2
-
-difflines=./diff-lines
-
-rm -rf $refv11dir $refvcompatdir $refv12dir
-rm -rf $newv11dir $newvcompatdir $newv12dir
-rm -f $v11diffs $vcompatdiffs $v12diffs $difflines
-
-mkdir $refv11dir $refvcompatdir $refv12dir
-mkdir $newv11dir $newvcompatdir $newv12dir
-
-set -ex
-
-${TESTJAVA}/bin/rmic -keep -nowrite -v1.1 -d $refv11dir -classpath "$@"
-${TESTJAVA}/bin/rmic -keep -nowrite -vcompat -d $refvcompatdir -classpath "$@"
-${TESTJAVA}/bin/rmic -keep -nowrite -v1.2 -d $refv12dir -classpath "$@"
-
-${TESTJAVA}/bin/rmic -Xnew -keep -nowrite -v1.1 -d $newv11dir -classpath "$@"
-${TESTJAVA}/bin/rmic -Xnew -keep -nowrite -vcompat -d $newvcompatdir -classpath "$@"
-${TESTJAVA}/bin/rmic -Xnew -keep -nowrite -v1.2 -d $newv12dir -classpath "$@"
-
-set +ex
-
-diff -r $refv11dir $newv11dir > $v11diffs
-diff -r $refvcompatdir $newvcompatdir > $vcompatdiffs
-diff -r $refv12dir $newv12dir > $v12diffs
-
-cat $v11diffs $vcompatdiffs $v12diffs | grep '^[<>O]' | fgrep -v ' server = (' > $difflines
-
-if [ `cat $difflines | wc -l` -gt 0 ]
-then
- cat $v11diffs $vcompatdiffs $v12diffs
- echo "TEST FAILED: unexpected diffs"
- exit 1
-fi
-
-echo "TEST PASSED: new rmic output identical to reference rmic output"
-
-rm -rf $refv11dir $refvcompatdir $refv12dir
-rm -rf $newv11dir $newvcompatdir $newv12dir
-rm -f $v11diffs $vcompatdiffs $v12diffs $difflines
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/run.sh Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-#
-# Copyright (c) 2003, 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.
-#
-
-# @test
-# @ignore test is disabled, while further discussion on the rmic -Xnew feature
-# takes place (c.f JDK-8146299, JDK-8145980).
-# @bug 4911536
-# @summary This test verifies that the new implementation of rmic
-# generates equivalent classes as the old implementation, for a set
-# of sample input classes.
-# @author Peter Jones
-#
-# @library ../../../../../java/rmi/testlibrary
-#
-# @build TestLibrary
-# AgentServerImpl
-# AppleImpl
-# AppleUserImpl
-# ComputeServerImpl
-# CountServerImpl
-# DayTimeServerImpl
-# G1Impl
-# MyObjectImpl
-# NotActivatableServerImpl
-# OrangeEchoImpl
-# OrangeImpl
-# ServerImpl
-#
-# @run shell run.sh
-
-if [ "${TESTJAVA}" = "" ]
-then
- echo "TESTJAVA not set. Test cannot execute. Failed."
- exit 1
-fi
-
-set -ex
-
-#
-# miscellaneous remote classes collected from other tests
-#
-
-sh ${TESTSRC:-.}/batch.sh ${TESTCLASSES:-.} \
- AgentServerImpl \
- AppleImpl \
- AppleUserImpl \
- ComputeServerImpl \
- CountServerImpl \
- DayTimeServerImpl \
- G1Impl \
- MyObjectImpl \
- NotActivatableServerImpl \
- OrangeEchoImpl \
- OrangeImpl \
- ServerImpl
-
-#
-# remote classes in the J2SE implementation
-#
-
-sh ${TESTSRC:-.}/batch.sh ${TESTCLASSES:-.} \
- sun.rmi.registry.RegistryImpl \
- sun.rmi.server.Activation\$ActivationMonitorImpl \
- sun.rmi.server.Activation\$ActivationSystemImpl \
- sun.rmi.server.Activation\$ActivatorImpl \
- java.rmi.activation.ActivationGroup
--- a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/m1/p1/Main.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/m1/p1/Main.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -34,35 +34,13 @@
import java.util.Collections;
import java.util.Set;
-import jdk.internal.module.ClassFileAttributes;
-import jdk.internal.module.ClassFileAttributes.ModuleTargetAttribute;
-import jdk.internal.module.ClassFileConstants;
-import jdk.internal.org.objectweb.asm.Attribute;
-import jdk.internal.org.objectweb.asm.ClassReader;
-import jdk.internal.org.objectweb.asm.ClassVisitor;
-import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.module.ModuleInfo;
+import jdk.internal.module.ModuleInfo.Attributes;
public class Main {
private static boolean hasModuleTarget(InputStream in) throws IOException {
- ModuleTargetAttribute[] modTargets = new ModuleTargetAttribute[1];
- ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) {
- @Override
- public void visitAttribute(Attribute attr) {
- if (attr instanceof ModuleTargetAttribute) {
- modTargets[0] = (ModuleTargetAttribute)attr;
- }
- }
- };
-
- // prototype of attributes that should be parsed
- Attribute[] attrs = new Attribute[] {
- new ModuleTargetAttribute()
- };
-
- // parse module-info.class
- ClassReader cr = new ClassReader(in);
- cr.accept(cv, attrs, 0);
- return modTargets[0] != null && modTargets[0].targetPlatform() != null;
+ ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
+ return attrs.target() != null;
}
public static void main(String... args) throws Exception {
--- a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/m4/p4/Main.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/m4/p4/Main.java Wed Nov 08 16:03:35 2017 -0500
@@ -35,35 +35,13 @@
import java.util.Map;
import java.util.Set;
-import jdk.internal.module.ClassFileAttributes;
-import jdk.internal.module.ClassFileAttributes.ModuleTargetAttribute;
-import jdk.internal.module.ClassFileConstants;
-import jdk.internal.org.objectweb.asm.Attribute;
-import jdk.internal.org.objectweb.asm.ClassReader;
-import jdk.internal.org.objectweb.asm.ClassVisitor;
-import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.module.ModuleInfo;
+import jdk.internal.module.ModuleInfo.Attributes;
public class Main {
private static boolean hasModuleTarget(InputStream in) throws IOException {
- ModuleTargetAttribute[] modTargets = new ModuleTargetAttribute[1];
- ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) {
- @Override
- public void visitAttribute(Attribute attr) {
- if (attr instanceof ModuleTargetAttribute) {
- modTargets[0] = (ModuleTargetAttribute)attr;
- }
- }
- };
-
- // prototype of attributes that should be parsed
- Attribute[] attrs = new Attribute[] {
- new ModuleTargetAttribute()
- };
-
- // parse module-info.class
- ClassReader cr = new ClassReader(in);
- cr.accept(cv, attrs, 0);
- return modTargets[0] != null && modTargets[0].targetPlatform() != null;
+ ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
+ return attrs.target() != null;
}
private static boolean hasModuleTarget(String modName) throws IOException {
--- a/test/langtools/jdk/jshell/MethodsTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/langtools/jdk/jshell/MethodsTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8080357 8167643
+ * @bug 8080357 8167643 8187359
* @summary Tests for EvaluationState.methods
* @build KullaTesting TestingInputStream ExpectedDiagnostic
* @run testng MethodsTest
@@ -230,6 +230,24 @@
assertActiveKeys();
}
+ public void objectMethodNamedMethodsErrors() {
+ assertDeclareFail("boolean equals(double d1, double d2) { return d1 == d2; }",
+ new ExpectedDiagnostic("jdk.eval.error.object.method", 8, 14, 8, -1, -1, Diagnostic.Kind.ERROR));
+ assertNumberOfActiveMethods(0);
+ assertActiveKeys();
+
+ assertDeclareFail("void wait() { }",
+ new ExpectedDiagnostic("jdk.eval.error.object.method", 14, 18, 14, -1, -1, Diagnostic.Kind.ERROR));
+ assertNumberOfActiveMethods(0);
+ assertActiveKeys();
+
+ assertDeclareFail(" String toString() throws NullPointerException{ }",
+ new ExpectedDiagnostic("jdk.eval.error.object.method", 11, 19, 11, -1, -1, Diagnostic.Kind.ERROR));
+ assertNumberOfActiveMethods(0);
+ assertActiveKeys();
+
+ }
+
public void methodsAccessModifierIgnored() {
Snippet f = methodKey(assertEval("public String f() {return null;}",
--- a/test/langtools/jdk/jshell/StartOptionTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/langtools/jdk/jshell/StartOptionTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -22,7 +22,7 @@
*/
/*
- * @test 8151754 8080883 8160089 8170162 8166581 8172102 8171343 8178023
+ * @test 8151754 8080883 8160089 8170162 8166581 8172102 8171343 8178023 8186708 8179856
* @summary Testing start-up options.
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@@ -147,7 +147,7 @@
for (String opt : new String[]{"-h", "--help"}) {
start(s -> {
assertTrue(s.split("\n").length >= 7, "Not enough usage lines: " + s);
- assertTrue(s.startsWith("Usage: jshell <options>"), "Unexpect usage start: " + s);
+ assertTrue(s.startsWith("Usage: jshell <option>..."), "Unexpect usage start: " + s);
assertTrue(s.contains("--show-version"), "Expected help: " + s);
assertFalse(s.contains("Welcome"), "Unexpected start: " + s);
}, null, null, opt);
@@ -172,6 +172,38 @@
s -> assertEquals(s.trim(), "Unknown option: unknown"), "--unknown");
}
+ /**
+ * Test that input is read with "-" and there is no extra output.
+ * @throws Exception
+ */
+ public void testHypenFile() throws Exception {
+ cmdInStream = new ByteArrayInputStream("System.out.print(\"Hello\");\n".getBytes());
+ startWithUserOutput("", "Hello", "", "-");
+ cmdInStream = new ByteArrayInputStream("System.out.print(\"Hello\");\n".getBytes());
+ startWithUserOutput("", "Hello", "", "-", "-");
+ Compiler compiler = new Compiler();
+ Path path = compiler.getPath("markload.jsh");
+ compiler.writeToFile(path, "System.out.print(\"===\");");
+ cmdInStream = new ByteArrayInputStream("System.out.print(\"Hello\");\n".getBytes());
+ startWithUserOutput("", "===Hello===", "", path.toString(), "-", path.toString());
+ // check that errors go to standard error
+ cmdInStream = new ByteArrayInputStream(") Foobar".getBytes());
+ start(
+ s -> assertEquals(s.trim(), "", "cmdout: empty"),
+ s -> assertEquals(s.trim(), "", "userout: empty"),
+ s -> assertTrue(s.contains("illegal start of expression"),
+ "cmderr: illegal start of expression"),
+ "-");
+ }
+
+ /**
+ * Test that non-existent load file sends output to stderr and does not start (no welcome).
+ * @throws Exception
+ */
+ public void testUnknownLoadFile() throws Exception {
+ start("", "File 'UNKNOWN' for 'jshell' is not found.", "UNKNOWN");
+ }
+
public void testStartup() throws Exception {
Compiler compiler = new Compiler();
Path p = compiler.getPath("file.txt");
--- a/test/langtools/jdk/jshell/ToolBasicTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/langtools/jdk/jshell/ToolBasicTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -45,7 +45,6 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import java.util.Locale;
import java.util.Scanner;
import java.util.function.BiFunction;
import java.util.function.Consumer;
@@ -408,10 +407,6 @@
(a) -> assertCommand(a, "x", "x ==> 20.0"),
(a) -> assertCommand(a, "a", "a ==> 10.0")
);
- Path unknown = compiler.getPath("UNKNOWN.jar");
- test(Locale.ROOT, true, new String[]{unknown.toString()},
- "| File '" + unknown
- + "' for 'jshell' is not found.");
}
public void testReset() {
--- a/test/langtools/jdk/jshell/ToolProviderTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/langtools/jdk/jshell/ToolProviderTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -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
@@ -24,6 +24,7 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
+import java.nio.file.Path;
import java.util.ServiceLoader;
import java.util.function.Consumer;
import javax.tools.Tool;
@@ -34,7 +35,7 @@
/*
* @test
- * @bug 8170044 8171343
+ * @bug 8170044 8171343 8179856
* @summary Test ServiceLoader launching of jshell tool
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@@ -97,4 +98,21 @@
null, null,
"--show-version");
}
+ /**
+ * Test that input is read with "-" and there is no extra output.
+ * @throws Exception
+ */
+ @Override
+ public void testHypenFile() throws Exception {
+ cmdInStream = new ByteArrayInputStream("System.out.print(\"Hello\");\n".getBytes());
+ start("Hello", "", "-");
+ cmdInStream = new ByteArrayInputStream("System.out.print(\"Hello\");\n".getBytes());
+ start("Hello", "", "-", "-");
+ Compiler compiler = new Compiler();
+ Path path = compiler.getPath("markload.jsh");
+ compiler.writeToFile(path, "System.out.print(\"===\");");
+ cmdInStream = new ByteArrayInputStream("System.out.print(\"Hello\");\n".getBytes());
+ start("===Hello===", "", path.toString(), "-", path.toString());
+ }
+
}
--- a/test/langtools/jdk/jshell/ToolTabCommandTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/langtools/jdk/jshell/ToolTabCommandTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -84,10 +84,6 @@
inputSink.write("\u0003/env \011");
waitOutput(out, "\u0005/env -\n" +
"-add-exports -add-modules -class-path -module-path \n" +
- "\r\u0005/env -");
-
- inputSink.write("\011");
- waitOutput(out, "-add-exports -add-modules -class-path -module-path \n" +
"\n" +
Pattern.quote(getResource("jshell.console.see.synopsis")) + "\n" +
"\r\u0005/env -");
--- a/test/langtools/jdk/jshell/ToolTabSnippetTest.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/langtools/jdk/jshell/ToolTabSnippetTest.java Wed Nov 08 16:03:35 2017 -0500
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 8177076 8185426
+ * @bug 8177076 8185426 8189595 8188072
* @modules
* jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@@ -191,6 +191,10 @@
//no crash:
inputSink.write("\u0003new Stringbuil\011");
waitOutput(out, "\u0005new Stringbuil\u0007");
+
+ //no crash: 8188072
+ inputSink.write("\u0003for (int:\011");
+ waitOutput(out, "\u0005for \\(int:\u0007");
});
}
@@ -227,6 +231,31 @@
});
}
+ public void testNoRepeat() throws Exception {
+ doRunTest((inputSink, out) -> {
+ inputSink.write("String xyzAA;\n");
+ waitOutput(out, "\u0005");
+
+ //xyz<tab>
+ inputSink.write("String s = xyz\011");
+ waitOutput(out, "^String s = xyzAA");
+ inputSink.write(".");
+ waitOutput(out, "^\\.");
+
+ inputSink.write("\u0003");
+ waitOutput(out, "\u0005");
+
+ inputSink.write("double xyzAB;\n");
+ waitOutput(out, "\u0005");
+
+ //xyz<tab>
+ inputSink.write("String s = xyz\011");
+ String allCompletions =
+ Pattern.quote(getResource("jshell.console.completion.all.completions"));
+ waitOutput(out, ".*xyzAA.*" + allCompletions + ".*\u0005String s = xyzA");
+ });
+ }
+
private Path prepareZip() {
String clazz1 =
"package jshelltest;\n" +
--- a/test/langtools/tools/javac/diags/examples/PatchModuleWithRelease/PatchModuleWithRelease.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * 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.
- */
-
-// key: compiler.err.patch.module.with.release
-// options: --release 9
-
-class PatchModuleWithRelease {
-}
--- a/test/langtools/tools/javac/diags/examples/PatchModuleWithRelease/patchmodule/java.base/java/lang/Test.java Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * 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.
- */
-
-package java.lang;
-
-class Test {
-}
--- a/test/langtools/tools/javac/options/release/ReleaseOptionUnsupported.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/langtools/tools/javac/options/release/ReleaseOptionUnsupported.java Wed Nov 08 16:03:35 2017 -0500
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 8178152
+ * @bug 8178152 8187681
* @summary Verify unsupported modules and module options handling.
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
@@ -263,35 +263,19 @@
tb.createDirectories(patch);
new JavacTask(tb)
- .options("-XDrawDiagnostics",
- "--patch-module", "java.base=" + patch)
+ .options("--patch-module", "java.base=" + patch)
.outdir(classes)
.files(tb.findJavaFiles(src))
.run(Expect.SUCCESS)
- .writeAll()
- .getOutputLines(Task.OutputKind.DIRECT);
+ .writeAll();
- List<String> log;
- List<String> expected;
-
- log = new JavacTask(tb)
- .options("-XDrawDiagnostics",
- "--patch-module", "java.base=" + patch,
+ new JavacTask(tb)
+ .options("--patch-module", "java.base=" + patch,
"--release", Target.DEFAULT.multiReleaseValue())
.outdir(classes)
.files(tb.findJavaFiles(src))
- .run(Expect.FAIL)
- .writeAll()
- .getOutputLines(Task.OutputKind.DIRECT);
-
- expected = Arrays.asList(
- "- compiler.err.patch.module.with.release: java.base",
- "1 error"
- );
-
- if (!expected.equals(log)) {
- throw new AssertionError("Unexpected output: " + log);
- }
+ .run(Expect.SUCCESS)
+ .writeAll();
//OK to patch a non-system module:
tb.createDirectories(classes);
--- a/test/langtools/tools/javac/tree/NoPrivateTypesExported.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/langtools/tools/javac/tree/NoPrivateTypesExported.java Wed Nov 08 16:03:35 2017 -0500
@@ -206,6 +206,33 @@
}
return null;
}
+ @Override public Void visitBoolean(boolean b, Void p) {
+ return null;
+ }
+ @Override public Void visitByte(byte b, Void p) {
+ return null;
+ }
+ @Override public Void visitChar(char c, Void p) {
+ return null;
+ }
+ @Override public Void visitDouble(double d, Void p) {
+ return null;
+ }
+ @Override public Void visitFloat(float f, Void p) {
+ return null;
+ }
+ @Override public Void visitInt(int i, Void p) {
+ return null;
+ }
+ @Override public Void visitLong(long i, Void p) {
+ return null;
+ }
+ @Override public Void visitShort(short s, Void p) {
+ return null;
+ }
+ @Override public Void visitString(String s, Void p) {
+ return null;
+ }
@Override protected Void defaultAction(Object o, Void p) {
error("Unexpected AnnotationValue: " + o.toString());
return super.defaultAction(o, p);
--- a/test/lib/sun/hotspot/WhiteBox.java Mon Nov 06 19:45:47 2017 +0100
+++ b/test/lib/sun/hotspot/WhiteBox.java Wed Nov 08 16:03:35 2017 -0500
@@ -525,6 +525,7 @@
public native boolean areSharedStringsIgnored();
public native boolean isCDSIncludedInVmBuild();
public native Object getResolvedReferences(Class<?> c);
+ public native boolean areOpenArchiveHeapObjectsMapped();
// Compiler Directive
public native int addCompilerDirective(String compDirect);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/nashorn/script/basic/JDK-8190698.js Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * JDK-8190698: jjs tool of jdk.scripting.nashorn.shell module should not statically depend on java.desktop
+ *
+ * @test
+ * @run
+ */
+
+var optJjsMod = java.lang.ModuleLayer.boot().findModule("jdk.scripting.nashorn.shell");
+
+// make sure that the module exists!
+Assert.assertTrue(optJjsMod.isPresent());
+
+// jdk.scripting.nashorn.shell should not have java.desktop dependency
+var javaDesktopDependency = optJjsMod.get().
+ descriptor.requires().
+ stream().
+ filter(function(mod) { return mod.name() == "java.desktop" }).
+ findFirst();
+
+Assert.assertTrue(!javaDesktopDependency.isPresent());