--- a/.hgtags Thu Apr 28 00:38:21 2016 -0700
+++ b/.hgtags Thu Apr 28 23:08:17 2016 -0700
@@ -357,3 +357,4 @@
7359994942f8d8e723b584d66a3a92c2e9e95e5c jdk-9+112
6072af7a98be3922f26bdce71b53bb3646cb2ac9 jdk-9+113
c84d0cce090e161d736de69e941830adf8c2f87a jdk-9+114
+8d78fb40648dd221ce4ef19f9d5aa41ee1a3a884 jdk-9+115
--- a/.hgtags-top-repo Thu Apr 28 00:38:21 2016 -0700
+++ b/.hgtags-top-repo Thu Apr 28 23:08:17 2016 -0700
@@ -357,3 +357,4 @@
03543a758cd5890f2266e4b9678378a925dde22a jdk-9+112
55b6d550828d1223b364e6ead4a56e56411c56df jdk-9+113
1d992540870ff33fe6cc550443388588df9b9e4f jdk-9+114
+09617ce980b99d49abfd54dacfed353c47e2a115 jdk-9+115
--- a/common/autoconf/basics.m4 Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/basics.m4 Thu Apr 28 23:08:17 2016 -0700
@@ -749,8 +749,8 @@
BASIC_PREPEND_TO_PATH([PATH],$EXTRA_PATH)
if test "x$OPENJDK_BUILD_OS" = "xsolaris"; then
- # Add extra search paths on solaris for utilities like ar and as etc...
- PATH="$PATH:/usr/ccs/bin:/usr/sfw/bin:/opt/csw/bin"
+ # Add extra search paths on solaris for utilities like ar, as, dtrace etc...
+ PATH="$PATH:/usr/ccs/bin:/usr/sfw/bin:/opt/csw/bin:/usr/sbin"
fi
AC_MSG_CHECKING([for sysroot])
@@ -777,7 +777,7 @@
# Create a default ./build/target-variant-debuglevel output root.
if test "x${CONF_NAME}" = x; then
AC_MSG_RESULT([in default location])
- CONF_NAME="${OPENJDK_TARGET_OS}-${OPENJDK_TARGET_CPU}-${JDK_VARIANT}-${ANDED_JVM_VARIANTS}-${DEBUG_LEVEL}"
+ CONF_NAME="${OPENJDK_TARGET_OS}-${OPENJDK_TARGET_CPU}-${JDK_VARIANT}-${JVM_VARIANTS_WITH_AND}-${DEBUG_LEVEL}"
else
AC_MSG_RESULT([in build directory with custom name])
fi
@@ -1037,6 +1037,7 @@
BASIC_PATH_PROGS(HG, hg)
BASIC_PATH_PROGS(STAT, stat)
BASIC_PATH_PROGS(TIME, time)
+ BASIC_PATH_PROGS(DTRACE, dtrace)
BASIC_PATH_PROGS(PATCH, [gpatch patch])
# Check if it's GNU time
IS_GNU_TIME=`$TIME --version 2>&1 | $GREP 'GNU time'`
--- a/common/autoconf/build-performance.m4 Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/build-performance.m4 Thu Apr 28 23:08:17 2016 -0700
@@ -364,6 +364,9 @@
elif test "x$ICECC" != "x"; then
AC_MSG_RESULT([no, does not work effectively with icecc])
USE_PRECOMPILED_HEADER=0
+ elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+ AC_MSG_RESULT([no, does not work with Solaris Studio])
+ USE_PRECOMPILED_HEADER=0
else
AC_MSG_RESULT([yes])
fi
--- a/common/autoconf/buildjdk-spec.gmk.in Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/buildjdk-spec.gmk.in Thu Apr 28 23:08:17 2016 -0700
@@ -57,6 +57,12 @@
OPENJDK_TARGET_CPU_ENDIAN := @OPENJDK_BUILD_CPU_ENDIAN@
OPENJDK_TARGET_CPU_LEGACY := @OPENJDK_BUILD_CPU_LEGACY@
+HOTSPOT_TARGET_OS := @HOTSPOT_BUILD_OS@
+HOTSPOT_TARGET_OS_TYPE := @HOTSPOT_BUILD_OS_TYPE@
+HOTSPOT_TARGET_CPU := @HOTSPOT_BUILD_CPU@
+HOTSPOT_TARGET_CPU_ARCH := @HOTSPOT_BUILD_CPU_ARCH@
+HOTSPOT_TARGET_CPU_DEFINE := @HOTSPOT_BUILD_CPU_DEFINE@
+
CFLAGS_JDKLIB := @OPENJDK_BUILD_CFLAGS_JDKLIB@
CXXFLAGS_JDKLIB := @OPENJDK_BUILD_CXXFLAGS_JDKLIB@
LDFLAGS_JDKLIB := @OPENJDK_BUILD_LDFLAGS_JDKLIB@
@@ -65,6 +71,11 @@
LDFLAGS_JDKEXE := @OPENJDK_BUILD_LDFLAGS_JDKEXE@
OPENJDK_TARGET_CPU_JLI_CFLAGS := @OPENJDK_BUILD_CPU_JLI_CFLAGS@
+JVM_CFLAGS := @OPENJDK_BUILD_JVM_CFLAGS@
+JVM_LDFLAGS := @OPENJDK_BUILD_JVM_LDFLAGS@
+JVM_ASFLAGS := @OPENJDK_BUILD_JVM_ASFLAGS@
+JVM_LIBS := @OPENJDK_BUILD_JVM_LIBS@
+
# The compiler for the build platform is likely not warning compatible with the official
# compiler.
WARNINGS_AS_ERRORS := false
--- a/common/autoconf/compare.sh.in Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/compare.sh.in Thu Apr 28 23:08:17 2016 -0700
@@ -31,7 +31,7 @@
export LEGACY_BUILD_DIR=@OPENJDK_TARGET_OS@-@OPENJDK_TARGET_CPU_LEGACY@
-export OPENJDK_TARGET_OS="@OPENJDK_TARGET_OS@"
+sexport OPENJDK_TARGET_OS="@OPENJDK_TARGET_OS@"
export OPENJDK_TARGET_CPU="@OPENJDK_TARGET_CPU@"
export OPENJDK_TARGET_CPU_LIBDIR="@OPENJDK_TARGET_CPU_LIBDIR@"
export DEBUG_LEVEL="@DEBUG_LEVEL@"
--- a/common/autoconf/configure Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/configure Thu Apr 28 23:08:17 2016 -0700
@@ -283,7 +283,7 @@
EOT
- # Print additional help, e.g. a list of toolchains.
+ # Print additional help, e.g. a list of toolchains and JVM features.
# This must be done by the autoconf script.
( CONFIGURE_PRINT_ADDITIONAL_HELP=true . $conf_script_to_run PRINTF=printf )
--- a/common/autoconf/configure.ac Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/configure.ac Thu Apr 28 23:08:17 2016 -0700
@@ -95,10 +95,8 @@
# These are needed to be able to create a configuration name (and thus the output directory)
JDKOPT_SETUP_JDK_VARIANT
-HOTSPOT_SETUP_JVM_INTERPRETER
+JDKOPT_SETUP_DEBUG_LEVEL
HOTSPOT_SETUP_JVM_VARIANTS
-JDKOPT_SETUP_DEBUG_LEVEL
-HOTSPOT_SETUP_DEBUG_LEVEL
# With basic setup done, call the custom early hook.
CUSTOM_EARLY_HOOK
@@ -135,7 +133,6 @@
# We need build & target for this.
JDKOPT_SETUP_JDK_OPTIONS
JDKOPT_SETUP_JLINK_OPTIONS
-HOTSPOT_SETUP_HOTSPOT_OPTIONS
JDKVER_SETUP_JDK_VERSION_NUMBERS
###############################################################################
@@ -207,6 +204,10 @@
JDKOPT_SETUP_DEBUG_SYMBOLS
JDKOPT_SETUP_CODE_COVERAGE
+# Need toolchain to setup dtrace
+HOTSPOT_SETUP_DTRACE
+HOTSPOT_SETUP_JVM_FEATURES
+
###############################################################################
#
# Check dependencies for external and internal libraries.
@@ -225,7 +226,7 @@
#
###############################################################################
-HOTSPOT_SETUP_BUILD_TWEAKS
+HOTSPOT_SETUP_LEGACY_BUILD
JDKOPT_DETECT_INTREE_EC
JDKOPT_ENABLE_DISABLE_FAILURE_HANDLER
@@ -268,6 +269,9 @@
# At the end, call the custom hook. (Dummy macro if no custom sources available)
CUSTOM_LATE_HOOK
+# This needs to be done after CUSTOM_LATE_HOOK since we can setup custom features.
+HOTSPOT_VALIDATE_JVM_FEATURES
+
# We're messing a bit with internal autoconf variables to put the config.status
# in the output directory instead of the current directory.
CONFIG_STATUS="$CONFIGURESUPPORT_OUTPUTDIR/config.status"
--- a/common/autoconf/flags.m4 Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/flags.m4 Thu Apr 28 23:08:17 2016 -0700
@@ -61,6 +61,10 @@
AC_SUBST(LEGACY_EXTRA_CXXFLAGS)
AC_SUBST(LEGACY_EXTRA_LDFLAGS)
+ AC_SUBST(EXTRA_CFLAGS)
+ AC_SUBST(EXTRA_CXXFLAGS)
+ AC_SUBST(EXTRA_LDFLAGS)
+
# The global CFLAGS and LDLAGS variables are used by configure tests and
# should include the extra parameters
CFLAGS="$EXTRA_CFLAGS"
@@ -211,8 +215,10 @@
# On Windows, we need to set RC flags.
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
RC_FLAGS="-nologo -l0x409"
+ JVM_RCFLAGS="-nologo"
if test "x$DEBUG_LEVEL" = xrelease; then
RC_FLAGS="$RC_FLAGS -DNDEBUG"
+ JVM_RCFLAGS="$JVM_RCFLAGS -DNDEBUG"
fi
# The version variables used to create RC_FLAGS may be overridden
@@ -228,8 +234,19 @@
-D\"JDK_COPYRIGHT=Copyright \xA9 $COPYRIGHT_YEAR\" \
-D\"JDK_NAME=\$(PRODUCT_NAME) \$(JDK_RC_PLATFORM_NAME) \$(VERSION_MAJOR)\" \
-D\"JDK_FVER=\$(subst .,\$(COMMA),\$(VERSION_NUMBER_FOUR_POSITIONS))\""
+
+ JVM_RCFLAGS="$JVM_RCFLAGS \
+ -D\"HS_BUILD_ID=\$(VERSION_STRING)\" \
+ -D\"HS_COMPANY=\$(COMPANY_NAME)\" \
+ -D\"JDK_DOTVER=\$(VERSION_NUMBER_FOUR_POSITIONS)\" \
+ -D\"HS_COPYRIGHT=Copyright $COPYRIGHT_YEAR\" \
+ -D\"HS_NAME=\$(PRODUCT_NAME) \$(VERSION_SHORT)\" \
+ -D\"JDK_VER=\$(subst .,\$(COMMA),\$(VERSION_NUMBER_FOUR_POSITIONS))\" \
+ -D\"HS_FNAME=jvm.dll\" \
+ -D\"HS_INTERNAL_NAME=jvm\""
fi
AC_SUBST(RC_FLAGS)
+ AC_SUBST(JVM_RCFLAGS)
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
# silence copyright notice and other headers.
@@ -237,7 +254,7 @@
fi
])
-AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_LIBS],
+AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_LIBS],
[
###############################################################################
#
@@ -255,6 +272,7 @@
SHARED_LIBRARY_FLAGS ='-undefined dynamic_lookup'
else
SHARED_LIBRARY_FLAGS="-dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0 $PICFLAG"
+ JVM_CFLAGS="$JVM_CFLAGS $PICFLAG"
fi
SET_EXECUTABLE_ORIGIN='-Wl,-rpath,@loader_path/.'
SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
@@ -280,6 +298,10 @@
SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-Wl,-install_name,@rpath/[$]1'
SET_SHARED_LIBRARY_MAPFILE='-Wl,-exported_symbols_list,[$]1'
+
+ if test "x$STATIC_BUILD" = xfalse; then
+ JVM_CFLAGS="$JVM_CFLAGS -fPIC"
+ fi
else
# Default works for linux, might work on other platforms as well.
PICFLAG='-fPIC'
@@ -339,11 +361,6 @@
AC_SUBST(SET_SHARED_LIBRARY_MAPFILE)
AC_SUBST(SHARED_LIBRARY_FLAGS)
- if test "x$OPENJDK_TARGET_OS" = xsolaris; then
- CFLAGS_JDK="${CFLAGS_JDK} -D__solaris__"
- CXXFLAGS_JDK="${CXXFLAGS_JDK} -D__solaris__"
- CFLAGS_JDKLIB_EXTRA='-xstrconst'
- fi
# The (cross) compiler is now configured, we can now test capabilities
# of the target platform.
])
@@ -434,6 +451,22 @@
AC_SUBST(CFLAGS_DEBUG_SYMBOLS)
AC_SUBST(CXXFLAGS_DEBUG_SYMBOLS)
+ # Debug symbols for JVM_CFLAGS
+ if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+ JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -xs"
+ if test "x$DEBUG_LEVEL" = xslowdebug; then
+ JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -g"
+ else
+ # -g0 does not disable inlining, which -g does.
+ JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -g0"
+ fi
+ elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+ JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -Z7 -d2Zi+"
+ else
+ JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -g"
+ fi
+ AC_SUBST(JVM_CFLAGS_SYMBOLS)
+
# bounds, memory and behavior checking options
if test "x$TOOLCHAIN_TYPE" = xgcc; then
case $DEBUG_LEVEL in
@@ -444,7 +477,7 @@
# no adjustment
;;
slowdebug )
- # FIXME: By adding this to C(XX)FLAGS_DEBUG_OPTIONS it
+ # FIXME: By adding this to C(XX)FLAGS_DEBUG_OPTIONS/JVM_CFLAGS_SYMBOLS it
# get's added conditionally on whether we produce debug symbols or not.
# This is most likely not really correct.
@@ -455,40 +488,59 @@
CFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
CXXFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
+ if test "x$STACK_PROTECTOR_CFLAG" != x; then
+ JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS $STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
+ fi
;;
esac
fi
+ if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+ if test "x$DEBUG_LEVEL" != xrelease; then
+ if test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+ JVM_CFLAGS="$JVM_CFLAGS -homeparams"
+ fi
+ fi
+ fi
+
# Optimization levels
if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
CC_HIGHEST="$CC_HIGHEST -fns -fsimple -fsingle -xbuiltin=%all -xdepend -xrestrict -xlibmil"
if test "x$OPENJDK_TARGET_CPU_ARCH" = "xx86"; then
# FIXME: seems we always set -xregs=no%frameptr; put it elsewhere more global?
+ C_O_FLAG_HIGHEST_JVM="-xO4"
C_O_FLAG_HIGHEST="-xO4 -Wu,-O4~yz $CC_HIGHEST -xalias_level=basic -xregs=no%frameptr"
C_O_FLAG_HI="-xO4 -Wu,-O4~yz -xregs=no%frameptr"
C_O_FLAG_NORM="-xO2 -Wu,-O2~yz -xregs=no%frameptr"
C_O_FLAG_DEBUG="-xregs=no%frameptr"
+ C_O_FLAG_DEBUG_JVM=""
C_O_FLAG_NONE="-xregs=no%frameptr"
+ CXX_O_FLAG_HIGHEST_JVM="-xO4"
CXX_O_FLAG_HIGHEST="-xO4 -Qoption ube -O4~yz $CC_HIGHEST -xregs=no%frameptr"
CXX_O_FLAG_HI="-xO4 -Qoption ube -O4~yz -xregs=no%frameptr"
CXX_O_FLAG_NORM="-xO2 -Qoption ube -O2~yz -xregs=no%frameptr"
CXX_O_FLAG_DEBUG="-xregs=no%frameptr"
+ CXX_O_FLAG_DEBUG_JVM=""
CXX_O_FLAG_NONE="-xregs=no%frameptr"
if test "x$OPENJDK_TARGET_CPU_BITS" = "x32"; then
C_O_FLAG_HIGHEST="$C_O_FLAG_HIGHEST -xchip=pentium"
CXX_O_FLAG_HIGHEST="$CXX_O_FLAG_HIGHEST -xchip=pentium"
fi
elif test "x$OPENJDK_TARGET_CPU_ARCH" = "xsparc"; then
+ C_O_FLAG_HIGHEST_JVM="-xO4"
C_O_FLAG_HIGHEST="-xO4 -Wc,-Qrm-s -Wc,-Qiselect-T0 $CC_HIGHEST -xalias_level=basic -xprefetch=auto,explicit -xchip=ultra"
C_O_FLAG_HI="-xO4 -Wc,-Qrm-s -Wc,-Qiselect-T0"
C_O_FLAG_NORM="-xO2 -Wc,-Qrm-s -Wc,-Qiselect-T0"
C_O_FLAG_DEBUG=""
+ C_O_FLAG_DEBUG_JVM=""
C_O_FLAG_NONE=""
+ CXX_O_FLAG_HIGHEST_JVM="-xO4"
CXX_O_FLAG_HIGHEST="-xO4 -Qoption cg -Qrm-s -Qoption cg -Qiselect-T0 $CC_HIGHEST -xprefetch=auto,explicit -xchip=ultra"
CXX_O_FLAG_HI="-xO4 -Qoption cg -Qrm-s -Qoption cg -Qiselect-T0"
CXX_O_FLAG_NORM="-xO2 -Qoption cg -Qrm-s -Qoption cg -Qiselect-T0"
CXX_O_FLAG_DEBUG=""
+ CXX_O_FLAG_DEBUG_JVM=""
CXX_O_FLAG_NONE=""
fi
else
@@ -498,48 +550,75 @@
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
# On MacOSX we optimize for size, something
# we should do for all platforms?
+ C_O_FLAG_HIGHEST_JVM="-Os"
C_O_FLAG_HIGHEST="-Os"
C_O_FLAG_HI="-Os"
C_O_FLAG_NORM="-Os"
+ C_O_FLAG_SIZE="-Os"
else
+ C_O_FLAG_HIGHEST_JVM="-O3"
C_O_FLAG_HIGHEST="-O3"
C_O_FLAG_HI="-O3"
C_O_FLAG_NORM="-O2"
+ C_O_FLAG_SIZE="-Os"
fi
C_O_FLAG_DEBUG="-O0"
+ if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+ C_O_FLAG_DEBUG_JVM=""
+ elif test "x$OPENJDK_TARGET_OS" = xlinux; then
+ C_O_FLAG_DEBUG_JVM="-O0"
+ fi
C_O_FLAG_NONE="-O0"
elif test "x$TOOLCHAIN_TYPE" = xclang; then
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
# On MacOSX we optimize for size, something
# we should do for all platforms?
+ C_O_FLAG_HIGHEST_JVM="-Os"
C_O_FLAG_HIGHEST="-Os"
C_O_FLAG_HI="-Os"
C_O_FLAG_NORM="-Os"
+ C_O_FLAG_SIZE="-Os"
else
+ C_O_FLAG_HIGHEST_JVM="-O3"
C_O_FLAG_HIGHEST="-O3"
C_O_FLAG_HI="-O3"
C_O_FLAG_NORM="-O2"
+ C_O_FLAG_SIZE="-Os"
fi
C_O_FLAG_DEBUG="-O0"
+ if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+ C_O_FLAG_DEBUG_JVM=""
+ elif test "x$OPENJDK_TARGET_OS" = xlinux; then
+ C_O_FLAG_DEBUG_JVM="-O0"
+ fi
C_O_FLAG_NONE="-O0"
elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+ C_O_FLAG_HIGHEST_JVM="-O3"
C_O_FLAG_HIGHEST="-O3"
C_O_FLAG_HI="-O3 -qstrict"
C_O_FLAG_NORM="-O2"
C_O_FLAG_DEBUG="-qnoopt"
+ # FIXME: Value below not verified.
+ C_O_FLAG_DEBUG_JVM=""
C_O_FLAG_NONE="-qnoopt"
elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+ C_O_FLAG_HIGHEST_JVM="-O2 -Oy-"
C_O_FLAG_HIGHEST="-O2"
C_O_FLAG_HI="-O1"
C_O_FLAG_NORM="-O1"
C_O_FLAG_DEBUG="-Od"
+ C_O_FLAG_DEBUG_JVM=""
C_O_FLAG_NONE="-Od"
+ C_O_FLAG_SIZE="-Os"
fi
+ CXX_O_FLAG_HIGHEST_JVM="$C_O_FLAG_HIGHEST_JVM"
CXX_O_FLAG_HIGHEST="$C_O_FLAG_HIGHEST"
CXX_O_FLAG_HI="$C_O_FLAG_HI"
CXX_O_FLAG_NORM="$C_O_FLAG_NORM"
CXX_O_FLAG_DEBUG="$C_O_FLAG_DEBUG"
+ CXX_O_FLAG_DEBUG_JVM="$C_O_FLAG_DEBUG_JVM"
CXX_O_FLAG_NONE="$C_O_FLAG_NONE"
+ CXX_O_FLAG_SIZE="$C_O_FLAG_SIZE"
fi
# Adjust optimization flags according to debug level.
@@ -554,51 +633,105 @@
;;
slowdebug )
# Disable optimization
+ C_O_FLAG_HIGHEST_JVM="$C_O_FLAG_DEBUG_JVM"
C_O_FLAG_HIGHEST="$C_O_FLAG_DEBUG"
C_O_FLAG_HI="$C_O_FLAG_DEBUG"
C_O_FLAG_NORM="$C_O_FLAG_DEBUG"
+ C_O_FLAG_SIZE="$C_O_FLAG_DEBUG"
+ CXX_O_FLAG_HIGHEST_JVM="$CXX_O_FLAG_DEBUG_JVM"
CXX_O_FLAG_HIGHEST="$CXX_O_FLAG_DEBUG"
CXX_O_FLAG_HI="$CXX_O_FLAG_DEBUG"
CXX_O_FLAG_NORM="$CXX_O_FLAG_DEBUG"
+ CXX_O_FLAG_SIZE="$CXX_O_FLAG_DEBUG"
;;
esac
+ AC_SUBST(C_O_FLAG_HIGHEST_JVM)
AC_SUBST(C_O_FLAG_HIGHEST)
AC_SUBST(C_O_FLAG_HI)
AC_SUBST(C_O_FLAG_NORM)
AC_SUBST(C_O_FLAG_DEBUG)
AC_SUBST(C_O_FLAG_NONE)
+ AC_SUBST(C_O_FLAG_SIZE)
+ AC_SUBST(CXX_O_FLAG_HIGHEST_JVM)
AC_SUBST(CXX_O_FLAG_HIGHEST)
AC_SUBST(CXX_O_FLAG_HI)
AC_SUBST(CXX_O_FLAG_NORM)
AC_SUBST(CXX_O_FLAG_DEBUG)
AC_SUBST(CXX_O_FLAG_NONE)
+ AC_SUBST(CXX_O_FLAG_SIZE)
])
-AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK],
+
+AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK],
+[
+
+ FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER([TARGET])
+ FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER([BUILD], [OPENJDK_BUILD_])
+
+ # Tests are only ever compiled for TARGET
+ # Flags for compiling test libraries
+ CFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
+ CXXFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
+
+ # Flags for compiling test executables
+ CFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK"
+ CXXFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK"
+
+ AC_SUBST(CFLAGS_TESTLIB)
+ AC_SUBST(CFLAGS_TESTEXE)
+ AC_SUBST(CXXFLAGS_TESTLIB)
+ AC_SUBST(CXXFLAGS_TESTEXE)
+
+ LDFLAGS_TESTLIB="$LDFLAGS_JDKLIB"
+ LDFLAGS_TESTEXE="$LDFLAGS_JDKEXE"
+
+ AC_SUBST(LDFLAGS_TESTLIB)
+ AC_SUBST(LDFLAGS_TESTEXE)
+
+])
+
+################################################################################
+# $1 - Either BUILD or TARGET to pick the correct OS/CPU variables to check
+# conditionals against.
+# $2 - Optional prefix for each variable defined.
+AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER],
[
# Special extras...
if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
- if test "x$OPENJDK_TARGET_CPU_ARCH" = "xsparc"; then
- CFLAGS_JDKLIB_EXTRA="${CFLAGS_JDKLIB_EXTRA} -xregs=no%appl"
- CXXFLAGS_JDKLIB_EXTRA="${CXXFLAGS_JDKLIB_EXTRA} -xregs=no%appl"
+ if test "x$OPENJDK_$1_CPU_ARCH" = "xsparc"; then
+ $2CFLAGS_JDKLIB_EXTRA="${$2CFLAGS_JDKLIB_EXTRA} -xregs=no%appl"
+ $2CXXFLAGS_JDKLIB_EXTRA="${$2CXXFLAGS_JDKLIB_EXTRA} -xregs=no%appl"
fi
- CFLAGS_JDKLIB_EXTRA="${CFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
- CXXFLAGS_JDKLIB_EXTRA="${CXXFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
+ $2CFLAGS_JDKLIB_EXTRA="${$2CFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
+ $2CXXFLAGS_JDKLIB_EXTRA="${$2CXXFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+ $2CFLAGS_JDK="${$2CFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+ $2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+ elif test "x$TOOLCHAIN_TYPE" = xgcc; then
+ $2CXXSTD_CXXFLAG="-std=gnu++98"
+ FLAGS_CXX_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [[$]$2CXXSTD_CXXFLAG -Werror],
+ IF_FALSE: [$2CXXSTD_CXXFLAG=""])
+ $2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} ${$2CXXSTD_CXXFLAG}"
+ AC_SUBST([$2CXXSTD_CXXFLAG])
+ fi
+ if test "x$OPENJDK_TARGET_OS" = xsolaris; then
+ $2CFLAGS_JDK="${$2CFLAGS_JDK} -D__solaris__"
+ $2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} -D__solaris__"
+ $2CFLAGS_JDKLIB_EXTRA='-xstrconst'
CFLAGS_JDK="${CFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
CXXFLAGS_JDK="${CXXFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
- elif test "x$TOOLCHAIN_TYPE" = xgcc; then
- CXXSTD_CXXFLAG="-std=gnu++98"
- FLAGS_CXX_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$CXXSTD_CXXFLAG -Werror],
- IF_FALSE: [CXXSTD_CXXFLAG=""])
- CXXFLAGS_JDK="${CXXFLAGS_JDK} ${CXXSTD_CXXFLAG}"
- AC_SUBST([CXXSTD_CXXFLAG])
fi
- CFLAGS_JDK="${CFLAGS_JDK} $EXTRA_CFLAGS"
- CXXFLAGS_JDK="${CXXFLAGS_JDK} $EXTRA_CXXFLAGS"
- LDFLAGS_JDK="${LDFLAGS_JDK} $EXTRA_LDFLAGS"
+ if test "x$OPENJDK_TARGET_OS" = xsolaris; then
+ $2CFLAGS_JDK="${$2CFLAGS_JDK} -D__solaris__"
+ $2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} -D__solaris__"
+ $2CFLAGS_JDKLIB_EXTRA='-xstrconst'
+ fi
+
+ $2CFLAGS_JDK="${$2CFLAGS_JDK} ${$2EXTRA_CFLAGS}"
+ $2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} ${$2EXTRA_CXXFLAGS}"
+ $2LDFLAGS_JDK="${$2LDFLAGS_JDK} ${$2EXTRA_LDFLAGS}"
###############################################################################
#
@@ -607,79 +740,94 @@
#
# Setup compiler/platform specific flags into
- # CFLAGS_JDK - C Compiler flags
- # CXXFLAGS_JDK - C++ Compiler flags
- # COMMON_CCXXFLAGS_JDK - common to C and C++
+ # $2CFLAGS_JDK - C Compiler flags
+ # $2CXXFLAGS_JDK - C++ Compiler flags
+ # $2COMMON_CCXXFLAGS_JDK - common to C and C++
if test "x$TOOLCHAIN_TYPE" = xgcc; then
- if test "x$OPENJDK_TARGET_CPU" = xx86; then
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_GNU_SOURCE"
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_REENTRANT"
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -fcheck-new"
+ if test "x$OPENJDK_$1_CPU" = xx86; then
# Force compatibility with i586 on 32 bit intel platforms.
- COMMON_CCXXFLAGS="${COMMON_CCXXFLAGS} -march=i586"
+ $2COMMON_CCXXFLAGS="${$2COMMON_CCXXFLAGS} -march=i586"
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -march=i586"
fi
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS [$]$2COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
-pipe -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
- case $OPENJDK_TARGET_CPU_ARCH in
+ case $OPENJDK_$1_CPU_ARCH in
arm )
# on arm we don't prevent gcc to omit frame pointer but do prevent strict aliasing
- CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
+ $2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
;;
ppc )
# on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
- CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
+ $2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
;;
* )
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
- CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
+ $2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
;;
esac
TOOLCHAIN_CHECK_COMPILER_VERSION(VERSION: 6, IF_AT_LEAST: FLAGS_SETUP_GCC6_COMPILER_FLAGS)
elif test "x$TOOLCHAIN_TYPE" = xclang; then
- if test "x$OPENJDK_TARGET_OS" = xlinux; then
- if test "x$OPENJDK_TARGET_CPU" = xx86; then
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_GNU_SOURCE"
+
+ # Restrict the debug information created by Clang to avoid
+ # too big object files and speed the build up a little bit
+ # (see http://llvm.org/bugs/show_bug.cgi?id=7554)
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -flimit-debug-info"
+ if test "x$OPENJDK_$1_OS" = xlinux; then
+ if test "x$OPENJDK_$1_CPU" = xx86; then
# Force compatibility with i586 on 32 bit intel platforms.
- COMMON_CCXXFLAGS="${COMMON_CCXXFLAGS} -march=i586"
+ $2COMMON_CCXXFLAGS="${$2COMMON_CCXXFLAGS} -march=i586"
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -march=i586"
fi
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wno-sometimes-uninitialized"
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS [$]$2COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
-pipe -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
- case $OPENJDK_TARGET_CPU_ARCH in
+ case $OPENJDK_$1_CPU_ARCH in
ppc )
# on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
- CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
+ $2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
;;
* )
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
- CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
+ $2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
;;
esac
fi
elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -DTRACING -DMACRO_MEMSYS_OPS -DBREAKPTS"
- if test "x$OPENJDK_TARGET_CPU_ARCH" = xx86; then
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DcpuIntel -Di586 -D$OPENJDK_TARGET_CPU_LEGACY_LIB"
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -DSPARC_WORKS"
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS [$]$2COMMON_CCXXFLAGS_JDK -DTRACING -DMACRO_MEMSYS_OPS -DBREAKPTS"
+ if test "x$OPENJDK_$1_CPU_ARCH" = xx86; then
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -DcpuIntel -Di586 -D$OPENJDK_$1_CPU_LEGACY_LIB"
fi
- CFLAGS_JDK="$CFLAGS_JDK -xc99=%none -xCC -errshort=tags -Xa -v -mt -W0,-noglobal"
- CXXFLAGS_JDK="$CXXFLAGS_JDK -errtags=yes +w -mt -features=no%except -DCC_NOEX -norunpath -xnolib"
+ $2CFLAGS_JDK="[$]$2CFLAGS_JDK -xc99=%none -xCC -errshort=tags -Xa -v -mt -W0,-noglobal"
+ $2CXXFLAGS_JDK="[$]$2CXXFLAGS_JDK -errtags=yes +w -mt -features=no%except -DCC_NOEX -norunpath -xnolib"
elif test "x$TOOLCHAIN_TYPE" = xxlc; then
- CFLAGS_JDK="$CFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
- CXXFLAGS_JDK="$CXXFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_REENTRANT -D__STDC_FORMAT_MACROS"
+ $2CFLAGS_JDK="[$]$2CFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
+ $2CXXFLAGS_JDK="[$]$2CXXFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK \
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS [$]$2COMMON_CCXXFLAGS_JDK \
-MD -Zc:wchar_t- -W3 -wd4800 \
-DWIN32_LEAN_AND_MEAN \
-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE \
-D_WINSOCK_DEPRECATED_NO_WARNINGS \
-DWIN32 -DIAL"
- if test "x$OPENJDK_TARGET_CPU" = xx86_64; then
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_AMD64_ -Damd64"
+ if test "x$OPENJDK_$1_CPU" = xx86_64; then
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_AMD64_ -Damd64"
else
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_X86_ -Dx86"
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_X86_ -Dx86"
fi
# If building with Visual Studio 2010, we can still use _STATIC_CPPLIB to
# avoid bundling msvcpNNN.dll. Doesn't work with newer versions of visual
# studio.
if test "x$TOOLCHAIN_VERSION" = "x2010"; then
STATIC_CPPLIB_FLAGS="-D_STATIC_CPPLIB -D_DISABLE_DEPRECATE_STATIC_CPPLIB"
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK $STATIC_CPPLIB_FLAGS"
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK $STATIC_CPPLIB_FLAGS"
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS $STATIC_CPPLIB_FLAGS"
fi
fi
@@ -688,8 +836,8 @@
# Adjust flags according to debug level.
case $DEBUG_LEVEL in
fastdebug | slowdebug )
- CFLAGS_JDK="$CFLAGS_JDK $CFLAGS_DEBUG_SYMBOLS $CFLAGS_DEBUG_OPTIONS"
- CXXFLAGS_JDK="$CXXFLAGS_JDK $CXXFLAGS_DEBUG_SYMBOLS $CXXFLAGS_DEBUG_OPTIONS"
+ $2CFLAGS_JDK="[$]$2CFLAGS_JDK $CFLAGS_DEBUG_SYMBOLS $CFLAGS_DEBUG_OPTIONS"
+ $2CXXFLAGS_JDK="[$]$2CXXFLAGS_JDK $CXXFLAGS_DEBUG_SYMBOLS $CXXFLAGS_DEBUG_OPTIONS"
JAVAC_FLAGS="$JAVAC_FLAGS -g"
;;
release )
@@ -703,58 +851,142 @@
# -D is universally accepted.
# Setup endianness
- if test "x$OPENJDK_TARGET_CPU_ENDIAN" = xlittle; then
+ if test "x$OPENJDK_$1_CPU_ENDIAN" = xlittle; then
# The macro _LITTLE_ENDIAN needs to be defined the same to avoid the
# Sun C compiler warning message: warning: macro redefined: _LITTLE_ENDIAN
# (The Solaris X86 system defines this in file /usr/include/sys/isa_defs.h).
# Note: -Dmacro is the same as #define macro 1
# -Dmacro= is the same as #define macro
- if test "x$OPENJDK_TARGET_OS" = xsolaris; then
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_LITTLE_ENDIAN="
+ if test "x$OPENJDK_$1_OS" = xsolaris; then
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_LITTLE_ENDIAN="
else
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_LITTLE_ENDIAN"
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_LITTLE_ENDIAN"
fi
else
# Same goes for _BIG_ENDIAN. Do we really need to set *ENDIAN on Solaris if they
# are defined in the system?
- if test "x$OPENJDK_TARGET_OS" = xsolaris; then
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_BIG_ENDIAN="
+ if test "x$OPENJDK_$1_OS" = xsolaris; then
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_BIG_ENDIAN="
else
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_BIG_ENDIAN"
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_BIG_ENDIAN"
fi
fi
# Setup target OS define. Use OS target name but in upper case.
- OPENJDK_TARGET_OS_UPPERCASE=`$ECHO $OPENJDK_TARGET_OS | $TR 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D$OPENJDK_TARGET_OS_UPPERCASE"
+ OPENJDK_$1_OS_UPPERCASE=`$ECHO $OPENJDK_$1_OS | $TR 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D$OPENJDK_$1_OS_UPPERCASE"
# Setup target CPU
- OPENJDK_TARGET_CCXXFLAGS_JDK="$OPENJDK_TARGET_CCXXFLAGS_JDK \
- $ADD_LP64 \
- -DARCH='\"$OPENJDK_TARGET_CPU_LEGACY\"' -D$OPENJDK_TARGET_CPU_LEGACY"
- OPENJDK_BUILD_CCXXFLAGS_JDK="$OPENJDK_BUILD_CCXXFLAGS_JDK \
- $OPENJDK_BUILD_ADD_LP64 \
- -DARCH='\"$OPENJDK_BUILD_CPU_LEGACY\"' -D$OPENJDK_BUILD_CPU_LEGACY"
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK \
+ $OPENJDK_$1_ADD_LP64 \
+ -DARCH='\"$OPENJDK_$1_CPU_LEGACY\"' -D$OPENJDK_$1_CPU_LEGACY"
# Setup debug/release defines
if test "x$DEBUG_LEVEL" = xrelease; then
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DNDEBUG"
- if test "x$OPENJDK_TARGET_OS" = xsolaris; then
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DTRIMMED"
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -DNDEBUG"
+ if test "x$OPENJDK_$1_OS" = xsolaris; then
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -DTRIMMED"
fi
else
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DDEBUG"
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -DDEBUG"
fi
# Set some additional per-OS defines.
- if test "x$OPENJDK_TARGET_OS" = xmacosx; then
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
- elif test "x$OPENJDK_TARGET_OS" = xbsd; then
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE"
+ if test "x$OPENJDK_$1_OS" = xlinux; then
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -DLINUX"
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -pipe -fPIC -fno-rtti -fno-exceptions \
+ -fvisibility=hidden -fno-strict-aliasing -fno-omit-frame-pointer"
+ elif test "x$OPENJDK_$1_OS" = xsolaris; then
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -DSOLARIS"
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -template=no%extdef -features=no%split_init \
+ -D_Crun_inline_placement -library=%none -KPIC -mt -xwe -features=no%except"
+ elif test "x$OPENJDK_$1_OS" = xmacosx; then
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_ALLBSD_SOURCE"
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_DARWIN_C_SOURCE -D_XOPEN_SOURCE"
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -fno-rtti -fno-exceptions -fvisibility=hidden \
+ -mno-omit-leaf-frame-pointer -mstack-alignment=16 -pipe -fno-strict-aliasing \
+ -DMAC_OS_X_VERSION_MAX_ALLOWED=1070 -mmacosx-version-min=10.7.0 \
+ -fno-omit-frame-pointer"
+ elif test "x$OPENJDK_$1_OS" = xaix; then
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -DAIX"
+ # We may need '-qminimaltoc' or '-qpic=large -bbigtoc' if the TOC overflows.
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -qtune=balanced -qhot=level=1 -qinline \
+ -qinlglue -qalias=noansi -qstrict -qtls=default -qlanglvl=c99vla \
+ -qlanglvl=noredefmac -qnortti -qnoeh -qignerrno"
+ elif test "x$OPENJDK_$1_OS" = xbsd; then
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE"
+ elif test "x$OPENJDK_$1_OS" = xwindows; then
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_WINDOWS -DWIN32 -D_JNI_IMPLEMENTATION_"
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -nologo -W3 -MD -MP"
+ fi
+
+ # Set some additional per-CPU defines.
+ if test "x$OPENJDK_$1_OS-$OPENJDK_$1_CPU" = xwindows-x86; then
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -arch:IA32"
+ elif test "x$OPENJDK_$1_CPU" = xsparcv9; then
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -xarch=sparc"
+ elif test "x$OPENJDK_$1_CPU" = xppc64; then
+ if test "x$OPENJDK_$1_OS" = xlinux; then
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -minsert-sched-nops=regroup_exact -mno-multiple -mno-string"
+ # fixes `relocation truncated to fit' error for gcc 4.1.
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -mminimal-toc"
+ # Use ppc64 instructions, but schedule for power5
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -mcpu=powerpc64 -mtune=power5"
+ elif test "x$OPENJDK_$1_OS" = xaix; then
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -qarch=ppc64"
+ fi
+ elif test "x$OPENJDK_$1_CPU" = xppc64le; then
+ if test "x$OPENJDK_$1_OS" = xlinux; then
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -minsert-sched-nops=regroup_exact -mno-multiple -mno-string"
+ # Little endian machine uses ELFv2 ABI.
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -DABI_ELFv2"
+ # Use Power8, this is the first CPU to support PPC64 LE with ELFv2 ABI.
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -mcpu=power7 -mtune=power8"
+ fi
+ fi
+
+ if test "x$OPENJDK_$1_CPU_ENDIAN" = xlittle; then
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -DVM_LITTLE_ENDIAN"
+ fi
+
+ if test "x$OPENJDK_$1_CPU_BITS" = x64; then
+ if test "x$OPENJDK_$1_OS" != xsolaris && test "x$OPENJDK_$1_OS" != xaix; then
+ # Solaris does not have _LP64=1 in the old build.
+ # xlc on AIX defines _LP64=1 by default and issues a warning if we redefine it.
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_LP64=1"
+ fi
+ fi
+
+ # Set $2JVM_CFLAGS warning handling
+ if test "x$OPENJDK_$1_OS" = xlinux; then
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wpointer-arith -Wsign-compare -Wunused-function \
+ -Wunused-value -Woverloaded-virtual"
+
+ if test "x$TOOLCHAIN_TYPE" = xgcc; then
+ TOOLCHAIN_CHECK_COMPILER_VERSION(VERSION: [4.8],
+ IF_AT_LEAST: [
+ # These flags either do not work or give spurious warnings prior to gcc 4.8.
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wno-format-zero-length -Wtype-limits -Wuninitialized"
+ ]
+ )
+ fi
+ if ! HOTSPOT_CHECK_JVM_VARIANT(zero) && ! HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
+ # Non-zero builds have stricter warnings
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wreturn-type -Wundef -Wformat=2"
+ else
+ if test "x$TOOLCHAIN_TYPE" = xclang; then
+ # Some versions of llvm do not like -Wundef
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wno-undef"
+ fi
+ fi
+ elif test "x$OPENJDK_$1_OS" = xmacosx; then
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wno-deprecated -Wpointer-arith \
+ -Wsign-compare -Wundef -Wunused-function -Wformat=2"
fi
# Additional macosx handling
- if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+ if test "x$OPENJDK_$1_OS" = xmacosx; then
# Setting these parameters makes it an error to link to macosx APIs that are
# newer than the given OS version and makes the linked binaries compatible
# even if built on a newer version of the OS.
@@ -765,108 +997,112 @@
# The macro takes the version with no dots, ex: 1070
# Let the flags variables get resolved in make for easier override on make
# command line.
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DMAC_OS_X_VERSION_MAX_ALLOWED=\$(subst .,,\$(MACOSX_VERSION_MIN)) -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
- LDFLAGS_JDK="$LDFLAGS_JDK -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -DMAC_OS_X_VERSION_MAX_ALLOWED=\$(subst .,,\$(MACOSX_VERSION_MIN)) -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
+ $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
fi
# Setup some hard coded includes
- COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK \
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK \
-I${JDK_TOPDIR}/src/java.base/share/native/include \
- -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS/native/include \
- -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/include \
+ -I${JDK_TOPDIR}/src/java.base/$OPENJDK_$1_OS/native/include \
+ -I${JDK_TOPDIR}/src/java.base/$OPENJDK_$1_OS_TYPE/native/include \
-I${JDK_TOPDIR}/src/java.base/share/native/libjava \
- -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/libjava"
+ -I${JDK_TOPDIR}/src/java.base/$OPENJDK_$1_OS_TYPE/native/libjava"
# The shared libraries are compiled using the picflag.
- CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
- $CFLAGS_JDK $EXTRA_CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
- CXXFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
- $CXXFLAGS_JDK $EXTRA_CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
+ $2CFLAGS_JDKLIB="[$]$2COMMON_CCXXFLAGS_JDK \
+ [$]$2CFLAGS_JDK [$]$2EXTRA_CFLAGS_JDK $PICFLAG [$]$2CFLAGS_JDKLIB_EXTRA"
+ $2CXXFLAGS_JDKLIB="[$]$2COMMON_CCXXFLAGS_JDK \
+ [$]$2CXXFLAGS_JDK [$]$2EXTRA_CXXFLAGS_JDK $PICFLAG [$]$2CXXFLAGS_JDKLIB_EXTRA"
# Executable flags
- CFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
- $CFLAGS_JDK $EXTRA_CFLAGS_JDK"
- CXXFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
- $CXXFLAGS_JDK $EXTRA_CXXFLAGS_JDK"
-
- # The corresponding flags for building for the build platform. This is still an
- # approximation, we only need something that runs on this machine when cross
- # compiling the product.
- OPENJDK_BUILD_CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK \
- $PICFLAG $CFLAGS_JDKLIB_EXTRA"
- OPENJDK_BUILD_CXXFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK \
- $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
- OPENJDK_BUILD_CFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK"
- OPENJDK_BUILD_CXXFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK"
+ $2CFLAGS_JDKEXE="[$]$2COMMON_CCXXFLAGS_JDK [$]$2CFLAGS_JDK [$]$2EXTRA_CFLAGS_JDK"
+ $2CXXFLAGS_JDKEXE="[$]$2COMMON_CCXXFLAGS_JDK [$]$2CXXFLAGS_JDK [$]$2EXTRA_CXXFLAGS_JDK"
- AC_SUBST(CFLAGS_JDKLIB)
- AC_SUBST(CFLAGS_JDKEXE)
- AC_SUBST(CXXFLAGS_JDKLIB)
- AC_SUBST(CXXFLAGS_JDKEXE)
- AC_SUBST(OPENJDK_BUILD_CFLAGS_JDKLIB)
- AC_SUBST(OPENJDK_BUILD_CFLAGS_JDKEXE)
- AC_SUBST(OPENJDK_BUILD_CXXFLAGS_JDKLIB)
- AC_SUBST(OPENJDK_BUILD_CXXFLAGS_JDKEXE)
-
- # Flags for compiling test libraries
- CFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
- CXXFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
-
- # Flags for compiling test executables
- CFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK"
- CXXFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK"
-
- AC_SUBST(CFLAGS_TESTLIB)
- AC_SUBST(CFLAGS_TESTEXE)
- AC_SUBST(CXXFLAGS_TESTLIB)
- AC_SUBST(CXXFLAGS_TESTEXE)
+ AC_SUBST($2CFLAGS_JDKLIB)
+ AC_SUBST($2CFLAGS_JDKEXE)
+ AC_SUBST($2CXXFLAGS_JDKLIB)
+ AC_SUBST($2CXXFLAGS_JDKEXE)
# Setup LDFLAGS et al.
#
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
LDFLAGS_MICROSOFT="-nologo -opt:ref"
- LDFLAGS_JDK="$LDFLAGS_JDK $LDFLAGS_MICROSOFT -incremental:no"
- if test "x$OPENJDK_TARGET_CPU_BITS" = "x32"; then
+ $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK $LDFLAGS_MICROSOFT -incremental:no"
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_MICROSOFT -opt:icf,8 -subsystem:windows -base:0x8000000"
+ if test "x$OPENJDK_$1_CPU_BITS" = "x32"; then
LDFLAGS_SAFESH="-safeseh"
- LDFLAGS_JDK="$LDFLAGS_JDK $LDFLAGS_SAFESH"
+ $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK $LDFLAGS_SAFESH"
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_SAFESH"
+ # NOTE: Old build added -machine. Probably not needed.
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -machine:I386"
+ else
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -machine:AMD64"
+ fi
+ elif test "x$TOOLCHAIN_TYPE" = xclang; then
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -mno-omit-leaf-frame-pointer -mstack-alignment=16 -stdlib=libstdc++ -fPIC"
+ if test "x$OPENJDK_$1_OS" = xmacosx; then
+ # FIXME: We should really generalize SET_SHARED_LIBRARY_ORIGIN instead.
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
fi
elif test "x$TOOLCHAIN_TYPE" = xgcc; then
# If this is a --hash-style=gnu system, use --hash-style=both, why?
# We have previously set HAS_GNU_HASH if this is the case
if test -n "$HAS_GNU_HASH"; then
- LDFLAGS_HASH_STYLE="-Wl,--hash-style=both"
- LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_HASH_STYLE"
+ $2LDFLAGS_HASH_STYLE="-Wl,--hash-style=both"
+ $2LDFLAGS_JDK="${$2LDFLAGS_JDK} [$]$2LDFLAGS_HASH_STYLE"
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS [$]$2LDFLAGS_HASH_STYLE"
fi
- if test "x$OPENJDK_TARGET_OS" = xlinux; then
+ if test "x$OPENJDK_$1_OS" = xmacosx; then
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
+ fi
+ if test "x$OPENJDK_$1_OS" = xlinux; then
# And since we now know that the linker is gnu, then add -z defs, to forbid
# undefined symbols in object files.
LDFLAGS_NO_UNDEF_SYM="-Wl,-z,defs"
- LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_NO_UNDEF_SYM"
+ $2LDFLAGS_JDK="${$2LDFLAGS_JDK} $LDFLAGS_NO_UNDEF_SYM"
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_NO_UNDEF_SYM"
+ LDFLAGS_NO_EXEC_STACK="-Wl,-z,noexecstack"
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_NO_EXEC_STACK"
+ if test "x$OPENJDK_$1_CPU" = xx86; then
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -march=i586"
+ fi
case $DEBUG_LEVEL in
release )
# tell linker to optimize libraries.
# Should this be supplied to the OSS linker as well?
LDFLAGS_DEBUGLEVEL_release="-Wl,-O1"
- LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_DEBUGLEVEL_release"
+ $2LDFLAGS_JDK="${$2LDFLAGS_JDK} $LDFLAGS_DEBUGLEVEL_release"
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_DEBUGLEVEL_release"
+ if test "x$HAS_LINKER_RELRO" = "xtrue"; then
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LINKER_RELRO_FLAG"
+ fi
;;
slowdebug )
+ # Hotspot always let the linker optimize
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -Wl,-O1"
if test "x$HAS_LINKER_NOW" = "xtrue"; then
# do relocations at load
- LDFLAGS_JDK="$LDFLAGS_JDK $LINKER_NOW_FLAG"
- LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LINKER_NOW_FLAG"
+ $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK $LINKER_NOW_FLAG"
+ $2LDFLAGS_CXX_JDK="[$]$2LDFLAGS_CXX_JDK $LINKER_NOW_FLAG"
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LINKER_NOW_FLAG"
fi
if test "x$HAS_LINKER_RELRO" = "xtrue"; then
# mark relocations read only
- LDFLAGS_JDK="$LDFLAGS_JDK $LINKER_RELRO_FLAG"
- LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+ $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK $LINKER_RELRO_FLAG"
+ $2LDFLAGS_CXX_JDK="[$]$2LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LINKER_RELRO_FLAG"
fi
;;
fastdebug )
+ # Hotspot always let the linker optimize
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -Wl,-O1"
if test "x$HAS_LINKER_RELRO" = "xtrue"; then
# mark relocations read only
- LDFLAGS_JDK="$LDFLAGS_JDK $LINKER_RELRO_FLAG"
- LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+ $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK $LINKER_RELRO_FLAG"
+ $2LDFLAGS_CXX_JDK="[$]$2LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LINKER_RELRO_FLAG"
fi
;;
* )
@@ -876,85 +1112,122 @@
fi
elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
LDFLAGS_SOLSTUDIO="-Wl,-z,defs"
- LDFLAGS_JDK="$LDFLAGS_JDK $LDFLAGS_SOLSTUDIO -xildoff -ztext"
+ $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK $LDFLAGS_SOLSTUDIO -xildoff -ztext"
LDFLAGS_CXX_SOLSTUDIO="-norunpath"
- LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LDFLAGS_CXX_SOLSTUDIO -xnolib"
+ $2LDFLAGS_CXX_JDK="[$]$2LDFLAGS_CXX_JDK $LDFLAGS_CXX_SOLSTUDIO -xnolib"
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_SOLSTUDIO -library=%none -mt $LDFLAGS_CXX_SOLSTUDIO -z noversion"
+ if test "x$OPENJDK_$1_CPU_ARCH" = "xsparc"; then
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -xarch=sparc"
+ fi
elif test "x$TOOLCHAIN_TYPE" = xxlc; then
LDFLAGS_XLC="-b64 -brtl -bnolibpath -bexpall -bernotok"
- LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_XLC"
+ $2LDFLAGS_JDK="${$2LDFLAGS_JDK} $LDFLAGS_XLC"
+ $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_XLC"
fi
# Customize LDFLAGS for executables
- LDFLAGS_JDKEXE="${LDFLAGS_JDK}"
+ $2LDFLAGS_JDKEXE="${$2LDFLAGS_JDK}"
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
- if test "x$OPENJDK_TARGET_CPU_BITS" = "x64"; then
+ if test "x$OPENJDK_$1_CPU_BITS" = "x64"; then
LDFLAGS_STACK_SIZE=1048576
else
LDFLAGS_STACK_SIZE=327680
fi
- LDFLAGS_JDKEXE="${LDFLAGS_JDKEXE} /STACK:$LDFLAGS_STACK_SIZE"
- elif test "x$OPENJDK_TARGET_OS" = xlinux; then
- LDFLAGS_JDKEXE="$LDFLAGS_JDKEXE -Wl,--allow-shlib-undefined"
+ $2LDFLAGS_JDKEXE="${$2LDFLAGS_JDKEXE} /STACK:$LDFLAGS_STACK_SIZE"
+ elif test "x$OPENJDK_$1_OS" = xlinux; then
+ $2LDFLAGS_JDKEXE="[$]$2LDFLAGS_JDKEXE -Wl,--allow-shlib-undefined"
fi
- OPENJDK_BUILD_LDFLAGS_JDKEXE="${LDFLAGS_JDKEXE}"
- LDFLAGS_JDKEXE="${LDFLAGS_JDKEXE} ${EXTRA_LDFLAGS_JDK}"
+ $2LDFLAGS_JDKEXE="${$2LDFLAGS_JDKEXE} ${$2EXTRA_LDFLAGS_JDK}"
# Customize LDFLAGS for libs
- LDFLAGS_JDKLIB="${LDFLAGS_JDK}"
+ $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDK}"
- LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} ${SHARED_LIBRARY_FLAGS}"
+ $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} ${SHARED_LIBRARY_FLAGS}"
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
- LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} \
+ $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} \
-libpath:${OUTPUT_ROOT}/support/modules_libs/java.base"
- JDKLIB_LIBS=""
+ $2JDKLIB_LIBS=""
else
- LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} \
- -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)"
+ $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} \
+ -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)"
+ if test "x$1" = "xTARGET"; then
# On some platforms (mac) the linker warns about non existing -L dirs.
# Add server first if available. Linking aginst client does not always produce the same results.
- # Only add client dir if client is being built. Add minimal (note not minimal1) if only building minimal1.
+ # Only add client/minimal dir if client/minimal is being built.
# Default to server for other variants.
- if test "x$JVM_VARIANT_SERVER" = xtrue; then
- LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
- elif test "x$JVM_VARIANT_CLIENT" = xtrue; then
- LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/client"
- elif test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
- LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/minimal"
+ if HOTSPOT_CHECK_JVM_VARIANT(server); then
+ $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/server"
+ elif HOTSPOT_CHECK_JVM_VARIANT(client); then
+ $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/client"
+ elif HOTSPOT_CHECK_JVM_VARIANT(minimal); then
+ $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/minimal"
else
- LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
+ $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/server"
+ fi
+ elif test "x$1" = "xBUILD"; then
+ # When building a buildjdk, it's always only the server variant
+ $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} \
+ -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/server"
fi
- JDKLIB_LIBS="-ljava -ljvm"
+ $2JDKLIB_LIBS="-ljava -ljvm"
if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
- JDKLIB_LIBS="$JDKLIB_LIBS -lc"
+ $2JDKLIB_LIBS="[$]$2JDKLIB_LIBS -lc"
fi
- # When building a buildjdk, it's always only the server variant
- OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} \
- -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
fi
- OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} ${LDFLAGS_JDKLIB}"
- LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} ${EXTRA_LDFLAGS_JDK}"
+ # Set $2JVM_LIBS (per os)
+ if test "x$OPENJDK_$1_OS" = xlinux; then
+ $2JVM_LIBS="[$]$2JVM_LIBS -lm -ldl -lpthread"
+ elif test "x$OPENJDK_$1_OS" = xsolaris; then
+ # FIXME: This hard-coded path is not really proper.
+ if test "x$OPENJDK_$1_CPU" = xx86_64; then
+ $2SOLARIS_LIBM_LIBS="/usr/lib/amd64/libm.so.1"
+ elif test "x$OPENJDK_$1_CPU" = xsparcv9; then
+ $2SOLARIS_LIBM_LIBS="/usr/lib/sparcv9/libm.so.1"
+ fi
+ $2JVM_LIBS="[$]$2JVM_LIBS -lsocket -lsched -ldl $SOLARIS_LIBM_LIBS -lCrun \
+ -lthread -ldoor -lc -ldemangle -lnsl -lkstat -lrt"
+ elif test "x$OPENJDK_$1_OS" = xmacosx; then
+ $2JVM_LIBS="[$]$2JVM_LIBS -lm"
+ elif test "x$OPENJDK_$1_OS" = xaix; then
+ $2JVM_LIBS="[$]$2JVM_LIBS -Wl,-lC_r -lm -ldl -lpthread"
+ elif test "x$OPENJDK_$1_OS" = xbsd; then
+ $2JVM_LIBS="[$]$2JVM_LIBS -lm"
+ elif test "x$OPENJDK_$1_OS" = xwindows; then
+ $2JVM_LIBS="[$]$2JVM_LIBS kernel32.lib user32.lib gdi32.lib winspool.lib \
+ comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib \
+ wsock32.lib winmm.lib version.lib psapi.lib"
+ fi
- AC_SUBST(LDFLAGS_JDKLIB)
- AC_SUBST(LDFLAGS_JDKEXE)
- AC_SUBST(OPENJDK_BUILD_LDFLAGS_JDKLIB)
- AC_SUBST(OPENJDK_BUILD_LDFLAGS_JDKEXE)
- AC_SUBST(JDKLIB_LIBS)
- AC_SUBST(JDKEXE_LIBS)
- AC_SUBST(LDFLAGS_CXX_JDK)
- AC_SUBST(LDFLAGS_HASH_STYLE)
+ # Set $2JVM_ASFLAGS
+ if test "x$OPENJDK_$1_OS" = xlinux; then
+ if test "x$OPENJDK_$1_CPU" = xx86; then
+ $2JVM_ASFLAGS="[$]$2JVM_ASFLAGS -march=i586"
+ fi
+ elif test "x$OPENJDK_$1_OS" = xmacosx; then
+ $2JVM_ASFLAGS="[$]$2JVM_ASFLAGS -x assembler-with-cpp -mno-omit-leaf-frame-pointer -mstack-alignment=16"
+ fi
+
+ $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} ${$2EXTRA_LDFLAGS_JDK}"
- LDFLAGS_TESTLIB="$LDFLAGS_JDKLIB"
- LDFLAGS_TESTEXE="$LDFLAGS_JDKEXE"
+ AC_SUBST($2LDFLAGS_JDKLIB)
+ AC_SUBST($2LDFLAGS_JDKEXE)
+ AC_SUBST($2JDKLIB_LIBS)
+ AC_SUBST($2JDKEXE_LIBS)
+ AC_SUBST($2LDFLAGS_CXX_JDK)
+ AC_SUBST($2LDFLAGS_HASH_STYLE)
- AC_SUBST(LDFLAGS_TESTLIB)
- AC_SUBST(LDFLAGS_TESTEXE)
+ AC_SUBST($2JVM_CFLAGS)
+ AC_SUBST($2JVM_LDFLAGS)
+ AC_SUBST($2JVM_ASFLAGS)
+ AC_SUBST($2JVM_LIBS)
+
])
# FLAGS_C_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [ARGUMENT], IF_TRUE: [RUN-IF-TRUE],
--- a/common/autoconf/generated-configure.sh Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/generated-configure.sh Thu Apr 28 23:08:17 2016 -0700
@@ -652,7 +652,21 @@
NUM_CORES
BUILD_FAILURE_HANDLER
ENABLE_INTREE_EC
+JVM_VARIANT_CORE
+JVM_VARIANT_ZEROSHARK
+JVM_VARIANT_ZERO
+JVM_VARIANT_HOTSPOT
+JVM_VARIANT_MINIMAL1
+JVM_VARIANT_CLIENT
+JVM_VARIANT_SERVER
+JVM_VARIANTS_COMMA
+TEST_IN_BUILD
HOTSPOT_MAKE_ARGS
+MACOSX_UNIVERSAL
+DEBUG_CLASSFILES
+FASTDEBUG
+VARIANT
+USE_NEW_HOTSPOT_BUILD
LIBZIP_CAN_USE_MMAP
LIBDL
LIBM
@@ -688,6 +702,15 @@
STATIC_CXX_SETTING
FIXPATH_DETACH_FLAG
FIXPATH
+VALID_JVM_FEATURES
+JVM_FEATURES_custom
+JVM_FEATURES_zeroshark
+JVM_FEATURES_zero
+JVM_FEATURES_minimal
+JVM_FEATURES_core
+JVM_FEATURES_client
+JVM_FEATURES_server
+INCLUDE_DTRACE
GCOV_ENABLED
STRIP_POLICY
DEBUG_BINARIES
@@ -703,22 +726,35 @@
ZERO_ARCHFLAG
LDFLAGS_TESTEXE
LDFLAGS_TESTLIB
+CXXFLAGS_TESTEXE
+CXXFLAGS_TESTLIB
+CFLAGS_TESTEXE
+CFLAGS_TESTLIB
+OPENJDK_BUILD_JVM_LIBS
+OPENJDK_BUILD_JVM_ASFLAGS
+OPENJDK_BUILD_JVM_LDFLAGS
+OPENJDK_BUILD_JVM_CFLAGS
+OPENJDK_BUILD_LDFLAGS_HASH_STYLE
+OPENJDK_BUILD_LDFLAGS_CXX_JDK
+OPENJDK_BUILD_JDKEXE_LIBS
+OPENJDK_BUILD_JDKLIB_LIBS
+OPENJDK_BUILD_LDFLAGS_JDKEXE
+OPENJDK_BUILD_LDFLAGS_JDKLIB
+OPENJDK_BUILD_CXXFLAGS_JDKEXE
+OPENJDK_BUILD_CXXFLAGS_JDKLIB
+OPENJDK_BUILD_CFLAGS_JDKEXE
+OPENJDK_BUILD_CFLAGS_JDKLIB
+OPENJDK_BUILD_CXXSTD_CXXFLAG
+JVM_LIBS
+JVM_ASFLAGS
+JVM_LDFLAGS
+JVM_CFLAGS
LDFLAGS_HASH_STYLE
LDFLAGS_CXX_JDK
JDKEXE_LIBS
JDKLIB_LIBS
-OPENJDK_BUILD_LDFLAGS_JDKEXE
-OPENJDK_BUILD_LDFLAGS_JDKLIB
LDFLAGS_JDKEXE
LDFLAGS_JDKLIB
-CXXFLAGS_TESTEXE
-CXXFLAGS_TESTLIB
-CFLAGS_TESTEXE
-CFLAGS_TESTLIB
-OPENJDK_BUILD_CXXFLAGS_JDKEXE
-OPENJDK_BUILD_CXXFLAGS_JDKLIB
-OPENJDK_BUILD_CFLAGS_JDKEXE
-OPENJDK_BUILD_CFLAGS_JDKLIB
CXXFLAGS_JDKEXE
CXXFLAGS_JDKLIB
CFLAGS_JDKEXE
@@ -727,16 +763,21 @@
NO_LIFETIME_DSE_CFLAG
NO_NULL_POINTER_CHECK_CFLAG
CXXSTD_CXXFLAG
+CXX_O_FLAG_SIZE
CXX_O_FLAG_NONE
CXX_O_FLAG_DEBUG
CXX_O_FLAG_NORM
CXX_O_FLAG_HI
CXX_O_FLAG_HIGHEST
+CXX_O_FLAG_HIGHEST_JVM
+C_O_FLAG_SIZE
C_O_FLAG_NONE
C_O_FLAG_DEBUG
C_O_FLAG_NORM
C_O_FLAG_HI
C_O_FLAG_HIGHEST
+C_O_FLAG_HIGHEST_JVM
+JVM_CFLAGS_SYMBOLS
CXXFLAGS_DEBUG_SYMBOLS
CFLAGS_DEBUG_SYMBOLS
CXX_FLAG_DEPS
@@ -748,6 +789,7 @@
SET_EXECUTABLE_ORIGIN
CXX_FLAG_REORDER
C_FLAG_REORDER
+JVM_RCFLAGS
RC_FLAGS
AR_OUT_OPTION
LD_OUT_OPTION
@@ -760,6 +802,7 @@
COMPILER_TARGET_BITS_FLAG
JT_HOME
JTREGEXE
+HOTSPOT_TOOLCHAIN_TYPE
USING_BROKEN_SUSE_LD
PACKAGE_PATH
USE_CLANG
@@ -822,6 +865,9 @@
CYGWIN_LINK
SYSROOT_LDFLAGS
SYSROOT_CFLAGS
+EXTRA_LDFLAGS
+EXTRA_CXXFLAGS
+EXTRA_CFLAGS
LEGACY_EXTRA_LDFLAGS
LEGACY_EXTRA_CXXFLAGS
LEGACY_EXTRA_CFLAGS
@@ -878,12 +924,12 @@
VERSION_MAJOR
MACOSX_BUNDLE_ID_BASE
MACOSX_BUNDLE_NAME_BASE
+HOTSPOT_VM_DISTRO
COMPANY_NAME
JDK_RC_PLATFORM_NAME
PRODUCT_SUFFIX
PRODUCT_NAME
LAUNCHER_NAME
-TEST_IN_BUILD
JLINK_KEEP_PACKAGED_MODULES
COPYRIGHT_YEAR
COMPRESS_JARS
@@ -905,6 +951,7 @@
DSYMUTIL
IS_GNU_TIME
PATCH
+DTRACE
TIME
STAT
HG
@@ -928,20 +975,10 @@
SPEC
SDKROOT
XCODEBUILD
-BUILD_VARIANT_RELEASE
-DEBUG_CLASSFILES
-FASTDEBUG
-VARIANT
+VALID_JVM_VARIANTS
+JVM_VARIANTS
DEBUG_LEVEL
-MACOSX_UNIVERSAL
-JVM_VARIANT_CORE
-JVM_VARIANT_ZEROSHARK
-JVM_VARIANT_ZERO
-JVM_VARIANT_MINIMAL1
-JVM_VARIANT_CLIENT
-JVM_VARIANT_SERVER
-JVM_VARIANTS
-JVM_INTERPRETER
+HOTSPOT_DEBUG_LEVEL
JDK_VARIANT
SET_OPENJDK
USERNAME
@@ -950,16 +987,29 @@
TOPDIR
PATH_SEP
ZERO_ARCHDEF
+HOTSPOT_BUILD_CPU_DEFINE
+HOTSPOT_BUILD_CPU_ARCH
+HOTSPOT_BUILD_CPU
+HOTSPOT_BUILD_OS_TYPE
+HOTSPOT_BUILD_OS
+OPENJDK_BUILD_OS_EXPORT_DIR
+OPENJDK_BUILD_CPU_JLI_CFLAGS
+OPENJDK_BUILD_CPU_OSARCH
+OPENJDK_BUILD_CPU_ISADIR
+OPENJDK_BUILD_CPU_LIBDIR
+OPENJDK_BUILD_CPU_LEGACY_LIB
+OPENJDK_BUILD_CPU_LEGACY
+HOTSPOT_TARGET_CPU_DEFINE
+HOTSPOT_TARGET_CPU_ARCH
+HOTSPOT_TARGET_CPU
+HOTSPOT_TARGET_OS_TYPE
+HOTSPOT_TARGET_OS
DEFINE_CROSS_COMPILE_ARCH
LP64
OPENJDK_TARGET_OS_EXPORT_DIR
-OPENJDK_BUILD_CPU_JLI_CFLAGS
OPENJDK_TARGET_CPU_JLI_CFLAGS
OPENJDK_TARGET_CPU_OSARCH
OPENJDK_TARGET_CPU_ISADIR
-OPENJDK_BUILD_CPU_LIBDIR
-OPENJDK_BUILD_CPU_LEGACY_LIB
-OPENJDK_BUILD_CPU_LEGACY
OPENJDK_TARGET_CPU_LIBDIR
OPENJDK_TARGET_CPU_LEGACY_LIB
OPENJDK_TARGET_CPU_LEGACY
@@ -1089,10 +1139,9 @@
enable_openjdk_only
with_custom_make_dir
with_jdk_variant
-with_jvm_interpreter
-with_jvm_variants
enable_debug
with_debug_level
+with_jvm_variants
with_devkit
with_sys_root
with_sysroot
@@ -1108,7 +1157,6 @@
enable_unlimited_crypto
with_copyright_year
enable_keep_packaged_modules
-enable_hotspot_test_in_build
with_milestone
with_update_version
with_user_release_suffix
@@ -1148,6 +1196,9 @@
enable_debug_symbols
enable_zip_debug_info
enable_native_coverage
+enable_dtrace
+with_jvm_features
+with_jvm_interpreter
with_stdc__lib
with_msvcr_dll
with_msvcp_dll
@@ -1174,6 +1225,8 @@
with_dxsdk_lib
with_dxsdk_include
enable_jtreg_failure_handler
+enable_new_hotspot_build
+enable_hotspot_test_in_build
with_num_cores
with_memory_size
with_jobs
@@ -1246,6 +1299,7 @@
HG
STAT
TIME
+DTRACE
PATCH
DSYMUTIL
XATTR
@@ -1925,8 +1979,6 @@
Enable unlimited crypto policy [disabled]
--disable-keep-packaged-modules
Do not keep packaged modules in jdk image [enable]
- --enable-hotspot-test-in-build
- run the Queens test after Hotspot build [disabled]
--enable-static-build enable static library build [disabled]
--disable-warnings-as-errors
do not consider native warnings to be an error
@@ -1938,10 +1990,18 @@
--enable-native-coverage
enable native compilation with code coverage
data[disabled]
+ --enable-dtrace[=yes/no/auto]
+ enable dtrace. Default is auto, where dtrace is
+ enabled if all dependencies are present.
--disable-freetype-bundling
disable bundling of the freetype library with the
build result [enabled on Windows or when using
--with-freetype, disabled otherwise]
+ --disable-new-hotspot-build
+ disable the new hotspot build system (use the old)
+ [enabled]
+ --enable-hotspot-test-in-build
+ run the Queens test after Hotspot build [disabled]
--enable-jtreg-failure-handler
forces build of the jtreg failure handler to be
enabled, missing dependencies become fatal errors.
@@ -1967,11 +2027,11 @@
--with-custom-make-dir Deprecated. Option is kept for backwards
compatibility and is ignored
--with-jdk-variant JDK variant to build (normal) [normal]
- --with-jvm-interpreter JVM interpreter to build (template, cpp) [template]
- --with-jvm-variants JVM variants (separated by commas) to build (server,
- client, minimal1, zero, zeroshark, core) [server]
--with-debug-level set the debug level (release, fastdebug, slowdebug,
optimized) [release]
+ --with-jvm-variants JVM variants (separated by commas) to build
+ (server,client,minimal,core,zero,zeroshark,custom)
+ [server]
--with-devkit use this devkit for compilers, tools and resources
--with-sys-root alias for --with-sysroot for backwards compatability
--with-sysroot use this directory as sysroot
@@ -2058,6 +2118,10 @@
--with-native-debug-symbols
set the native debug symbol configuration (none,
internal, external, zipped) [varying]
+ --with-jvm-features additional JVM features to enable (separated by
+ comma), use '--help' to show possible values [none]
+ --with-jvm-interpreter Deprecated. Option is kept for backwards
+ compatibility and is ignored
--with-stdc++lib=<static>,<dynamic>,<default>
force linking of the C++ runtime on Linux to either
static or dynamic, default is static with dynamic as
@@ -2178,6 +2242,7 @@
HG Override default value for HG
STAT Override default value for STAT
TIME Override default value for TIME
+ DTRACE Override default value for DTRACE
PATCH Override default value for PATCH
DSYMUTIL Override default value for DSYMUTIL
XATTR Override default value for XATTR
@@ -3977,6 +4042,13 @@
+
+################################################################################
+# $1 - Either BUILD or TARGET to pick the correct OS/CPU variables to check
+# conditionals against.
+# $2 - Optional prefix for each variable defined.
+
+
# FLAGS_C_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [ARGUMENT], IF_TRUE: [RUN-IF-TRUE],
# IF_FALSE: [RUN-IF-FALSE])
# ------------------------------------------------------------
@@ -4101,6 +4173,8 @@
PKGHANDLER_COMMAND="sudo apt-get install libX11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev" ;;
ccache)
PKGHANDLER_COMMAND="sudo apt-get install ccache" ;;
+ dtrace)
+ PKGHANDLER_COMMAND="sudo apt-get install systemtap-sdt-dev" ;;
esac
}
@@ -4170,37 +4244,66 @@
# questions.
#
+# All valid JVM features, regardless of platform
+VALID_JVM_FEATURES="compiler1 compiler2 zero shark minimal dtrace jvmti jvmci \
+ fprof vm-structs jni-check services management all-gcs nmt cds static-build"
+
+# All valid JVM variants
+VALID_JVM_VARIANTS="server client minimal core zero zeroshark custom"
+
###############################################################################
-# Check which interpreter of the JVM we want to build.
-# Currently we have:
-# template: Template interpreter (the default)
-# cpp : C++ interpreter
+# Check if the specified JVM variant should be built. To be used in shell if
+# constructs, like this:
+# if HOTSPOT_CHECK_JVM_VARIANT(server); then
+#
+# Only valid to use after HOTSPOT_SETUP_JVM_VARIANTS has setup variants.
+
+# Definition kept in one line to allow inlining in if statements.
+# Additional [] needed to keep m4 from mangling shell constructs.
+
+
+###############################################################################
+# Check if the specified JVM features are explicitly enabled. To be used in
+# shell if constructs, like this:
+# if HOTSPOT_CHECK_JVM_FEATURE(jvmti); then
+#
+# Only valid to use after HOTSPOT_SETUP_JVM_FEATURES has setup features.
+
+# Definition kept in one line to allow inlining in if statements.
+# Additional [] needed to keep m4 from mangling shell constructs.
###############################################################################
-# Check which variants of the JVM that we want to build.
-# Currently we have:
-# server: normal interpreter and a C2 or tiered C1/C2 compiler
-# client: normal interpreter and C1 (no C2 compiler) (only 32-bit platforms)
-# minimal1: reduced form of client with optional VM services and features stripped out
-# zero: no machine code interpreter, no compiler
-# zeroshark: zero interpreter and shark/llvm compiler backend
-# core: interpreter only, no compiler (only works on some platforms)
-
+# Check which variants of the JVM that we want to build. Available variants are:
+# server: normal interpreter, and a tiered C1/C2 compiler
+# client: normal interpreter, and C1 (no C2 compiler)
+# minimal: reduced form of client with optional features stripped out
+# core: normal interpreter only, no compiler
+# zero: C++ based interpreter only, no compiler
+# zeroshark: C++ based interpreter, and a llvm-based compiler
+# custom: baseline JVM with no default features
+#
###############################################################################
-# Setup legacy vars/targets and new vars to deal with different debug levels.
-#
-# release: no debug information, all optimizations, no asserts.
-# optimized: no debug information, all optimizations, no asserts, HotSpot target is 'optimized'.
-# fastdebug: debug information (-g), all optimizations, all asserts
-# slowdebug: debug information (-g), no optimizations, all asserts
-#
-
-
-
-
+# Check if dtrace should be enabled and has all prerequisites present.
+#
+
+
+###############################################################################
+# Set up all JVM features for each JVM variant.
+#
+
+
+###############################################################################
+# Validate JVM features once all setup is complete, including custom setup.
+#
+
+
+###############################################################################
+# Support for old hotspot build. Remove once new hotspot build has proven
+# to work satisfactory.
+#
#
@@ -4543,7 +4646,7 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -4627,7 +4730,7 @@
#
-# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -4678,6 +4781,9 @@
#
+# $1 - Either TARGET or BUILD to setup the variables for.
+
+
#%%% Build and target systems %%%
@@ -4989,6 +5095,13 @@
TOOLCHAIN_DESCRIPTION=${!toolchain_var_name}
$PRINTF " %-10s %s\n" $toolchain "$TOOLCHAIN_DESCRIPTION"
done
+ $PRINTF "\n"
+
+ # Print available jvm features
+ $PRINTF "The following JVM features are available as arguments to --with-jvm-features.\n"
+ $PRINTF "Which are valid to use depends on the target platform.\n "
+ $PRINTF "%s " $VALID_JVM_FEATURES
+ $PRINTF "\n"
# And now exit directly
exit 0
@@ -15229,6 +15342,7 @@
+
# Also store the legacy naming of the cpu.
# Ie i586 and amd64 instead of x86 and x86_64
OPENJDK_TARGET_CPU_LEGACY="$OPENJDK_TARGET_CPU"
@@ -15259,37 +15373,6 @@
fi
- # Now do the same for OPENJDK_BUILD_CPU...
- # Also store the legacy naming of the cpu.
- # Ie i586 and amd64 instead of x86 and x86_64
- OPENJDK_BUILD_CPU_LEGACY="$OPENJDK_BUILD_CPU"
- if test "x$OPENJDK_BUILD_CPU" = xx86; then
- OPENJDK_BUILD_CPU_LEGACY="i586"
- elif test "x$OPENJDK_BUILD_OS" != xmacosx && test "x$OPENJDK_BUILD_CPU" = xx86_64; then
- # On all platforms except MacOSX replace x86_64 with amd64.
- OPENJDK_BUILD_CPU_LEGACY="amd64"
- fi
-
-
- # And the second legacy naming of the cpu.
- # Ie i386 and amd64 instead of x86 and x86_64.
- OPENJDK_BUILD_CPU_LEGACY_LIB="$OPENJDK_BUILD_CPU"
- if test "x$OPENJDK_BUILD_CPU" = xx86; then
- OPENJDK_BUILD_CPU_LEGACY_LIB="i386"
- elif test "x$OPENJDK_BUILD_CPU" = xx86_64; then
- OPENJDK_BUILD_CPU_LEGACY_LIB="amd64"
- fi
-
-
- # This is the name of the cpu (but using i386 and amd64 instead of
- # x86 and x86_64, respectively), preceeded by a /, to be used when
- # locating libraries. On macosx, it's empty, though.
- OPENJDK_BUILD_CPU_LIBDIR="/$OPENJDK_BUILD_CPU_LEGACY_LIB"
- if test "x$OPENJDK_BUILD_OS" = xmacosx; then
- OPENJDK_BUILD_CPU_LIBDIR=""
- fi
-
-
# OPENJDK_TARGET_CPU_ISADIR is normally empty. On 64-bit Solaris systems, it is set to
# /amd64 or /sparcv9. This string is appended to some library paths, like this:
# /usr/lib${OPENJDK_TARGET_CPU_ISADIR}/libexample.so
@@ -15332,6 +15415,144 @@
fi
+ if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+ OPENJDK_TARGET_OS_EXPORT_DIR=macosx
+ else
+ OPENJDK_TARGET_OS_EXPORT_DIR=${OPENJDK_TARGET_OS_TYPE}
+ fi
+
+
+ if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+ A_LP64="LP64:="
+ # -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in
+ # unpack200.exe
+ if test "x$OPENJDK_TARGET_OS" = xlinux || test "x$OPENJDK_TARGET_OS" = xmacosx; then
+ OPENJDK_TARGET_ADD_LP64="-D_LP64=1"
+ fi
+ fi
+ LP64=$A_LP64
+
+
+ if test "x$COMPILE_TYPE" = "xcross"; then
+ # FIXME: ... or should this include reduced builds..?
+ DEFINE_CROSS_COMPILE_ARCH="CROSS_COMPILE_ARCH:=$OPENJDK_TARGET_CPU_LEGACY"
+ else
+ DEFINE_CROSS_COMPILE_ARCH=""
+ fi
+
+
+ # Convert openjdk platform names to hotspot names
+
+ HOTSPOT_TARGET_OS=${OPENJDK_TARGET_OS}
+ if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+ HOTSPOT_TARGET_OS=bsd
+ fi
+
+
+ HOTSPOT_TARGET_OS_TYPE=${OPENJDK_TARGET_OS_TYPE}
+ if test "x$OPENJDK_TARGET_OS_TYPE" = xunix; then
+ HOTSPOT_TARGET_OS_TYPE=posix
+ fi
+
+
+ HOTSPOT_TARGET_CPU=${OPENJDK_TARGET_CPU}
+ if test "x$OPENJDK_TARGET_CPU" = xx86; then
+ HOTSPOT_TARGET_CPU=x86_32
+ elif test "x$OPENJDK_TARGET_CPU" = xsparcv9; then
+ HOTSPOT_TARGET_CPU=sparc
+ elif test "x$OPENJDK_TARGET_CPU" = xppc64; then
+ HOTSPOT_TARGET_CPU=ppc_64
+ elif test "x$OPENJDK_TARGET_CPU" = xppc64le; then
+ HOTSPOT_TARGET_CPU=ppc_64
+ fi
+
+
+ # This is identical with OPENJDK_*, but define anyway for consistency.
+ HOTSPOT_TARGET_CPU_ARCH=${OPENJDK_TARGET_CPU_ARCH}
+
+
+ # Setup HOTSPOT_TARGET_CPU_DEFINE
+ if test "x$OPENJDK_TARGET_CPU" = xx86; then
+ HOTSPOT_TARGET_CPU_DEFINE=IA32
+ elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+ HOTSPOT_TARGET_CPU_DEFINE=AMD64
+ elif test "x$OPENJDK_TARGET_CPU" = xsparcv9; then
+ HOTSPOT_TARGET_CPU_DEFINE=SPARC
+ elif test "x$OPENJDK_TARGET_CPU" = xaarch64; then
+ HOTSPOT_TARGET_CPU_DEFINE=AARCH64
+ elif test "x$OPENJDK_TARGET_CPU" = xppc64; then
+ HOTSPOT_TARGET_CPU_DEFINE=PPC64
+ elif test "x$OPENJDK_TARGET_CPU" = xppc64le; then
+ HOTSPOT_TARGET_CPU_DEFINE=PPC64
+
+ # The cpu defines below are for zero, we don't support them directly.
+ elif test "x$OPENJDK_TARGET_CPU" = xsparc; then
+ HOTSPOT_TARGET_CPU_DEFINE=SPARC
+ elif test "x$OPENJDK_TARGET_CPU" = xppc; then
+ HOTSPOT_TARGET_CPU_DEFINE=PPC32
+ elif test "x$OPENJDK_TARGET_CPU" = xs390; then
+ HOTSPOT_TARGET_CPU_DEFINE=S390
+ elif test "x$OPENJDK_TARGET_CPU" = ss390x; then
+ HOTSPOT_TARGET_CPU_DEFINE=S390
+ fi
+
+
+
+
+ # Also store the legacy naming of the cpu.
+ # Ie i586 and amd64 instead of x86 and x86_64
+ OPENJDK_BUILD_CPU_LEGACY="$OPENJDK_BUILD_CPU"
+ if test "x$OPENJDK_BUILD_CPU" = xx86; then
+ OPENJDK_BUILD_CPU_LEGACY="i586"
+ elif test "x$OPENJDK_BUILD_OS" != xmacosx && test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+ # On all platforms except MacOSX replace x86_64 with amd64.
+ OPENJDK_BUILD_CPU_LEGACY="amd64"
+ fi
+
+
+ # And the second legacy naming of the cpu.
+ # Ie i386 and amd64 instead of x86 and x86_64.
+ OPENJDK_BUILD_CPU_LEGACY_LIB="$OPENJDK_BUILD_CPU"
+ if test "x$OPENJDK_BUILD_CPU" = xx86; then
+ OPENJDK_BUILD_CPU_LEGACY_LIB="i386"
+ elif test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+ OPENJDK_BUILD_CPU_LEGACY_LIB="amd64"
+ fi
+
+
+ # This is the name of the cpu (but using i386 and amd64 instead of
+ # x86 and x86_64, respectively), preceeded by a /, to be used when
+ # locating libraries. On macosx, it's empty, though.
+ OPENJDK_BUILD_CPU_LIBDIR="/$OPENJDK_BUILD_CPU_LEGACY_LIB"
+ if test "x$OPENJDK_BUILD_OS" = xmacosx; then
+ OPENJDK_BUILD_CPU_LIBDIR=""
+ fi
+
+
+ # OPENJDK_BUILD_CPU_ISADIR is normally empty. On 64-bit Solaris systems, it is set to
+ # /amd64 or /sparcv9. This string is appended to some library paths, like this:
+ # /usr/lib${OPENJDK_BUILD_CPU_ISADIR}/libexample.so
+ OPENJDK_BUILD_CPU_ISADIR=""
+ if test "x$OPENJDK_BUILD_OS" = xsolaris; then
+ if test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+ OPENJDK_BUILD_CPU_ISADIR="/amd64"
+ elif test "x$OPENJDK_BUILD_CPU" = xsparcv9; then
+ OPENJDK_BUILD_CPU_ISADIR="/sparcv9"
+ fi
+ fi
+
+
+ # Setup OPENJDK_BUILD_CPU_OSARCH, which is used to set the os.arch Java system property
+ OPENJDK_BUILD_CPU_OSARCH="$OPENJDK_BUILD_CPU"
+ if test "x$OPENJDK_BUILD_OS" = xlinux && test "x$OPENJDK_BUILD_CPU" = xx86; then
+ # On linux only, we replace x86 with i386.
+ OPENJDK_BUILD_CPU_OSARCH="i386"
+ elif test "x$OPENJDK_BUILD_OS" != xmacosx && test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+ # On all platforms except macosx, we replace x86_64 with amd64.
+ OPENJDK_BUILD_CPU_OSARCH="amd64"
+ fi
+
+
OPENJDK_BUILD_CPU_JLI="$OPENJDK_BUILD_CPU"
if test "x$OPENJDK_BUILD_CPU" = xx86; then
OPENJDK_BUILD_CPU_JLI="i386"
@@ -15350,47 +15571,94 @@
fi
- if test "x$OPENJDK_TARGET_OS" = xmacosx; then
- OPENJDK_TARGET_OS_EXPORT_DIR=macosx
- else
- OPENJDK_TARGET_OS_EXPORT_DIR=${OPENJDK_TARGET_OS_TYPE}
- fi
-
-
- if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+ if test "x$OPENJDK_BUILD_OS" = xmacosx; then
+ OPENJDK_BUILD_OS_EXPORT_DIR=macosx
+ else
+ OPENJDK_BUILD_OS_EXPORT_DIR=${OPENJDK_BUILD_OS_TYPE}
+ fi
+
+
+ if test "x$OPENJDK_BUILD_CPU_BITS" = x64; then
A_LP64="LP64:="
# -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in
# unpack200.exe
- if test "x$OPENJDK_TARGET_OS" = xlinux || test "x$OPENJDK_TARGET_OS" = xmacosx; then
- ADD_LP64="-D_LP64=1"
+ if test "x$OPENJDK_BUILD_OS" = xlinux || test "x$OPENJDK_BUILD_OS" = xmacosx; then
+ OPENJDK_BUILD_ADD_LP64="-D_LP64=1"
fi
fi
LP64=$A_LP64
- if test "x$OPENJDK_BUILD_CPU_BITS" = x64; then
- if test "x$OPENJDK_BUILD_OS" = xlinux || test "x$OPENJDK_BUILD_OS" = xmacosx; then
- OPENJDK_BUILD_ADD_LP64="-D_LP64=1"
- fi
- fi
if test "x$COMPILE_TYPE" = "xcross"; then
# FIXME: ... or should this include reduced builds..?
- DEFINE_CROSS_COMPILE_ARCH="CROSS_COMPILE_ARCH:=$OPENJDK_TARGET_CPU_LEGACY"
+ DEFINE_CROSS_COMPILE_ARCH="CROSS_COMPILE_ARCH:=$OPENJDK_BUILD_CPU_LEGACY"
else
DEFINE_CROSS_COMPILE_ARCH=""
fi
- # ZERO_ARCHDEF is used to enable architecture-specific code
- case "${OPENJDK_TARGET_CPU}" in
- ppc) ZERO_ARCHDEF=PPC32 ;;
- ppc64) ZERO_ARCHDEF=PPC64 ;;
- s390*) ZERO_ARCHDEF=S390 ;;
- sparc*) ZERO_ARCHDEF=SPARC ;;
- x86_64*) ZERO_ARCHDEF=AMD64 ;;
- x86) ZERO_ARCHDEF=IA32 ;;
- *) ZERO_ARCHDEF=$(echo "${OPENJDK_TARGET_CPU_LEGACY_LIB}" | tr a-z A-Z)
- esac
+ # Convert openjdk platform names to hotspot names
+
+ HOTSPOT_BUILD_OS=${OPENJDK_BUILD_OS}
+ if test "x$OPENJDK_BUILD_OS" = xmacosx; then
+ HOTSPOT_BUILD_OS=bsd
+ fi
+
+
+ HOTSPOT_BUILD_OS_TYPE=${OPENJDK_BUILD_OS_TYPE}
+ if test "x$OPENJDK_BUILD_OS_TYPE" = xunix; then
+ HOTSPOT_BUILD_OS_TYPE=posix
+ fi
+
+
+ HOTSPOT_BUILD_CPU=${OPENJDK_BUILD_CPU}
+ if test "x$OPENJDK_BUILD_CPU" = xx86; then
+ HOTSPOT_BUILD_CPU=x86_32
+ elif test "x$OPENJDK_BUILD_CPU" = xsparcv9; then
+ HOTSPOT_BUILD_CPU=sparc
+ elif test "x$OPENJDK_BUILD_CPU" = xppc64; then
+ HOTSPOT_BUILD_CPU=ppc_64
+ elif test "x$OPENJDK_BUILD_CPU" = xppc64le; then
+ HOTSPOT_BUILD_CPU=ppc_64
+ fi
+
+
+ # This is identical with OPENJDK_*, but define anyway for consistency.
+ HOTSPOT_BUILD_CPU_ARCH=${OPENJDK_BUILD_CPU_ARCH}
+
+
+ # Setup HOTSPOT_BUILD_CPU_DEFINE
+ if test "x$OPENJDK_BUILD_CPU" = xx86; then
+ HOTSPOT_BUILD_CPU_DEFINE=IA32
+ elif test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+ HOTSPOT_BUILD_CPU_DEFINE=AMD64
+ elif test "x$OPENJDK_BUILD_CPU" = xsparcv9; then
+ HOTSPOT_BUILD_CPU_DEFINE=SPARC
+ elif test "x$OPENJDK_BUILD_CPU" = xaarch64; then
+ HOTSPOT_BUILD_CPU_DEFINE=AARCH64
+ elif test "x$OPENJDK_BUILD_CPU" = xppc64; then
+ HOTSPOT_BUILD_CPU_DEFINE=PPC64
+ elif test "x$OPENJDK_BUILD_CPU" = xppc64le; then
+ HOTSPOT_BUILD_CPU_DEFINE=PPC64
+
+ # The cpu defines below are for zero, we don't support them directly.
+ elif test "x$OPENJDK_BUILD_CPU" = xsparc; then
+ HOTSPOT_BUILD_CPU_DEFINE=SPARC
+ elif test "x$OPENJDK_BUILD_CPU" = xppc; then
+ HOTSPOT_BUILD_CPU_DEFINE=PPC32
+ elif test "x$OPENJDK_BUILD_CPU" = xs390; then
+ HOTSPOT_BUILD_CPU_DEFINE=S390
+ elif test "x$OPENJDK_BUILD_CPU" = ss390x; then
+ HOTSPOT_BUILD_CPU_DEFINE=S390
+ fi
+
+
+
+
+ # ZERO_ARCHDEF is used to enable architecture-specific code.
+ # This is used in legacy hotspot build.
+ ZERO_ARCHDEF="$HOTSPOT_TARGET_CPU_DEFINE"
+
@@ -15929,98 +16197,6 @@
$as_echo "$JDK_VARIANT" >&6; }
-
-# Check whether --with-jvm-interpreter was given.
-if test "${with_jvm_interpreter+set}" = set; then :
- withval=$with_jvm_interpreter;
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking which interpreter of the JVM to build" >&5
-$as_echo_n "checking which interpreter of the JVM to build... " >&6; }
- if test "x$with_jvm_interpreter" = x; then
- JVM_INTERPRETER="template"
- else
- JVM_INTERPRETER="$with_jvm_interpreter"
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JVM_INTERPRETER" >&5
-$as_echo "$JVM_INTERPRETER" >&6; }
-
- if test "x$JVM_INTERPRETER" != xtemplate && test "x$JVM_INTERPRETER" != xcpp; then
- as_fn_error $? "The available JVM interpreters are: template, cpp" "$LINENO" 5
- fi
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variants of the JVM to build" >&5
-$as_echo_n "checking which variants of the JVM to build... " >&6; }
-
-# Check whether --with-jvm-variants was given.
-if test "${with_jvm_variants+set}" = set; then :
- withval=$with_jvm_variants;
-fi
-
-
- if test "x$with_jvm_variants" = x; then
- with_jvm_variants="server"
- fi
-
- JVM_VARIANTS=",$with_jvm_variants,"
- TEST_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/server,//' -e 's/client,//' -e 's/minimal1,//' -e 's/zero,//' -e 's/zeroshark,//' -e 's/core,//'`
-
- if test "x$TEST_VARIANTS" != "x,"; then
- as_fn_error $? "The available JVM variants are: server, client, minimal1, zero, zeroshark, core" "$LINENO" 5
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_jvm_variants" >&5
-$as_echo "$with_jvm_variants" >&6; }
-
- JVM_VARIANT_SERVER=`$ECHO "$JVM_VARIANTS" | $SED -e '/,server,/!s/.*/false/g' -e '/,server,/s/.*/true/g'`
- JVM_VARIANT_CLIENT=`$ECHO "$JVM_VARIANTS" | $SED -e '/,client,/!s/.*/false/g' -e '/,client,/s/.*/true/g'`
- JVM_VARIANT_MINIMAL1=`$ECHO "$JVM_VARIANTS" | $SED -e '/,minimal1,/!s/.*/false/g' -e '/,minimal1,/s/.*/true/g'`
- JVM_VARIANT_ZERO=`$ECHO "$JVM_VARIANTS" | $SED -e '/,zero,/!s/.*/false/g' -e '/,zero,/s/.*/true/g'`
- JVM_VARIANT_ZEROSHARK=`$ECHO "$JVM_VARIANTS" | $SED -e '/,zeroshark,/!s/.*/false/g' -e '/,zeroshark,/s/.*/true/g'`
- JVM_VARIANT_CORE=`$ECHO "$JVM_VARIANTS" | $SED -e '/,core,/!s/.*/false/g' -e '/,core,/s/.*/true/g'`
-
- if test "x$JVM_VARIANT_CLIENT" = xtrue; then
- if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
- as_fn_error $? "You cannot build a client JVM for a 64-bit machine." "$LINENO" 5
- fi
- fi
- if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
- if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
- as_fn_error $? "You cannot build a minimal JVM for a 64-bit machine." "$LINENO" 5
- fi
- fi
-
- # Replace the commas with AND for use in the build directory name.
- ANDED_JVM_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/^,//' -e 's/,$//' -e 's/,/AND/g'`
- COUNT_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/server,/1/' -e 's/client,/1/' -e 's/minimal1,/1/' -e 's/zero,/1/' -e 's/zeroshark,/1/' -e 's/core,/1/'`
- if test "x$COUNT_VARIANTS" != "x,1"; then
- BUILDING_MULTIPLE_JVM_VARIANTS=yes
- else
- BUILDING_MULTIPLE_JVM_VARIANTS=no
- fi
-
- if test "x$JVM_VARIANT_ZERO" = xtrue && test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = xyes; then
- as_fn_error $? "You cannot build multiple variants with zero." "$LINENO" 5
- fi
-
-
-
-
-
-
-
-
-
- if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
- MACOSX_UNIVERSAL="true"
- fi
-
-
-
-
DEBUG_LEVEL="release"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which debug level to use" >&5
$as_echo_n "checking which debug level to use... " >&6; }
@@ -16056,105 +16232,88 @@
as_fn_error $? "Allowed debug levels are: release, fastdebug, slowdebug and optimized" "$LINENO" 5
fi
-
- case $DEBUG_LEVEL in
- release )
- VARIANT="OPT"
- FASTDEBUG="false"
- DEBUG_CLASSFILES="false"
- BUILD_VARIANT_RELEASE=""
- HOTSPOT_DEBUG_LEVEL="product"
- HOTSPOT_EXPORT="product"
- ;;
- fastdebug )
- VARIANT="DBG"
- FASTDEBUG="true"
- DEBUG_CLASSFILES="true"
- BUILD_VARIANT_RELEASE="-fastdebug"
- HOTSPOT_DEBUG_LEVEL="fastdebug"
- HOTSPOT_EXPORT="fastdebug"
- ;;
- slowdebug )
- VARIANT="DBG"
- FASTDEBUG="false"
- DEBUG_CLASSFILES="true"
- BUILD_VARIANT_RELEASE="-debug"
- HOTSPOT_DEBUG_LEVEL="debug"
- HOTSPOT_EXPORT="debug"
- ;;
- optimized )
- VARIANT="OPT"
- FASTDEBUG="false"
- DEBUG_CLASSFILES="false"
- BUILD_VARIANT_RELEASE="-optimized"
- HOTSPOT_DEBUG_LEVEL="optimized"
- HOTSPOT_EXPORT="optimized"
- ;;
- esac
-
- # The debug level 'optimized' is a little special because it is currently only
- # applicable to the HotSpot build where it means to build a completely
- # optimized version of the VM without any debugging code (like for the
- # 'release' debug level which is called 'product' in the HotSpot build) but
- # with the exception that it can contain additional code which is otherwise
- # protected by '#ifndef PRODUCT' macros. These 'optimized' builds are used to
- # test new and/or experimental features which are not intended for customer
- # shipment. Because these new features need to be tested and benchmarked in
- # real world scenarios, we want to build the containing JDK at the 'release'
- # debug level.
+ # Translate DEBUG_LEVEL to debug level used by Hotspot
+ HOTSPOT_DEBUG_LEVEL="$DEBUG_LEVEL"
+ if test "x$DEBUG_LEVEL" = xrelease; then
+ HOTSPOT_DEBUG_LEVEL="product"
+ elif test "x$DEBUG_LEVEL" = xslowdebug; then
+ HOTSPOT_DEBUG_LEVEL="debug"
+ fi
+
if test "x$DEBUG_LEVEL" = xoptimized; then
+ # The debug level 'optimized' is a little special because it is currently only
+ # applicable to the HotSpot build where it means to build a completely
+ # optimized version of the VM without any debugging code (like for the
+ # 'release' debug level which is called 'product' in the HotSpot build) but
+ # with the exception that it can contain additional code which is otherwise
+ # protected by '#ifndef PRODUCT' macros. These 'optimized' builds are used to
+ # test new and/or experimental features which are not intended for customer
+ # shipment. Because these new features need to be tested and benchmarked in
+ # real world scenarios, we want to build the containing JDK at the 'release'
+ # debug level.
DEBUG_LEVEL="release"
fi
- #####
- # Generate the legacy makefile targets for hotspot.
- # The hotspot api for selecting the build artifacts, really, needs to be improved.
- # JDK-7195896 will fix this on the hotspot side by using the JVM_VARIANT_* variables to
- # determine what needs to be built. All we will need to set here is all_product, all_fastdebug etc
- # But until then ...
- HOTSPOT_TARGET=""
-
- if test "x$JVM_VARIANT_SERVER" = xtrue; then
- HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL} "
- fi
-
- if test "x$JVM_VARIANT_CLIENT" = xtrue; then
- HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}1 "
- fi
-
- if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
- HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}minimal1 "
- fi
-
- if test "x$JVM_VARIANT_ZERO" = xtrue; then
- HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}zero "
- fi
-
- if test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
- HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}shark "
- fi
-
- if test "x$JVM_VARIANT_CORE" = xtrue; then
- HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}core "
- fi
-
- HOTSPOT_TARGET="$HOTSPOT_TARGET docs export_$HOTSPOT_EXPORT"
-
- # On Macosx universal binaries are produced, but they only contain
- # 64 bit intel. This invalidates control of which jvms are built
- # from configure, but only server is valid anyway. Fix this
- # when hotspot makefiles are rewritten.
- if test "x$MACOSX_UNIVERSAL" = xtrue; then
- HOTSPOT_TARGET=universal_${HOTSPOT_EXPORT}
- fi
-
- #####
-
-
-
-
-
-
+
+
+
+
+
+# Check whether --with-jvm-variants was given.
+if test "${with_jvm_variants+set}" = set; then :
+ withval=$with_jvm_variants;
+fi
+
+
+ if test "x$with_jvm_variants" = x; then
+ with_jvm_variants="server"
+ fi
+ JVM_VARIANTS_OPT="$with_jvm_variants"
+
+ # Has the user listed more than one variant?
+ # Additional [] needed to keep m4 from mangling shell constructs.
+ if [[ "$JVM_VARIANTS_OPT" =~ "," ]] ; then
+ BUILDING_MULTIPLE_JVM_VARIANTS=true
+ else
+ BUILDING_MULTIPLE_JVM_VARIANTS=false
+ fi
+ # Replace the commas with AND for use in the build directory name.
+ JVM_VARIANTS_WITH_AND=`$ECHO "$JVM_VARIANTS_OPT" | $SED -e 's/,/AND/g'`
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variants of the JVM to build" >&5
+$as_echo_n "checking which variants of the JVM to build... " >&6; }
+ # JVM_VARIANTS is a space-separated list.
+ # Also use minimal, not minimal1 (which is kept for backwards compatibility).
+ JVM_VARIANTS=`$ECHO $JVM_VARIANTS_OPT | $SED -e 's/,/ /g' -e 's/minimal1/minimal/'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JVM_VARIANTS" >&5
+$as_echo "$JVM_VARIANTS" >&6; }
+
+ # Check that the selected variants are valid
+
+ # grep filter function inspired by a comment to http://stackoverflow.com/a/1617326
+ INVALID_VARIANTS=`$GREP -Fvx "${VALID_JVM_VARIANTS// /$'\n'}" <<< "${JVM_VARIANTS// /$'\n'}"`
+ if test "x$INVALID_VARIANTS" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Unknown variant(s) specified: $INVALID_VARIANTS" >&5
+$as_echo "$as_me: Unknown variant(s) specified: $INVALID_VARIANTS" >&6;}
+ as_fn_error $? "The available JVM variants are: $VALID_JVM_VARIANTS" "$LINENO" 5
+ fi
+
+ # All "special" variants share the same output directory ("server")
+ VALID_MULTIPLE_JVM_VARIANTS="server client minimal"
+ INVALID_MULTIPLE_VARIANTS=`$GREP -Fvx "${VALID_MULTIPLE_JVM_VARIANTS// /$'\n'}" <<< "${JVM_VARIANTS// /$'\n'}"`
+ if test "x$INVALID_MULTIPLE_VARIANTS" != x && test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = xtrue; then
+ as_fn_error $? "You cannot build multiple variants with anything else than $VALID_MULTIPLE_JVM_VARIANTS." "$LINENO" 5
+ fi
+
+
+
+
+ if [[ " $JVM_VARIANTS " =~ " zero " ]] || [[ " $JVM_VARIANTS " =~ " zeroshark " ]] ; then
+ # zero behaves as a platform and rewrites these values. This is really weird. :(
+ # We are guaranteed that we do not build any other variants when building zero.
+ HOTSPOT_TARGET_CPU=zero
+ HOTSPOT_TARGET_CPU_ARCH=zero
+ fi
# With basic setup done, call the custom early hook.
@@ -16603,8 +16762,8 @@
if test "x$OPENJDK_BUILD_OS" = "xsolaris"; then
- # Add extra search paths on solaris for utilities like ar and as etc...
- PATH="$PATH:/usr/ccs/bin:/usr/sfw/bin:/opt/csw/bin"
+ # Add extra search paths on solaris for utilities like ar, as, dtrace etc...
+ PATH="$PATH:/usr/ccs/bin:/usr/sfw/bin:/opt/csw/bin:/usr/sbin"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
@@ -16643,7 +16802,7 @@
if test "x${CONF_NAME}" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: in default location" >&5
$as_echo "in default location" >&6; }
- CONF_NAME="${OPENJDK_TARGET_OS}-${OPENJDK_TARGET_CPU}-${JDK_VARIANT}-${ANDED_JVM_VARIANTS}-${DEBUG_LEVEL}"
+ CONF_NAME="${OPENJDK_TARGET_OS}-${OPENJDK_TARGET_CPU}-${JDK_VARIANT}-${JVM_VARIANTS_WITH_AND}-${DEBUG_LEVEL}"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: in build directory with custom name" >&5
$as_echo "in build directory with custom name" >&6; }
@@ -22143,6 +22302,203 @@
# Publish this variable in the help.
+ if [ -z "${DTRACE+x}" ]; then
+ # The variable is not set by user, try to locate tool using the code snippet
+ for ac_prog in dtrace
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DTRACE+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $DTRACE in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_DTRACE="$DTRACE" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_DTRACE="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+DTRACE=$ac_cv_path_DTRACE
+if test -n "$DTRACE"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5
+$as_echo "$DTRACE" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DTRACE" && break
+done
+
+ else
+ # The variable is set, but is it from the command line or the environment?
+
+ # Try to remove the string !DTRACE! from our list.
+ try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!DTRACE!/}
+ if test "x$try_remove_var" = "x$CONFIGURE_OVERRIDDEN_VARIABLES"; then
+ # If it failed, the variable was not from the command line. Ignore it,
+ # but warn the user (except for BASH, which is always set by the calling BASH).
+ if test "xDTRACE" != xBASH; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of DTRACE from the environment. Use command line variables instead." >&5
+$as_echo "$as_me: WARNING: Ignoring value of DTRACE from the environment. Use command line variables instead." >&2;}
+ fi
+ # Try to locate tool using the code snippet
+ for ac_prog in dtrace
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DTRACE+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $DTRACE in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_DTRACE="$DTRACE" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_DTRACE="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+DTRACE=$ac_cv_path_DTRACE
+if test -n "$DTRACE"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5
+$as_echo "$DTRACE" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DTRACE" && break
+done
+
+ else
+ # If it succeeded, then it was overridden by the user. We will use it
+ # for the tool.
+
+ # First remove it from the list of overridden variables, so we can test
+ # for unknown variables in the end.
+ CONFIGURE_OVERRIDDEN_VARIABLES="$try_remove_var"
+
+ # Check if we try to supply an empty value
+ if test "x$DTRACE" = x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool DTRACE= (no value)" >&5
+$as_echo "$as_me: Setting user supplied tool DTRACE= (no value)" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DTRACE" >&5
+$as_echo_n "checking for DTRACE... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
+$as_echo "disabled" >&6; }
+ else
+ # Check if the provided tool contains a complete path.
+ tool_specified="$DTRACE"
+ tool_basename="${tool_specified##*/}"
+ if test "x$tool_basename" = "x$tool_specified"; then
+ # A command without a complete path is provided, search $PATH.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Will search for user supplied tool DTRACE=$tool_basename" >&5
+$as_echo "$as_me: Will search for user supplied tool DTRACE=$tool_basename" >&6;}
+ # Extract the first word of "$tool_basename", so it can be a program name with args.
+set dummy $tool_basename; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DTRACE+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $DTRACE in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_DTRACE="$DTRACE" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_DTRACE="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+DTRACE=$ac_cv_path_DTRACE
+if test -n "$DTRACE"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5
+$as_echo "$DTRACE" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "x$DTRACE" = x; then
+ as_fn_error $? "User supplied tool $tool_basename could not be found" "$LINENO" 5
+ fi
+ else
+ # Otherwise we believe it is a complete path. Use it as it is.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Will use user supplied tool DTRACE=$tool_specified" >&5
+$as_echo "$as_me: Will use user supplied tool DTRACE=$tool_specified" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DTRACE" >&5
+$as_echo_n "checking for DTRACE... " >&6; }
+ if test ! -x "$tool_specified"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+ as_fn_error $? "User supplied tool DTRACE=$tool_specified does not exist or is not executable" "$LINENO" 5
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tool_specified" >&5
+$as_echo "$tool_specified" >&6; }
+ fi
+ fi
+ fi
+
+ fi
+
+
+
+
+ # Publish this variable in the help.
+
+
if [ -z "${PATCH+x}" ]; then
# The variable is not set by user, try to locate tool using the code snippet
for ac_prog in gpatch patch
@@ -23422,10 +23778,7 @@
# Should we build the serviceability agent (SA)?
INCLUDE_SA=true
- if test "x$JVM_VARIANT_ZERO" = xtrue ; then
- INCLUDE_SA=false
- fi
- if test "x$JVM_VARIANT_ZEROSHARK" = xtrue ; then
+ if [[ " $JVM_VARIANTS " =~ " zero " ]] || [[ " $JVM_VARIANTS " =~ " zeroshark " ]] ; then
INCLUDE_SA=false
fi
if test "x$OPENJDK_TARGET_OS" = xaix ; then
@@ -23487,22 +23840,6 @@
- # Control wether Hotspot runs Queens test after build.
- # Check whether --enable-hotspot-test-in-build was given.
-if test "${enable_hotspot_test_in_build+set}" = set; then :
- enableval=$enable_hotspot_test_in_build;
-else
- enable_hotspot_test_in_build=no
-fi
-
- if test "x$enable_hotspot_test_in_build" = "xyes"; then
- TEST_IN_BUILD=true
- else
- TEST_IN_BUILD=false
- fi
-
-
-
# Warn user that old version arguments are deprecated.
@@ -23553,6 +23890,7 @@
+
# Override version from arguments
# If --with-version-string is set, process it first. It is possible to
@@ -30625,6 +30963,10 @@
+
+
+
+
# The global CFLAGS and LDLAGS variables are used by configure tests and
# should include the extra parameters
CFLAGS="$EXTRA_CFLAGS"
@@ -46752,6 +47094,17 @@
fi
+ # Setup hotspot lecagy names for toolchains
+ HOTSPOT_TOOLCHAIN_TYPE=$TOOLCHAIN_TYPE
+ if test "x$TOOLCHAIN_TYPE" = xclang; then
+ HOTSPOT_TOOLCHAIN_TYPE=gcc
+ elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+ HOTSPOT_TOOLCHAIN_TYPE=sparcWorks
+ elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+ HOTSPOT_TOOLCHAIN_TYPE=visCPP
+ fi
+
+
# Setup the JTReg Regression Test Harness.
@@ -47231,8 +47584,10 @@
# On Windows, we need to set RC flags.
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
RC_FLAGS="-nologo -l0x409"
+ JVM_RCFLAGS="-nologo"
if test "x$DEBUG_LEVEL" = xrelease; then
RC_FLAGS="$RC_FLAGS -DNDEBUG"
+ JVM_RCFLAGS="$JVM_RCFLAGS -DNDEBUG"
fi
# The version variables used to create RC_FLAGS may be overridden
@@ -47248,7 +47603,18 @@
-D\"JDK_COPYRIGHT=Copyright \xA9 $COPYRIGHT_YEAR\" \
-D\"JDK_NAME=\$(PRODUCT_NAME) \$(JDK_RC_PLATFORM_NAME) \$(VERSION_MAJOR)\" \
-D\"JDK_FVER=\$(subst .,\$(COMMA),\$(VERSION_NUMBER_FOUR_POSITIONS))\""
- fi
+
+ JVM_RCFLAGS="$JVM_RCFLAGS \
+ -D\"HS_BUILD_ID=\$(VERSION_STRING)\" \
+ -D\"HS_COMPANY=\$(COMPANY_NAME)\" \
+ -D\"JDK_DOTVER=\$(VERSION_NUMBER_FOUR_POSITIONS)\" \
+ -D\"HS_COPYRIGHT=Copyright $COPYRIGHT_YEAR\" \
+ -D\"HS_NAME=\$(PRODUCT_NAME) \$(VERSION_SHORT)\" \
+ -D\"JDK_VER=\$(subst .,\$(COMMA),\$(VERSION_NUMBER_FOUR_POSITIONS))\" \
+ -D\"HS_FNAME=jvm.dll\" \
+ -D\"HS_INTERNAL_NAME=jvm\""
+ fi
+
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
@@ -47416,6 +47782,10 @@
CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
+ JVM_CFLAGS="$JVM_CFLAGS $ADDED_CFLAGS"
+ JVM_LDFLAGS="$JVM_LDFLAGS $ADDED_LDFLAGS"
+ JVM_ASFLAGS="$JVM_ASFLAGS $ADDED_CFLAGS"
+
elif test "x$COMPILE_TYPE" = xreduced; then
if test "x$OPENJDK_TARGET_OS_TYPE" = xunix; then
# Specify -m if running reduced on unix platforms
@@ -47436,7 +47806,16 @@
CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
- fi
+ JVM_CFLAGS="$JVM_CFLAGS $ADDED_CFLAGS"
+ JVM_LDFLAGS="$JVM_LDFLAGS $ADDED_LDFLAGS"
+ JVM_ASFLAGS="$JVM_ASFLAGS $ADDED_CFLAGS"
+
+ fi
+ fi
+ if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+ JVM_CFLAGS="$JVM_CFLAGS ${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
+ JVM_LDFLAGS="$JVM_LDFLAGS ${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
+ JVM_ASFLAGS="$JVM_ASFLAGS ${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
fi
# Make compilation sanity check
@@ -47562,6 +47941,10 @@
CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
+ JVM_CFLAGS="$JVM_CFLAGS $ADDED_CFLAGS"
+ JVM_LDFLAGS="$JVM_LDFLAGS $ADDED_LDFLAGS"
+ JVM_ASFLAGS="$JVM_ASFLAGS $ADDED_CFLAGS"
+
# We have to unset 'ac_cv_sizeof_int_p' first, otherwise AC_CHECK_SIZEOF will use the previously cached value!
unset ac_cv_sizeof_int_p
@@ -47908,6 +48291,7 @@
SHARED_LIBRARY_FLAGS ='-undefined dynamic_lookup'
else
SHARED_LIBRARY_FLAGS="-dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0 $PICFLAG"
+ JVM_CFLAGS="$JVM_CFLAGS $PICFLAG"
fi
SET_EXECUTABLE_ORIGIN='-Wl,-rpath,@loader_path/.'
SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
@@ -47933,6 +48317,10 @@
SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-Wl,-install_name,@rpath/$1'
SET_SHARED_LIBRARY_MAPFILE='-Wl,-exported_symbols_list,$1'
+
+ if test "x$STATIC_BUILD" = xfalse; then
+ JVM_CFLAGS="$JVM_CFLAGS -fPIC"
+ fi
else
# Default works for linux, might work on other platforms as well.
PICFLAG='-fPIC'
@@ -47992,11 +48380,6 @@
- if test "x$OPENJDK_TARGET_OS" = xsolaris; then
- CFLAGS_JDK="${CFLAGS_JDK} -D__solaris__"
- CXXFLAGS_JDK="${CXXFLAGS_JDK} -D__solaris__"
- CFLAGS_JDKLIB_EXTRA='-xstrconst'
- fi
# The (cross) compiler is now configured, we can now test capabilities
# of the target platform.
@@ -48054,6 +48437,22 @@
+ # Debug symbols for JVM_CFLAGS
+ if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+ JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -xs"
+ if test "x$DEBUG_LEVEL" = xslowdebug; then
+ JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -g"
+ else
+ # -g0 does not disable inlining, which -g does.
+ JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -g0"
+ fi
+ elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+ JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -Z7 -d2Zi+"
+ else
+ JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -g"
+ fi
+
+
# bounds, memory and behavior checking options
if test "x$TOOLCHAIN_TYPE" = xgcc; then
case $DEBUG_LEVEL in
@@ -48064,7 +48463,7 @@
# no adjustment
;;
slowdebug )
- # FIXME: By adding this to C(XX)FLAGS_DEBUG_OPTIONS it
+ # FIXME: By adding this to C(XX)FLAGS_DEBUG_OPTIONS/JVM_CFLAGS_SYMBOLS it
# get's added conditionally on whether we produce debug symbols or not.
# This is most likely not really correct.
@@ -48339,40 +48738,59 @@
CFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
CXXFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
+ if test "x$STACK_PROTECTOR_CFLAG" != x; then
+ JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS $STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
+ fi
;;
esac
fi
+ if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+ if test "x$DEBUG_LEVEL" != xrelease; then
+ if test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+ JVM_CFLAGS="$JVM_CFLAGS -homeparams"
+ fi
+ fi
+ fi
+
# Optimization levels
if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
CC_HIGHEST="$CC_HIGHEST -fns -fsimple -fsingle -xbuiltin=%all -xdepend -xrestrict -xlibmil"
if test "x$OPENJDK_TARGET_CPU_ARCH" = "xx86"; then
# FIXME: seems we always set -xregs=no%frameptr; put it elsewhere more global?
+ C_O_FLAG_HIGHEST_JVM="-xO4"
C_O_FLAG_HIGHEST="-xO4 -Wu,-O4~yz $CC_HIGHEST -xalias_level=basic -xregs=no%frameptr"
C_O_FLAG_HI="-xO4 -Wu,-O4~yz -xregs=no%frameptr"
C_O_FLAG_NORM="-xO2 -Wu,-O2~yz -xregs=no%frameptr"
C_O_FLAG_DEBUG="-xregs=no%frameptr"
+ C_O_FLAG_DEBUG_JVM=""
C_O_FLAG_NONE="-xregs=no%frameptr"
+ CXX_O_FLAG_HIGHEST_JVM="-xO4"
CXX_O_FLAG_HIGHEST="-xO4 -Qoption ube -O4~yz $CC_HIGHEST -xregs=no%frameptr"
CXX_O_FLAG_HI="-xO4 -Qoption ube -O4~yz -xregs=no%frameptr"
CXX_O_FLAG_NORM="-xO2 -Qoption ube -O2~yz -xregs=no%frameptr"
CXX_O_FLAG_DEBUG="-xregs=no%frameptr"
+ CXX_O_FLAG_DEBUG_JVM=""
CXX_O_FLAG_NONE="-xregs=no%frameptr"
if test "x$OPENJDK_TARGET_CPU_BITS" = "x32"; then
C_O_FLAG_HIGHEST="$C_O_FLAG_HIGHEST -xchip=pentium"
CXX_O_FLAG_HIGHEST="$CXX_O_FLAG_HIGHEST -xchip=pentium"
fi
elif test "x$OPENJDK_TARGET_CPU_ARCH" = "xsparc"; then
+ C_O_FLAG_HIGHEST_JVM="-xO4"
C_O_FLAG_HIGHEST="-xO4 -Wc,-Qrm-s -Wc,-Qiselect-T0 $CC_HIGHEST -xalias_level=basic -xprefetch=auto,explicit -xchip=ultra"
C_O_FLAG_HI="-xO4 -Wc,-Qrm-s -Wc,-Qiselect-T0"
C_O_FLAG_NORM="-xO2 -Wc,-Qrm-s -Wc,-Qiselect-T0"
C_O_FLAG_DEBUG=""
+ C_O_FLAG_DEBUG_JVM=""
C_O_FLAG_NONE=""
+ CXX_O_FLAG_HIGHEST_JVM="-xO4"
CXX_O_FLAG_HIGHEST="-xO4 -Qoption cg -Qrm-s -Qoption cg -Qiselect-T0 $CC_HIGHEST -xprefetch=auto,explicit -xchip=ultra"
CXX_O_FLAG_HI="-xO4 -Qoption cg -Qrm-s -Qoption cg -Qiselect-T0"
CXX_O_FLAG_NORM="-xO2 -Qoption cg -Qrm-s -Qoption cg -Qiselect-T0"
CXX_O_FLAG_DEBUG=""
+ CXX_O_FLAG_DEBUG_JVM=""
CXX_O_FLAG_NONE=""
fi
else
@@ -48382,48 +48800,75 @@
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
# On MacOSX we optimize for size, something
# we should do for all platforms?
+ C_O_FLAG_HIGHEST_JVM="-Os"
C_O_FLAG_HIGHEST="-Os"
C_O_FLAG_HI="-Os"
C_O_FLAG_NORM="-Os"
- else
+ C_O_FLAG_SIZE="-Os"
+ else
+ C_O_FLAG_HIGHEST_JVM="-O3"
C_O_FLAG_HIGHEST="-O3"
C_O_FLAG_HI="-O3"
C_O_FLAG_NORM="-O2"
+ C_O_FLAG_SIZE="-Os"
fi
C_O_FLAG_DEBUG="-O0"
+ if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+ C_O_FLAG_DEBUG_JVM=""
+ elif test "x$OPENJDK_TARGET_OS" = xlinux; then
+ C_O_FLAG_DEBUG_JVM="-O0"
+ fi
C_O_FLAG_NONE="-O0"
elif test "x$TOOLCHAIN_TYPE" = xclang; then
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
# On MacOSX we optimize for size, something
# we should do for all platforms?
+ C_O_FLAG_HIGHEST_JVM="-Os"
C_O_FLAG_HIGHEST="-Os"
C_O_FLAG_HI="-Os"
C_O_FLAG_NORM="-Os"
- else
+ C_O_FLAG_SIZE="-Os"
+ else
+ C_O_FLAG_HIGHEST_JVM="-O3"
C_O_FLAG_HIGHEST="-O3"
C_O_FLAG_HI="-O3"
C_O_FLAG_NORM="-O2"
+ C_O_FLAG_SIZE="-Os"
fi
C_O_FLAG_DEBUG="-O0"
+ if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+ C_O_FLAG_DEBUG_JVM=""
+ elif test "x$OPENJDK_TARGET_OS" = xlinux; then
+ C_O_FLAG_DEBUG_JVM="-O0"
+ fi
C_O_FLAG_NONE="-O0"
elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+ C_O_FLAG_HIGHEST_JVM="-O3"
C_O_FLAG_HIGHEST="-O3"
C_O_FLAG_HI="-O3 -qstrict"
C_O_FLAG_NORM="-O2"
C_O_FLAG_DEBUG="-qnoopt"
+ # FIXME: Value below not verified.
+ C_O_FLAG_DEBUG_JVM=""
C_O_FLAG_NONE="-qnoopt"
elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+ C_O_FLAG_HIGHEST_JVM="-O2 -Oy-"
C_O_FLAG_HIGHEST="-O2"
C_O_FLAG_HI="-O1"
C_O_FLAG_NORM="-O1"
C_O_FLAG_DEBUG="-Od"
+ C_O_FLAG_DEBUG_JVM=""
C_O_FLAG_NONE="-Od"
- fi
+ C_O_FLAG_SIZE="-Os"
+ fi
+ CXX_O_FLAG_HIGHEST_JVM="$C_O_FLAG_HIGHEST_JVM"
CXX_O_FLAG_HIGHEST="$C_O_FLAG_HIGHEST"
CXX_O_FLAG_HI="$C_O_FLAG_HI"
CXX_O_FLAG_NORM="$C_O_FLAG_NORM"
CXX_O_FLAG_DEBUG="$C_O_FLAG_DEBUG"
+ CXX_O_FLAG_DEBUG_JVM="$C_O_FLAG_DEBUG_JVM"
CXX_O_FLAG_NONE="$C_O_FLAG_NONE"
+ CXX_O_FLAG_SIZE="$C_O_FLAG_SIZE"
fi
# Adjust optimization flags according to debug level.
@@ -48438,12 +48883,16 @@
;;
slowdebug )
# Disable optimization
+ C_O_FLAG_HIGHEST_JVM="$C_O_FLAG_DEBUG_JVM"
C_O_FLAG_HIGHEST="$C_O_FLAG_DEBUG"
C_O_FLAG_HI="$C_O_FLAG_DEBUG"
C_O_FLAG_NORM="$C_O_FLAG_DEBUG"
+ C_O_FLAG_SIZE="$C_O_FLAG_DEBUG"
+ CXX_O_FLAG_HIGHEST_JVM="$CXX_O_FLAG_DEBUG_JVM"
CXX_O_FLAG_HIGHEST="$CXX_O_FLAG_DEBUG"
CXX_O_FLAG_HI="$CXX_O_FLAG_DEBUG"
CXX_O_FLAG_NORM="$CXX_O_FLAG_DEBUG"
+ CXX_O_FLAG_SIZE="$CXX_O_FLAG_DEBUG"
;;
esac
@@ -48459,6 +48908,12 @@
+
+
+
+
+
+
# Special extras...
if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
if test "x$OPENJDK_TARGET_CPU_ARCH" = "xsparc"; then
@@ -48570,10 +49025,23 @@
CXXFLAGS_JDK="${CXXFLAGS_JDK} ${CXXSTD_CXXFLAG}"
fi
-
- CFLAGS_JDK="${CFLAGS_JDK} $EXTRA_CFLAGS"
- CXXFLAGS_JDK="${CXXFLAGS_JDK} $EXTRA_CXXFLAGS"
- LDFLAGS_JDK="${LDFLAGS_JDK} $EXTRA_LDFLAGS"
+ if test "x$OPENJDK_TARGET_OS" = xsolaris; then
+ CFLAGS_JDK="${CFLAGS_JDK} -D__solaris__"
+ CXXFLAGS_JDK="${CXXFLAGS_JDK} -D__solaris__"
+ CFLAGS_JDKLIB_EXTRA='-xstrconst'
+ CFLAGS_JDK="${CFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+ CXXFLAGS_JDK="${CXXFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+ fi
+
+ if test "x$OPENJDK_TARGET_OS" = xsolaris; then
+ CFLAGS_JDK="${CFLAGS_JDK} -D__solaris__"
+ CXXFLAGS_JDK="${CXXFLAGS_JDK} -D__solaris__"
+ CFLAGS_JDKLIB_EXTRA='-xstrconst'
+ fi
+
+ CFLAGS_JDK="${CFLAGS_JDK} ${EXTRA_CFLAGS}"
+ CXXFLAGS_JDK="${CXXFLAGS_JDK} ${EXTRA_CXXFLAGS}"
+ LDFLAGS_JDK="${LDFLAGS_JDK} ${EXTRA_LDFLAGS}"
###############################################################################
#
@@ -48586,9 +49054,13 @@
# CXXFLAGS_JDK - C++ Compiler flags
# COMMON_CCXXFLAGS_JDK - common to C and C++
if test "x$TOOLCHAIN_TYPE" = xgcc; then
+ JVM_CFLAGS="$JVM_CFLAGS -D_GNU_SOURCE"
+ JVM_CFLAGS="$JVM_CFLAGS -D_REENTRANT"
+ JVM_CFLAGS="$JVM_CFLAGS -fcheck-new"
if test "x$OPENJDK_TARGET_CPU" = xx86; then
# Force compatibility with i586 on 32 bit intel platforms.
COMMON_CCXXFLAGS="${COMMON_CCXXFLAGS} -march=i586"
+ JVM_CFLAGS="$JVM_CFLAGS -march=i586"
fi
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
-pipe -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
@@ -49225,11 +49697,19 @@
elif test "x$TOOLCHAIN_TYPE" = xclang; then
+ JVM_CFLAGS="$JVM_CFLAGS -D_GNU_SOURCE"
+
+ # Restrict the debug information created by Clang to avoid
+ # too big object files and speed the build up a little bit
+ # (see http://llvm.org/bugs/show_bug.cgi?id=7554)
+ JVM_CFLAGS="$JVM_CFLAGS -flimit-debug-info"
if test "x$OPENJDK_TARGET_OS" = xlinux; then
if test "x$OPENJDK_TARGET_CPU" = xx86; then
# Force compatibility with i586 on 32 bit intel platforms.
COMMON_CCXXFLAGS="${COMMON_CCXXFLAGS} -march=i586"
- fi
+ JVM_CFLAGS="$JVM_CFLAGS -march=i586"
+ fi
+ JVM_CFLAGS="$JVM_CFLAGS -Wno-sometimes-uninitialized"
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
-pipe -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
case $OPENJDK_TARGET_CPU_ARCH in
@@ -49244,6 +49724,7 @@
esac
fi
elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+ JVM_CFLAGS="$JVM_CFLAGS -DSPARC_WORKS"
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -DTRACING -DMACRO_MEMSYS_OPS -DBREAKPTS"
if test "x$OPENJDK_TARGET_CPU_ARCH" = xx86; then
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DcpuIntel -Di586 -D$OPENJDK_TARGET_CPU_LEGACY_LIB"
@@ -49252,6 +49733,7 @@
CFLAGS_JDK="$CFLAGS_JDK -xc99=%none -xCC -errshort=tags -Xa -v -mt -W0,-noglobal"
CXXFLAGS_JDK="$CXXFLAGS_JDK -errtags=yes +w -mt -features=no%except -DCC_NOEX -norunpath -xnolib"
elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+ JVM_CFLAGS="$JVM_CFLAGS -D_REENTRANT -D__STDC_FORMAT_MACROS"
CFLAGS_JDK="$CFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
CXXFLAGS_JDK="$CXXFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
@@ -49272,6 +49754,7 @@
if test "x$TOOLCHAIN_VERSION" = "x2010"; then
STATIC_CPPLIB_FLAGS="-D_STATIC_CPPLIB -D_DISABLE_DEPRECATE_STATIC_CPPLIB"
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK $STATIC_CPPLIB_FLAGS"
+ JVM_CFLAGS="$JVM_CFLAGS $STATIC_CPPLIB_FLAGS"
fi
fi
@@ -49321,12 +49804,9 @@
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D$OPENJDK_TARGET_OS_UPPERCASE"
# Setup target CPU
- OPENJDK_TARGET_CCXXFLAGS_JDK="$OPENJDK_TARGET_CCXXFLAGS_JDK \
- $ADD_LP64 \
+ COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK \
+ $OPENJDK_TARGET_ADD_LP64 \
-DARCH='\"$OPENJDK_TARGET_CPU_LEGACY\"' -D$OPENJDK_TARGET_CPU_LEGACY"
- OPENJDK_BUILD_CCXXFLAGS_JDK="$OPENJDK_BUILD_CCXXFLAGS_JDK \
- $OPENJDK_BUILD_ADD_LP64 \
- -DARCH='\"$OPENJDK_BUILD_CPU_LEGACY\"' -D$OPENJDK_BUILD_CPU_LEGACY"
# Setup debug/release defines
if test "x$DEBUG_LEVEL" = xrelease; then
@@ -49339,10 +49819,172 @@
fi
# Set some additional per-OS defines.
- if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+ if test "x$OPENJDK_TARGET_OS" = xlinux; then
+ JVM_CFLAGS="$JVM_CFLAGS -DLINUX"
+ JVM_CFLAGS="$JVM_CFLAGS -pipe -fPIC -fno-rtti -fno-exceptions \
+ -fvisibility=hidden -fno-strict-aliasing -fno-omit-frame-pointer"
+ elif test "x$OPENJDK_TARGET_OS" = xsolaris; then
+ JVM_CFLAGS="$JVM_CFLAGS -DSOLARIS"
+ JVM_CFLAGS="$JVM_CFLAGS -template=no%extdef -features=no%split_init \
+ -D_Crun_inline_placement -library=%none -KPIC -mt -xwe -features=no%except"
+ elif test "x$OPENJDK_TARGET_OS" = xmacosx; then
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
+ JVM_CFLAGS="$JVM_CFLAGS -D_ALLBSD_SOURCE"
+ JVM_CFLAGS="$JVM_CFLAGS -D_DARWIN_C_SOURCE -D_XOPEN_SOURCE"
+ JVM_CFLAGS="$JVM_CFLAGS -fno-rtti -fno-exceptions -fvisibility=hidden \
+ -mno-omit-leaf-frame-pointer -mstack-alignment=16 -pipe -fno-strict-aliasing \
+ -DMAC_OS_X_VERSION_MAX_ALLOWED=1070 -mmacosx-version-min=10.7.0 \
+ -fno-omit-frame-pointer"
+ elif test "x$OPENJDK_TARGET_OS" = xaix; then
+ JVM_CFLAGS="$JVM_CFLAGS -DAIX"
+ # We may need '-qminimaltoc' or '-qpic=large -bbigtoc' if the TOC overflows.
+ JVM_CFLAGS="$JVM_CFLAGS -qtune=balanced -qhot=level=1 -qinline \
+ -qinlglue -qalias=noansi -qstrict -qtls=default -qlanglvl=c99vla \
+ -qlanglvl=noredefmac -qnortti -qnoeh -qignerrno"
elif test "x$OPENJDK_TARGET_OS" = xbsd; then
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE"
+ elif test "x$OPENJDK_TARGET_OS" = xwindows; then
+ JVM_CFLAGS="$JVM_CFLAGS -D_WINDOWS -DWIN32 -D_JNI_IMPLEMENTATION_"
+ JVM_CFLAGS="$JVM_CFLAGS -nologo -W3 -MD -MP"
+ fi
+
+ # Set some additional per-CPU defines.
+ if test "x$OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU" = xwindows-x86; then
+ JVM_CFLAGS="$JVM_CFLAGS -arch:IA32"
+ elif test "x$OPENJDK_TARGET_CPU" = xsparcv9; then
+ JVM_CFLAGS="$JVM_CFLAGS -xarch=sparc"
+ elif test "x$OPENJDK_TARGET_CPU" = xppc64; then
+ if test "x$OPENJDK_TARGET_OS" = xlinux; then
+ JVM_CFLAGS="$JVM_CFLAGS -minsert-sched-nops=regroup_exact -mno-multiple -mno-string"
+ # fixes `relocation truncated to fit' error for gcc 4.1.
+ JVM_CFLAGS="$JVM_CFLAGS -mminimal-toc"
+ # Use ppc64 instructions, but schedule for power5
+ JVM_CFLAGS="$JVM_CFLAGS -mcpu=powerpc64 -mtune=power5"
+ elif test "x$OPENJDK_TARGET_OS" = xaix; then
+ JVM_CFLAGS="$JVM_CFLAGS -qarch=ppc64"
+ fi
+ elif test "x$OPENJDK_TARGET_CPU" = xppc64le; then
+ if test "x$OPENJDK_TARGET_OS" = xlinux; then
+ JVM_CFLAGS="$JVM_CFLAGS -minsert-sched-nops=regroup_exact -mno-multiple -mno-string"
+ # Little endian machine uses ELFv2 ABI.
+ JVM_CFLAGS="$JVM_CFLAGS -DABI_ELFv2"
+ # Use Power8, this is the first CPU to support PPC64 LE with ELFv2 ABI.
+ JVM_CFLAGS="$JVM_CFLAGS -mcpu=power7 -mtune=power8"
+ fi
+ fi
+
+ if test "x$OPENJDK_TARGET_CPU_ENDIAN" = xlittle; then
+ JVM_CFLAGS="$JVM_CFLAGS -DVM_LITTLE_ENDIAN"
+ fi
+
+ if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+ if test "x$OPENJDK_TARGET_OS" != xsolaris && test "x$OPENJDK_TARGET_OS" != xaix; then
+ # Solaris does not have _LP64=1 in the old build.
+ # xlc on AIX defines _LP64=1 by default and issues a warning if we redefine it.
+ JVM_CFLAGS="$JVM_CFLAGS -D_LP64=1"
+ fi
+ fi
+
+ # Set JVM_CFLAGS warning handling
+ if test "x$OPENJDK_TARGET_OS" = xlinux; then
+ JVM_CFLAGS="$JVM_CFLAGS -Wpointer-arith -Wsign-compare -Wunused-function \
+ -Wunused-value -Woverloaded-virtual"
+
+ if test "x$TOOLCHAIN_TYPE" = xgcc; then
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ # Execute function body
+
+ # Need to assign to a variable since m4 is blocked from modifying parts in [].
+ REFERENCE_VERSION=4.8
+
+ if [[ "$REFERENCE_VERSION" =~ (.*\.){3} ]] ; then
+ as_fn_error $? "Internal error: Cannot compare to 4.8, only three parts (X.Y.Z) is supported" "$LINENO" 5
+ fi
+
+ if [[ "$REFERENCE_VERSION" =~ [0-9]{6} ]] ; then
+ as_fn_error $? "Internal error: Cannot compare to 4.8, only parts < 99999 is supported" "$LINENO" 5
+ fi
+
+ # Version comparison method inspired by http://stackoverflow.com/a/24067243
+ COMPARABLE_REFERENCE_VERSION=`$AWK -F. '{ printf("%05d%05d%05d\n", $1, $2, $3) }' <<< "$REFERENCE_VERSION"`
+
+ if test $COMPARABLE_ACTUAL_VERSION -ge $COMPARABLE_REFERENCE_VERSION ; then
+ :
+
+ # These flags either do not work or give spurious warnings prior to gcc 4.8.
+ JVM_CFLAGS="$JVM_CFLAGS -Wno-format-zero-length -Wtype-limits -Wuninitialized"
+
+
+ else
+ :
+
+ fi
+
+
+
+
+
+
+
+
+
+
+
+
+ fi
+ if ! [[ " $JVM_VARIANTS " =~ " zero " ]] && ! [[ " $JVM_VARIANTS " =~ " zeroshark " ]] ; then
+ # Non-zero builds have stricter warnings
+ JVM_CFLAGS="$JVM_CFLAGS -Wreturn-type -Wundef -Wformat=2"
+ else
+ if test "x$TOOLCHAIN_TYPE" = xclang; then
+ # Some versions of llvm do not like -Wundef
+ JVM_CFLAGS="$JVM_CFLAGS -Wno-undef"
+ fi
+ fi
+ elif test "x$OPENJDK_TARGET_OS" = xmacosx; then
+ JVM_CFLAGS="$JVM_CFLAGS -Wno-deprecated -Wpointer-arith \
+ -Wsign-compare -Wundef -Wunused-function -Wformat=2"
fi
# Additional macosx handling
@@ -49370,43 +50012,14 @@
-I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/libjava"
# The shared libraries are compiled using the picflag.
- CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
+ CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK \
$CFLAGS_JDK $EXTRA_CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
- CXXFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
+ CXXFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK \
$CXXFLAGS_JDK $EXTRA_CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
# Executable flags
- CFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
- $CFLAGS_JDK $EXTRA_CFLAGS_JDK"
- CXXFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
- $CXXFLAGS_JDK $EXTRA_CXXFLAGS_JDK"
-
- # The corresponding flags for building for the build platform. This is still an
- # approximation, we only need something that runs on this machine when cross
- # compiling the product.
- OPENJDK_BUILD_CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK \
- $PICFLAG $CFLAGS_JDKLIB_EXTRA"
- OPENJDK_BUILD_CXXFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK \
- $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
- OPENJDK_BUILD_CFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK"
- OPENJDK_BUILD_CXXFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK"
-
-
-
-
-
-
-
-
-
-
- # Flags for compiling test libraries
- CFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
- CXXFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
-
- # Flags for compiling test executables
- CFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK"
- CXXFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK"
+ CFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $EXTRA_CFLAGS_JDK"
+ CXXFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK $EXTRA_CXXFLAGS_JDK"
@@ -49419,9 +50032,21 @@
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
LDFLAGS_MICROSOFT="-nologo -opt:ref"
LDFLAGS_JDK="$LDFLAGS_JDK $LDFLAGS_MICROSOFT -incremental:no"
+ JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_MICROSOFT -opt:icf,8 -subsystem:windows -base:0x8000000"
if test "x$OPENJDK_TARGET_CPU_BITS" = "x32"; then
LDFLAGS_SAFESH="-safeseh"
LDFLAGS_JDK="$LDFLAGS_JDK $LDFLAGS_SAFESH"
+ JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_SAFESH"
+ # NOTE: Old build added -machine. Probably not needed.
+ JVM_LDFLAGS="$JVM_LDFLAGS -machine:I386"
+ else
+ JVM_LDFLAGS="$JVM_LDFLAGS -machine:AMD64"
+ fi
+ elif test "x$TOOLCHAIN_TYPE" = xclang; then
+ JVM_LDFLAGS="$JVM_LDFLAGS -mno-omit-leaf-frame-pointer -mstack-alignment=16 -stdlib=libstdc++ -fPIC"
+ if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+ # FIXME: We should really generalize SET_SHARED_LIBRARY_ORIGIN instead.
+ JVM_LDFLAGS="$JVM_LDFLAGS -Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
fi
elif test "x$TOOLCHAIN_TYPE" = xgcc; then
# If this is a --hash-style=gnu system, use --hash-style=both, why?
@@ -49429,36 +50054,57 @@
if test -n "$HAS_GNU_HASH"; then
LDFLAGS_HASH_STYLE="-Wl,--hash-style=both"
LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_HASH_STYLE"
+ JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_HASH_STYLE"
+ fi
+ if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+ JVM_LDFLAGS="$JVM_LDFLAGS -Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
fi
if test "x$OPENJDK_TARGET_OS" = xlinux; then
# And since we now know that the linker is gnu, then add -z defs, to forbid
# undefined symbols in object files.
LDFLAGS_NO_UNDEF_SYM="-Wl,-z,defs"
LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_NO_UNDEF_SYM"
+ JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_NO_UNDEF_SYM"
+ LDFLAGS_NO_EXEC_STACK="-Wl,-z,noexecstack"
+ JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_NO_EXEC_STACK"
+ if test "x$OPENJDK_TARGET_CPU" = xx86; then
+ JVM_LDFLAGS="$JVM_LDFLAGS -march=i586"
+ fi
case $DEBUG_LEVEL in
release )
# tell linker to optimize libraries.
# Should this be supplied to the OSS linker as well?
LDFLAGS_DEBUGLEVEL_release="-Wl,-O1"
LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_DEBUGLEVEL_release"
+ JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_DEBUGLEVEL_release"
+ if test "x$HAS_LINKER_RELRO" = "xtrue"; then
+ JVM_LDFLAGS="$JVM_LDFLAGS $LINKER_RELRO_FLAG"
+ fi
;;
slowdebug )
+ # Hotspot always let the linker optimize
+ JVM_LDFLAGS="$JVM_LDFLAGS -Wl,-O1"
if test "x$HAS_LINKER_NOW" = "xtrue"; then
# do relocations at load
LDFLAGS_JDK="$LDFLAGS_JDK $LINKER_NOW_FLAG"
LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LINKER_NOW_FLAG"
+ JVM_LDFLAGS="$JVM_LDFLAGS $LINKER_NOW_FLAG"
fi
if test "x$HAS_LINKER_RELRO" = "xtrue"; then
# mark relocations read only
LDFLAGS_JDK="$LDFLAGS_JDK $LINKER_RELRO_FLAG"
LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+ JVM_LDFLAGS="$JVM_LDFLAGS $LINKER_RELRO_FLAG"
fi
;;
fastdebug )
+ # Hotspot always let the linker optimize
+ JVM_LDFLAGS="$JVM_LDFLAGS -Wl,-O1"
if test "x$HAS_LINKER_RELRO" = "xtrue"; then
# mark relocations read only
LDFLAGS_JDK="$LDFLAGS_JDK $LINKER_RELRO_FLAG"
LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+ JVM_LDFLAGS="$JVM_LDFLAGS $LINKER_RELRO_FLAG"
fi
;;
* )
@@ -49471,9 +50117,14 @@
LDFLAGS_JDK="$LDFLAGS_JDK $LDFLAGS_SOLSTUDIO -xildoff -ztext"
LDFLAGS_CXX_SOLSTUDIO="-norunpath"
LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LDFLAGS_CXX_SOLSTUDIO -xnolib"
+ JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_SOLSTUDIO -library=%none -mt $LDFLAGS_CXX_SOLSTUDIO -z noversion"
+ if test "x$OPENJDK_TARGET_CPU_ARCH" = "xsparc"; then
+ JVM_LDFLAGS="$JVM_LDFLAGS -xarch=sparc"
+ fi
elif test "x$TOOLCHAIN_TYPE" = xxlc; then
LDFLAGS_XLC="-b64 -brtl -bnolibpath -bexpall -bernotok"
LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_XLC"
+ JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_XLC"
fi
# Customize LDFLAGS for executables
@@ -49491,7 +50142,6 @@
LDFLAGS_JDKEXE="$LDFLAGS_JDKEXE -Wl,--allow-shlib-undefined"
fi
- OPENJDK_BUILD_LDFLAGS_JDKEXE="${LDFLAGS_JDKEXE}"
LDFLAGS_JDKEXE="${LDFLAGS_JDKEXE} ${EXTRA_LDFLAGS_JDK}"
# Customize LDFLAGS for libs
@@ -49506,18 +50156,24 @@
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} \
-L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)"
+ if test "xTARGET" = "xTARGET"; then
# On some platforms (mac) the linker warns about non existing -L dirs.
# Add server first if available. Linking aginst client does not always produce the same results.
- # Only add client dir if client is being built. Add minimal (note not minimal1) if only building minimal1.
+ # Only add client/minimal dir if client/minimal is being built.
# Default to server for other variants.
- if test "x$JVM_VARIANT_SERVER" = xtrue; then
- LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
- elif test "x$JVM_VARIANT_CLIENT" = xtrue; then
- LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/client"
- elif test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
- LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/minimal"
- else
- LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
+ if [[ " $JVM_VARIANTS " =~ " server " ]] ; then
+ LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
+ elif [[ " $JVM_VARIANTS " =~ " client " ]] ; then
+ LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/client"
+ elif [[ " $JVM_VARIANTS " =~ " minimal " ]] ; then
+ LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/minimal"
+ else
+ LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
+ fi
+ elif test "xTARGET" = "xBUILD"; then
+ # When building a buildjdk, it's always only the server variant
+ LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} \
+ -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
fi
JDKLIB_LIBS="-ljava -ljvm"
@@ -49525,17 +50181,842 @@
JDKLIB_LIBS="$JDKLIB_LIBS -lc"
fi
- # When building a buildjdk, it's always only the server variant
+ fi
+
+ # Set JVM_LIBS (per os)
+ if test "x$OPENJDK_TARGET_OS" = xlinux; then
+ JVM_LIBS="$JVM_LIBS -lm -ldl -lpthread"
+ elif test "x$OPENJDK_TARGET_OS" = xsolaris; then
+ # FIXME: This hard-coded path is not really proper.
+ if test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+ SOLARIS_LIBM_LIBS="/usr/lib/amd64/libm.so.1"
+ elif test "x$OPENJDK_TARGET_CPU" = xsparcv9; then
+ SOLARIS_LIBM_LIBS="/usr/lib/sparcv9/libm.so.1"
+ fi
+ JVM_LIBS="$JVM_LIBS -lsocket -lsched -ldl $SOLARIS_LIBM_LIBS -lCrun \
+ -lthread -ldoor -lc -ldemangle -lnsl -lkstat -lrt"
+ elif test "x$OPENJDK_TARGET_OS" = xmacosx; then
+ JVM_LIBS="$JVM_LIBS -lm"
+ elif test "x$OPENJDK_TARGET_OS" = xaix; then
+ JVM_LIBS="$JVM_LIBS -Wl,-lC_r -lm -ldl -lpthread"
+ elif test "x$OPENJDK_TARGET_OS" = xbsd; then
+ JVM_LIBS="$JVM_LIBS -lm"
+ elif test "x$OPENJDK_TARGET_OS" = xwindows; then
+ JVM_LIBS="$JVM_LIBS kernel32.lib user32.lib gdi32.lib winspool.lib \
+ comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib \
+ wsock32.lib winmm.lib version.lib psapi.lib"
+ fi
+
+ # Set JVM_ASFLAGS
+ if test "x$OPENJDK_TARGET_OS" = xlinux; then
+ if test "x$OPENJDK_TARGET_CPU" = xx86; then
+ JVM_ASFLAGS="$JVM_ASFLAGS -march=i586"
+ fi
+ elif test "x$OPENJDK_TARGET_OS" = xmacosx; then
+ JVM_ASFLAGS="$JVM_ASFLAGS -x assembler-with-cpp -mno-omit-leaf-frame-pointer -mstack-alignment=16"
+ fi
+
+ LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} ${EXTRA_LDFLAGS_JDK}"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ # Special extras...
+ if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+ if test "x$OPENJDK_BUILD_CPU_ARCH" = "xsparc"; then
+ OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA="${OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA} -xregs=no%appl"
+ OPENJDK_BUILD_CXXFLAGS_JDKLIB_EXTRA="${OPENJDK_BUILD_CXXFLAGS_JDKLIB_EXTRA} -xregs=no%appl"
+ fi
+ OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA="${OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
+ OPENJDK_BUILD_CXXFLAGS_JDKLIB_EXTRA="${OPENJDK_BUILD_CXXFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
+ elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+ OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+ OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+ elif test "x$TOOLCHAIN_TYPE" = xgcc; then
+ OPENJDK_BUILD_CXXSTD_CXXFLAG="-std=gnu++98"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ # Execute function body
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the C++ compiler supports \"$OPENJDK_BUILD_CXXSTD_CXXFLAG -Werror\"" >&5
+$as_echo_n "checking if the C++ compiler supports \"$OPENJDK_BUILD_CXXSTD_CXXFLAG -Werror\"... " >&6; }
+ supports=yes
+
+ saved_cxxflags="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAG $OPENJDK_BUILD_CXXSTD_CXXFLAG -Werror"
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int i;
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+ supports=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ CXXFLAGS="$saved_cxxflags"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5
+$as_echo "$supports" >&6; }
+ if test "x$supports" = "xyes" ; then
+ :
+
+ else
+ :
+ OPENJDK_BUILD_CXXSTD_CXXFLAG=""
+ fi
+
+
+
+
+
+
+
+
+
+
+
+
+ OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} ${OPENJDK_BUILD_CXXSTD_CXXFLAG}"
+
+ fi
+ if test "x$OPENJDK_TARGET_OS" = xsolaris; then
+ OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -D__solaris__"
+ OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} -D__solaris__"
+ OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA='-xstrconst'
+ CFLAGS_JDK="${CFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+ CXXFLAGS_JDK="${CXXFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+ fi
+
+ if test "x$OPENJDK_TARGET_OS" = xsolaris; then
+ OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -D__solaris__"
+ OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} -D__solaris__"
+ OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA='-xstrconst'
+ fi
+
+ OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} ${OPENJDK_BUILD_EXTRA_CFLAGS}"
+ OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} ${OPENJDK_BUILD_EXTRA_CXXFLAGS}"
+ OPENJDK_BUILD_LDFLAGS_JDK="${OPENJDK_BUILD_LDFLAGS_JDK} ${OPENJDK_BUILD_EXTRA_LDFLAGS}"
+
+ ###############################################################################
+ #
+ # Now setup the CFLAGS and LDFLAGS for the JDK build.
+ # Later we will also have CFLAGS and LDFLAGS for the hotspot subrepo build.
+ #
+
+ # Setup compiler/platform specific flags into
+ # OPENJDK_BUILD_CFLAGS_JDK - C Compiler flags
+ # OPENJDK_BUILD_CXXFLAGS_JDK - C++ Compiler flags
+ # OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK - common to C and C++
+ if test "x$TOOLCHAIN_TYPE" = xgcc; then
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_GNU_SOURCE"
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_REENTRANT"
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -fcheck-new"
+ if test "x$OPENJDK_BUILD_CPU" = xx86; then
+ # Force compatibility with i586 on 32 bit intel platforms.
+ OPENJDK_BUILD_COMMON_CCXXFLAGS="${OPENJDK_BUILD_COMMON_CCXXFLAGS} -march=i586"
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -march=i586"
+ fi
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS $OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
+ -pipe -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
+ case $OPENJDK_BUILD_CPU_ARCH in
+ arm )
+ # on arm we don't prevent gcc to omit frame pointer but do prevent strict aliasing
+ OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
+ ;;
+ ppc )
+ # on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
+ OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
+ ;;
+ * )
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
+ OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
+ ;;
+ esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ # Execute function body
+
+ # Need to assign to a variable since m4 is blocked from modifying parts in [].
+ REFERENCE_VERSION=6
+
+ if [[ "$REFERENCE_VERSION" =~ (.*\.){3} ]] ; then
+ as_fn_error $? "Internal error: Cannot compare to 6, only three parts (X.Y.Z) is supported" "$LINENO" 5
+ fi
+
+ if [[ "$REFERENCE_VERSION" =~ [0-9]{6} ]] ; then
+ as_fn_error $? "Internal error: Cannot compare to 6, only parts < 99999 is supported" "$LINENO" 5
+ fi
+
+ # Version comparison method inspired by http://stackoverflow.com/a/24067243
+ COMPARABLE_REFERENCE_VERSION=`$AWK -F. '{ printf("%05d%05d%05d\n", $1, $2, $3) }' <<< "$REFERENCE_VERSION"`
+
+ if test $COMPARABLE_ACTUAL_VERSION -ge $COMPARABLE_REFERENCE_VERSION ; then
+ :
+
+ else
+ :
+
+ fi
+
+
+
+
+
+
+
+
+
+
+
+
+ elif test "x$TOOLCHAIN_TYPE" = xclang; then
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_GNU_SOURCE"
+
+ # Restrict the debug information created by Clang to avoid
+ # too big object files and speed the build up a little bit
+ # (see http://llvm.org/bugs/show_bug.cgi?id=7554)
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -flimit-debug-info"
+ if test "x$OPENJDK_BUILD_OS" = xlinux; then
+ if test "x$OPENJDK_BUILD_CPU" = xx86; then
+ # Force compatibility with i586 on 32 bit intel platforms.
+ OPENJDK_BUILD_COMMON_CCXXFLAGS="${OPENJDK_BUILD_COMMON_CCXXFLAGS} -march=i586"
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -march=i586"
+ fi
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wno-sometimes-uninitialized"
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS $OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
+ -pipe -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
+ case $OPENJDK_BUILD_CPU_ARCH in
+ ppc )
+ # on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
+ OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
+ ;;
+ * )
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
+ OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
+ ;;
+ esac
+ fi
+ elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DSPARC_WORKS"
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS $OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -DTRACING -DMACRO_MEMSYS_OPS -DBREAKPTS"
+ if test "x$OPENJDK_BUILD_CPU_ARCH" = xx86; then
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -DcpuIntel -Di586 -D$OPENJDK_BUILD_CPU_LEGACY_LIB"
+ fi
+
+ OPENJDK_BUILD_CFLAGS_JDK="$OPENJDK_BUILD_CFLAGS_JDK -xc99=%none -xCC -errshort=tags -Xa -v -mt -W0,-noglobal"
+ OPENJDK_BUILD_CXXFLAGS_JDK="$OPENJDK_BUILD_CXXFLAGS_JDK -errtags=yes +w -mt -features=no%except -DCC_NOEX -norunpath -xnolib"
+ elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_REENTRANT -D__STDC_FORMAT_MACROS"
+ OPENJDK_BUILD_CFLAGS_JDK="$OPENJDK_BUILD_CFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
+ OPENJDK_BUILD_CXXFLAGS_JDK="$OPENJDK_BUILD_CXXFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
+ elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS $OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK \
+ -MD -Zc:wchar_t- -W3 -wd4800 \
+ -DWIN32_LEAN_AND_MEAN \
+ -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE \
+ -D_WINSOCK_DEPRECATED_NO_WARNINGS \
+ -DWIN32 -DIAL"
+ if test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_AMD64_ -Damd64"
+ else
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_X86_ -Dx86"
+ fi
+ # If building with Visual Studio 2010, we can still use _STATIC_CPPLIB to
+ # avoid bundling msvcpNNN.dll. Doesn't work with newer versions of visual
+ # studio.
+ if test "x$TOOLCHAIN_VERSION" = "x2010"; then
+ STATIC_CPPLIB_FLAGS="-D_STATIC_CPPLIB -D_DISABLE_DEPRECATE_STATIC_CPPLIB"
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK $STATIC_CPPLIB_FLAGS"
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS $STATIC_CPPLIB_FLAGS"
+ fi
+ fi
+
+ ###############################################################################
+
+ # Adjust flags according to debug level.
+ case $DEBUG_LEVEL in
+ fastdebug | slowdebug )
+ OPENJDK_BUILD_CFLAGS_JDK="$OPENJDK_BUILD_CFLAGS_JDK $CFLAGS_DEBUG_SYMBOLS $CFLAGS_DEBUG_OPTIONS"
+ OPENJDK_BUILD_CXXFLAGS_JDK="$OPENJDK_BUILD_CXXFLAGS_JDK $CXXFLAGS_DEBUG_SYMBOLS $CXXFLAGS_DEBUG_OPTIONS"
+ JAVAC_FLAGS="$JAVAC_FLAGS -g"
+ ;;
+ release )
+ ;;
+ * )
+ as_fn_error $? "Unrecognized \$DEBUG_LEVEL: $DEBUG_LEVEL" "$LINENO" 5
+ ;;
+ esac
+
+ # Set some common defines. These works for all compilers, but assume
+ # -D is universally accepted.
+
+ # Setup endianness
+ if test "x$OPENJDK_BUILD_CPU_ENDIAN" = xlittle; then
+ # The macro _LITTLE_ENDIAN needs to be defined the same to avoid the
+ # Sun C compiler warning message: warning: macro redefined: _LITTLE_ENDIAN
+ # (The Solaris X86 system defines this in file /usr/include/sys/isa_defs.h).
+ # Note: -Dmacro is the same as #define macro 1
+ # -Dmacro= is the same as #define macro
+ if test "x$OPENJDK_BUILD_OS" = xsolaris; then
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_LITTLE_ENDIAN="
+ else
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_LITTLE_ENDIAN"
+ fi
+ else
+ # Same goes for _BIG_ENDIAN. Do we really need to set *ENDIAN on Solaris if they
+ # are defined in the system?
+ if test "x$OPENJDK_BUILD_OS" = xsolaris; then
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_BIG_ENDIAN="
+ else
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_BIG_ENDIAN"
+ fi
+ fi
+
+ # Setup target OS define. Use OS target name but in upper case.
+ OPENJDK_BUILD_OS_UPPERCASE=`$ECHO $OPENJDK_BUILD_OS | $TR 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D$OPENJDK_BUILD_OS_UPPERCASE"
+
+ # Setup target CPU
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK \
+ $OPENJDK_BUILD_ADD_LP64 \
+ -DARCH='\"$OPENJDK_BUILD_CPU_LEGACY\"' -D$OPENJDK_BUILD_CPU_LEGACY"
+
+ # Setup debug/release defines
+ if test "x$DEBUG_LEVEL" = xrelease; then
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -DNDEBUG"
+ if test "x$OPENJDK_BUILD_OS" = xsolaris; then
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -DTRIMMED"
+ fi
+ else
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -DDEBUG"
+ fi
+
+ # Set some additional per-OS defines.
+ if test "x$OPENJDK_BUILD_OS" = xlinux; then
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DLINUX"
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -pipe -fPIC -fno-rtti -fno-exceptions \
+ -fvisibility=hidden -fno-strict-aliasing -fno-omit-frame-pointer"
+ elif test "x$OPENJDK_BUILD_OS" = xsolaris; then
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DSOLARIS"
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -template=no%extdef -features=no%split_init \
+ -D_Crun_inline_placement -library=%none -KPIC -mt -xwe -features=no%except"
+ elif test "x$OPENJDK_BUILD_OS" = xmacosx; then
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_ALLBSD_SOURCE"
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_DARWIN_C_SOURCE -D_XOPEN_SOURCE"
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -fno-rtti -fno-exceptions -fvisibility=hidden \
+ -mno-omit-leaf-frame-pointer -mstack-alignment=16 -pipe -fno-strict-aliasing \
+ -DMAC_OS_X_VERSION_MAX_ALLOWED=1070 -mmacosx-version-min=10.7.0 \
+ -fno-omit-frame-pointer"
+ elif test "x$OPENJDK_BUILD_OS" = xaix; then
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DAIX"
+ # We may need '-qminimaltoc' or '-qpic=large -bbigtoc' if the TOC overflows.
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -qtune=balanced -qhot=level=1 -qinline \
+ -qinlglue -qalias=noansi -qstrict -qtls=default -qlanglvl=c99vla \
+ -qlanglvl=noredefmac -qnortti -qnoeh -qignerrno"
+ elif test "x$OPENJDK_BUILD_OS" = xbsd; then
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE"
+ elif test "x$OPENJDK_BUILD_OS" = xwindows; then
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_WINDOWS -DWIN32 -D_JNI_IMPLEMENTATION_"
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -nologo -W3 -MD -MP"
+ fi
+
+ # Set some additional per-CPU defines.
+ if test "x$OPENJDK_BUILD_OS-$OPENJDK_BUILD_CPU" = xwindows-x86; then
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -arch:IA32"
+ elif test "x$OPENJDK_BUILD_CPU" = xsparcv9; then
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -xarch=sparc"
+ elif test "x$OPENJDK_BUILD_CPU" = xppc64; then
+ if test "x$OPENJDK_BUILD_OS" = xlinux; then
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -minsert-sched-nops=regroup_exact -mno-multiple -mno-string"
+ # fixes `relocation truncated to fit' error for gcc 4.1.
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -mminimal-toc"
+ # Use ppc64 instructions, but schedule for power5
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -mcpu=powerpc64 -mtune=power5"
+ elif test "x$OPENJDK_BUILD_OS" = xaix; then
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -qarch=ppc64"
+ fi
+ elif test "x$OPENJDK_BUILD_CPU" = xppc64le; then
+ if test "x$OPENJDK_BUILD_OS" = xlinux; then
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -minsert-sched-nops=regroup_exact -mno-multiple -mno-string"
+ # Little endian machine uses ELFv2 ABI.
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DABI_ELFv2"
+ # Use Power8, this is the first CPU to support PPC64 LE with ELFv2 ABI.
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -mcpu=power7 -mtune=power8"
+ fi
+ fi
+
+ if test "x$OPENJDK_BUILD_CPU_ENDIAN" = xlittle; then
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DVM_LITTLE_ENDIAN"
+ fi
+
+ if test "x$OPENJDK_BUILD_CPU_BITS" = x64; then
+ if test "x$OPENJDK_BUILD_OS" != xsolaris && test "x$OPENJDK_BUILD_OS" != xaix; then
+ # Solaris does not have _LP64=1 in the old build.
+ # xlc on AIX defines _LP64=1 by default and issues a warning if we redefine it.
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_LP64=1"
+ fi
+ fi
+
+ # Set OPENJDK_BUILD_JVM_CFLAGS warning handling
+ if test "x$OPENJDK_BUILD_OS" = xlinux; then
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wpointer-arith -Wsign-compare -Wunused-function \
+ -Wunused-value -Woverloaded-virtual"
+
+ if test "x$TOOLCHAIN_TYPE" = xgcc; then
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ # Execute function body
+
+ # Need to assign to a variable since m4 is blocked from modifying parts in [].
+ REFERENCE_VERSION=4.8
+
+ if [[ "$REFERENCE_VERSION" =~ (.*\.){3} ]] ; then
+ as_fn_error $? "Internal error: Cannot compare to 4.8, only three parts (X.Y.Z) is supported" "$LINENO" 5
+ fi
+
+ if [[ "$REFERENCE_VERSION" =~ [0-9]{6} ]] ; then
+ as_fn_error $? "Internal error: Cannot compare to 4.8, only parts < 99999 is supported" "$LINENO" 5
+ fi
+
+ # Version comparison method inspired by http://stackoverflow.com/a/24067243
+ COMPARABLE_REFERENCE_VERSION=`$AWK -F. '{ printf("%05d%05d%05d\n", $1, $2, $3) }' <<< "$REFERENCE_VERSION"`
+
+ if test $COMPARABLE_ACTUAL_VERSION -ge $COMPARABLE_REFERENCE_VERSION ; then
+ :
+
+ # These flags either do not work or give spurious warnings prior to gcc 4.8.
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wno-format-zero-length -Wtype-limits -Wuninitialized"
+
+
+ else
+ :
+
+ fi
+
+
+
+
+
+
+
+
+
+
+
+
+ fi
+ if ! [[ " $JVM_VARIANTS " =~ " zero " ]] && ! [[ " $JVM_VARIANTS " =~ " zeroshark " ]] ; then
+ # Non-zero builds have stricter warnings
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wreturn-type -Wundef -Wformat=2"
+ else
+ if test "x$TOOLCHAIN_TYPE" = xclang; then
+ # Some versions of llvm do not like -Wundef
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wno-undef"
+ fi
+ fi
+ elif test "x$OPENJDK_BUILD_OS" = xmacosx; then
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wno-deprecated -Wpointer-arith \
+ -Wsign-compare -Wundef -Wunused-function -Wformat=2"
+ fi
+
+ # Additional macosx handling
+ if test "x$OPENJDK_BUILD_OS" = xmacosx; then
+ # Setting these parameters makes it an error to link to macosx APIs that are
+ # newer than the given OS version and makes the linked binaries compatible
+ # even if built on a newer version of the OS.
+ # The expected format is X.Y.Z
+ MACOSX_VERSION_MIN=10.7.0
+
+
+ # The macro takes the version with no dots, ex: 1070
+ # Let the flags variables get resolved in make for easier override on make
+ # command line.
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -DMAC_OS_X_VERSION_MAX_ALLOWED=\$(subst .,,\$(MACOSX_VERSION_MIN)) -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
+ OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
+ fi
+
+ # Setup some hard coded includes
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK \
+ -I${JDK_TOPDIR}/src/java.base/share/native/include \
+ -I${JDK_TOPDIR}/src/java.base/$OPENJDK_BUILD_OS/native/include \
+ -I${JDK_TOPDIR}/src/java.base/$OPENJDK_BUILD_OS_TYPE/native/include \
+ -I${JDK_TOPDIR}/src/java.base/share/native/libjava \
+ -I${JDK_TOPDIR}/src/java.base/$OPENJDK_BUILD_OS_TYPE/native/libjava"
+
+ # The shared libraries are compiled using the picflag.
+ OPENJDK_BUILD_CFLAGS_JDKLIB="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK \
+ $OPENJDK_BUILD_CFLAGS_JDK $OPENJDK_BUILD_EXTRA_CFLAGS_JDK $PICFLAG $OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA"
+ OPENJDK_BUILD_CXXFLAGS_JDKLIB="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK \
+ $OPENJDK_BUILD_CXXFLAGS_JDK $OPENJDK_BUILD_EXTRA_CXXFLAGS_JDK $PICFLAG $OPENJDK_BUILD_CXXFLAGS_JDKLIB_EXTRA"
+
+ # Executable flags
+ OPENJDK_BUILD_CFLAGS_JDKEXE="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CFLAGS_JDK $OPENJDK_BUILD_EXTRA_CFLAGS_JDK"
+ OPENJDK_BUILD_CXXFLAGS_JDKEXE="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CXXFLAGS_JDK $OPENJDK_BUILD_EXTRA_CXXFLAGS_JDK"
+
+
+
+
+
+
+ # Setup LDFLAGS et al.
+ #
+
+ if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+ LDFLAGS_MICROSOFT="-nologo -opt:ref"
+ OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK $LDFLAGS_MICROSOFT -incremental:no"
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_MICROSOFT -opt:icf,8 -subsystem:windows -base:0x8000000"
+ if test "x$OPENJDK_BUILD_CPU_BITS" = "x32"; then
+ LDFLAGS_SAFESH="-safeseh"
+ OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK $LDFLAGS_SAFESH"
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_SAFESH"
+ # NOTE: Old build added -machine. Probably not needed.
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -machine:I386"
+ else
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -machine:AMD64"
+ fi
+ elif test "x$TOOLCHAIN_TYPE" = xclang; then
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -mno-omit-leaf-frame-pointer -mstack-alignment=16 -stdlib=libstdc++ -fPIC"
+ if test "x$OPENJDK_BUILD_OS" = xmacosx; then
+ # FIXME: We should really generalize SET_SHARED_LIBRARY_ORIGIN instead.
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
+ fi
+ elif test "x$TOOLCHAIN_TYPE" = xgcc; then
+ # If this is a --hash-style=gnu system, use --hash-style=both, why?
+ # We have previously set HAS_GNU_HASH if this is the case
+ if test -n "$HAS_GNU_HASH"; then
+ OPENJDK_BUILD_LDFLAGS_HASH_STYLE="-Wl,--hash-style=both"
+ OPENJDK_BUILD_LDFLAGS_JDK="${OPENJDK_BUILD_LDFLAGS_JDK} $OPENJDK_BUILD_LDFLAGS_HASH_STYLE"
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $OPENJDK_BUILD_LDFLAGS_HASH_STYLE"
+ fi
+ if test "x$OPENJDK_BUILD_OS" = xmacosx; then
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
+ fi
+ if test "x$OPENJDK_BUILD_OS" = xlinux; then
+ # And since we now know that the linker is gnu, then add -z defs, to forbid
+ # undefined symbols in object files.
+ LDFLAGS_NO_UNDEF_SYM="-Wl,-z,defs"
+ OPENJDK_BUILD_LDFLAGS_JDK="${OPENJDK_BUILD_LDFLAGS_JDK} $LDFLAGS_NO_UNDEF_SYM"
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_NO_UNDEF_SYM"
+ LDFLAGS_NO_EXEC_STACK="-Wl,-z,noexecstack"
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_NO_EXEC_STACK"
+ if test "x$OPENJDK_BUILD_CPU" = xx86; then
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -march=i586"
+ fi
+ case $DEBUG_LEVEL in
+ release )
+ # tell linker to optimize libraries.
+ # Should this be supplied to the OSS linker as well?
+ LDFLAGS_DEBUGLEVEL_release="-Wl,-O1"
+ OPENJDK_BUILD_LDFLAGS_JDK="${OPENJDK_BUILD_LDFLAGS_JDK} $LDFLAGS_DEBUGLEVEL_release"
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_DEBUGLEVEL_release"
+ if test "x$HAS_LINKER_RELRO" = "xtrue"; then
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LINKER_RELRO_FLAG"
+ fi
+ ;;
+ slowdebug )
+ # Hotspot always let the linker optimize
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -Wl,-O1"
+ if test "x$HAS_LINKER_NOW" = "xtrue"; then
+ # do relocations at load
+ OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK $LINKER_NOW_FLAG"
+ OPENJDK_BUILD_LDFLAGS_CXX_JDK="$OPENJDK_BUILD_LDFLAGS_CXX_JDK $LINKER_NOW_FLAG"
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LINKER_NOW_FLAG"
+ fi
+ if test "x$HAS_LINKER_RELRO" = "xtrue"; then
+ # mark relocations read only
+ OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK $LINKER_RELRO_FLAG"
+ OPENJDK_BUILD_LDFLAGS_CXX_JDK="$OPENJDK_BUILD_LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LINKER_RELRO_FLAG"
+ fi
+ ;;
+ fastdebug )
+ # Hotspot always let the linker optimize
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -Wl,-O1"
+ if test "x$HAS_LINKER_RELRO" = "xtrue"; then
+ # mark relocations read only
+ OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK $LINKER_RELRO_FLAG"
+ OPENJDK_BUILD_LDFLAGS_CXX_JDK="$OPENJDK_BUILD_LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LINKER_RELRO_FLAG"
+ fi
+ ;;
+ * )
+ as_fn_error $? "Unrecognized \$DEBUG_LEVEL: $DEBUG_LEVEL" "$LINENO" 5
+ ;;
+ esac
+ fi
+ elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+ LDFLAGS_SOLSTUDIO="-Wl,-z,defs"
+ OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK $LDFLAGS_SOLSTUDIO -xildoff -ztext"
+ LDFLAGS_CXX_SOLSTUDIO="-norunpath"
+ OPENJDK_BUILD_LDFLAGS_CXX_JDK="$OPENJDK_BUILD_LDFLAGS_CXX_JDK $LDFLAGS_CXX_SOLSTUDIO -xnolib"
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_SOLSTUDIO -library=%none -mt $LDFLAGS_CXX_SOLSTUDIO -z noversion"
+ if test "x$OPENJDK_BUILD_CPU_ARCH" = "xsparc"; then
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -xarch=sparc"
+ fi
+ elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+ LDFLAGS_XLC="-b64 -brtl -bnolibpath -bexpall -bernotok"
+ OPENJDK_BUILD_LDFLAGS_JDK="${OPENJDK_BUILD_LDFLAGS_JDK} $LDFLAGS_XLC"
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_XLC"
+ fi
+
+ # Customize LDFLAGS for executables
+
+ OPENJDK_BUILD_LDFLAGS_JDKEXE="${OPENJDK_BUILD_LDFLAGS_JDK}"
+
+ if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+ if test "x$OPENJDK_BUILD_CPU_BITS" = "x64"; then
+ LDFLAGS_STACK_SIZE=1048576
+ else
+ LDFLAGS_STACK_SIZE=327680
+ fi
+ OPENJDK_BUILD_LDFLAGS_JDKEXE="${OPENJDK_BUILD_LDFLAGS_JDKEXE} /STACK:$LDFLAGS_STACK_SIZE"
+ elif test "x$OPENJDK_BUILD_OS" = xlinux; then
+ OPENJDK_BUILD_LDFLAGS_JDKEXE="$OPENJDK_BUILD_LDFLAGS_JDKEXE -Wl,--allow-shlib-undefined"
+ fi
+
+ OPENJDK_BUILD_LDFLAGS_JDKEXE="${OPENJDK_BUILD_LDFLAGS_JDKEXE} ${OPENJDK_BUILD_EXTRA_LDFLAGS_JDK}"
+
+ # Customize LDFLAGS for libs
+ OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDK}"
+
+ OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} ${SHARED_LIBRARY_FLAGS}"
+ if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} \
- -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
- fi
-
- OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} ${LDFLAGS_JDKLIB}"
- LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} ${EXTRA_LDFLAGS_JDK}"
-
-
-
-
+ -libpath:${OUTPUT_ROOT}/support/modules_libs/java.base"
+ OPENJDK_BUILD_JDKLIB_LIBS=""
+ else
+ OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} \
+ -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)"
+
+ if test "xBUILD" = "xTARGET"; then
+ # On some platforms (mac) the linker warns about non existing -L dirs.
+ # Add server first if available. Linking aginst client does not always produce the same results.
+ # Only add client/minimal dir if client/minimal is being built.
+ # Default to server for other variants.
+ if [[ " $JVM_VARIANTS " =~ " server " ]] ; then
+ OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/server"
+ elif [[ " $JVM_VARIANTS " =~ " client " ]] ; then
+ OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/client"
+ elif [[ " $JVM_VARIANTS " =~ " minimal " ]] ; then
+ OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/minimal"
+ else
+ OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/server"
+ fi
+ elif test "xBUILD" = "xBUILD"; then
+ # When building a buildjdk, it's always only the server variant
+ OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} \
+ -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/server"
+ fi
+
+ OPENJDK_BUILD_JDKLIB_LIBS="-ljava -ljvm"
+ if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+ OPENJDK_BUILD_JDKLIB_LIBS="$OPENJDK_BUILD_JDKLIB_LIBS -lc"
+ fi
+
+ fi
+
+ # Set OPENJDK_BUILD_JVM_LIBS (per os)
+ if test "x$OPENJDK_BUILD_OS" = xlinux; then
+ OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS -lm -ldl -lpthread"
+ elif test "x$OPENJDK_BUILD_OS" = xsolaris; then
+ # FIXME: This hard-coded path is not really proper.
+ if test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+ OPENJDK_BUILD_SOLARIS_LIBM_LIBS="/usr/lib/amd64/libm.so.1"
+ elif test "x$OPENJDK_BUILD_CPU" = xsparcv9; then
+ OPENJDK_BUILD_SOLARIS_LIBM_LIBS="/usr/lib/sparcv9/libm.so.1"
+ fi
+ OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS -lsocket -lsched -ldl $SOLARIS_LIBM_LIBS -lCrun \
+ -lthread -ldoor -lc -ldemangle -lnsl -lkstat -lrt"
+ elif test "x$OPENJDK_BUILD_OS" = xmacosx; then
+ OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS -lm"
+ elif test "x$OPENJDK_BUILD_OS" = xaix; then
+ OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS -Wl,-lC_r -lm -ldl -lpthread"
+ elif test "x$OPENJDK_BUILD_OS" = xbsd; then
+ OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS -lm"
+ elif test "x$OPENJDK_BUILD_OS" = xwindows; then
+ OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS kernel32.lib user32.lib gdi32.lib winspool.lib \
+ comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib \
+ wsock32.lib winmm.lib version.lib psapi.lib"
+ fi
+
+ # Set OPENJDK_BUILD_JVM_ASFLAGS
+ if test "x$OPENJDK_BUILD_OS" = xlinux; then
+ if test "x$OPENJDK_BUILD_CPU" = xx86; then
+ OPENJDK_BUILD_JVM_ASFLAGS="$OPENJDK_BUILD_JVM_ASFLAGS -march=i586"
+ fi
+ elif test "x$OPENJDK_BUILD_OS" = xmacosx; then
+ OPENJDK_BUILD_JVM_ASFLAGS="$OPENJDK_BUILD_JVM_ASFLAGS -x assembler-with-cpp -mno-omit-leaf-frame-pointer -mstack-alignment=16"
+ fi
+
+ OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} ${OPENJDK_BUILD_EXTRA_LDFLAGS_JDK}"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ # Tests are only ever compiled for TARGET
+ # Flags for compiling test libraries
+ CFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
+ CXXFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
+
+ # Flags for compiling test executables
+ CFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK"
+ CXXFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK"
@@ -49549,6 +51030,7 @@
+
# Some Zero and Shark settings.
# ZERO_ARCHFLAG tells the compiler which mode to build for
case "${OPENJDK_TARGET_CPU}" in
@@ -50897,6 +52379,222 @@
+# Need toolchain to setup dtrace
+
+ # Test for dtrace dependencies
+ # Check whether --enable-dtrace was given.
+if test "${enable_dtrace+set}" = set; then :
+ enableval=$enable_dtrace;
+fi
+
+
+ DTRACE_DEP_MISSING=false
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dtrace tool" >&5
+$as_echo_n "checking for dtrace tool... " >&6; }
+ if test "x$DTRACE" != "x" && test -x "$DTRACE"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5
+$as_echo "$DTRACE" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found, cannot build dtrace" >&5
+$as_echo "not found, cannot build dtrace" >&6; }
+ DTRACE_DEP_MISSING=true
+ fi
+
+ for ac_header in sys/sdt.h
+do :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "sys/sdt.h" "ac_cv_header_sys_sdt_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_sdt_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_SDT_H 1
+_ACEOF
+ DTRACE_HEADERS_OK=yes
+else
+ DTRACE_HEADERS_OK=no
+fi
+
+done
+
+ if test "x$DTRACE_HEADERS_OK" != "xyes"; then
+ DTRACE_DEP_MISSING=true
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if dtrace should be built" >&5
+$as_echo_n "checking if dtrace should be built... " >&6; }
+ if test "x$enable_dtrace" = "xyes"; then
+ if test "x$DTRACE_DEP_MISSING" = "xtrue"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, missing dependencies" >&5
+$as_echo "no, missing dependencies" >&6; }
+
+ # Print a helpful message on how to acquire the necessary build dependency.
+ # dtrace is the help tag: freetype, cups, alsa etc
+ MISSING_DEPENDENCY=dtrace
+
+ 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 ;;
+ 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 $? "Cannot enable dtrace with missing dependencies. See above. $HELP_MSG" "$LINENO" 5
+ else
+ INCLUDE_DTRACE=true
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, forced" >&5
+$as_echo "yes, forced" >&6; }
+ fi
+ elif test "x$enable_dtrace" = "xno"; then
+ INCLUDE_DTRACE=false
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, forced" >&5
+$as_echo "no, forced" >&6; }
+ elif test "x$enable_dtrace" = "xauto" || test "x$enable_dtrace" = "x"; then
+ if test "x$OPENJDK_TARGET_OS" = "xlinux" && test "x$OPENJDK" != "xtrue"; then
+ INCLUDE_DTRACE=false
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, non-open linux build" >&5
+$as_echo "no, non-open linux build" >&6; }
+ elif test "x$DTRACE_DEP_MISSING" = "xtrue"; then
+ INCLUDE_DTRACE=false
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, missing dependencies" >&5
+$as_echo "no, missing dependencies" >&6; }
+ else
+ INCLUDE_DTRACE=true
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, dependencies present" >&5
+$as_echo "yes, dependencies present" >&6; }
+ fi
+ else
+ as_fn_error $? "Invalid value for --enable-dtrace: $enable_dtrace" "$LINENO" 5
+ fi
+
+
+
+ # The user can in some cases supply additional jvm features. For the custom
+ # variant, this defines the entire variant.
+
+# Check whether --with-jvm-features was given.
+if test "${with_jvm_features+set}" = set; then :
+ withval=$with_jvm_features;
+fi
+
+ if test "x$with_jvm_features" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking additional JVM features" >&5
+$as_echo_n "checking additional JVM features... " >&6; }
+ JVM_FEATURES=`$ECHO $with_jvm_features | $SED -e 's/,/ /g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JVM_FEATURES" >&5
+$as_echo "$JVM_FEATURES" >&6; }
+ fi
+
+ # Verify that dependencies are met for explicitly set features.
+ if [[ " $JVM_FEATURES " =~ " jvmti " ]] && ! [[ " $JVM_FEATURES " =~ " services " ]] ; then
+ as_fn_error $? "Specified JVM feature 'jvmti' requires feature 'services'" "$LINENO" 5
+ fi
+
+ if [[ " $JVM_FEATURES " =~ " management " ]] && ! [[ " $JVM_FEATURES " =~ " nmt " ]] ; then
+ as_fn_error $? "Specified JVM feature 'management' requires feature 'nmt'" "$LINENO" 5
+ fi
+
+ if [[ " $JVM_FEATURES " =~ " jvmci " ]] && ! [[ " $JVM_FEATURES " =~ " compiler2 " ]] ; then
+ as_fn_error $? "Specified JVM feature 'jvmci' requires feature 'compiler2'" "$LINENO" 5
+ fi
+
+ if [[ " $JVM_FEATURES " =~ " compiler2 " ]] && ! [[ " $JVM_FEATURES " =~ " all-gcs " ]] ; then
+ as_fn_error $? "Specified JVM feature 'compiler2' requires feature 'all-gcs'" "$LINENO" 5
+ fi
+
+ if [[ " $JVM_FEATURES " =~ " vm-structs " ]] && ! [[ " $JVM_FEATURES " =~ " all-gcs " ]] ; then
+ as_fn_error $? "Specified JVM feature 'vm-structs' requires feature 'all-gcs'" "$LINENO" 5
+ fi
+
+ # Turn on additional features based on other parts of configure
+ if test "x$INCLUDE_DTRACE" = "xtrue"; then
+ JVM_FEATURES="$JVM_FEATURES dtrace"
+ else
+ if [[ " $JVM_FEATURES " =~ " dtrace " ]] ; then
+ as_fn_error $? "To enable dtrace, you must use --enable-dtrace" "$LINENO" 5
+ fi
+ fi
+
+ if test "x$STATIC_BUILD" = "xtrue"; then
+ JVM_FEATURES="$JVM_FEATURES static-build"
+ else
+ if [[ " $JVM_FEATURES " =~ " static-build " ]] ; then
+ as_fn_error $? "To enable static-build, you must use --enable-static-build" "$LINENO" 5
+ fi
+ fi
+
+ if ! [[ " $JVM_VARIANTS " =~ " zero " ]] && ! [[ " $JVM_VARIANTS " =~ " zeroshark " ]] ; then
+ if [[ " $JVM_FEATURES " =~ " zero " ]] ; then
+ as_fn_error $? "To enable zero/zeroshark, you must use --with-jvm-variants=zero/zeroshark" "$LINENO" 5
+ fi
+ fi
+
+ if ! [[ " $JVM_VARIANTS " =~ " zeroshark " ]] ; then
+ if [[ " $JVM_FEATURES " =~ " shark " ]] ; then
+ as_fn_error $? "To enable shark, you must use --with-jvm-variants=zeroshark" "$LINENO" 5
+ fi
+ fi
+
+ # Only enable jvmci on x86_64, sparcv9 and aarch64, and only on server.
+ if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || \
+ test "x$OPENJDK_TARGET_CPU" = "xsparcv9" || \
+ test "x$OPENJDK_TARGET_CPU" = "xaarch64" ; then
+ JVM_FEATURES_jvmci="jvmci"
+ else
+ JVM_FEATURES_jvmci=""
+ fi
+
+ # All variants but minimal (and custom) get these features
+ NON_MINIMAL_FEATURES="$NON_MINIMAL_FEATURES jvmti fprof vm-structs jni-check services management all-gcs nmt cds"
+
+ # Enable features depending on variant.
+ JVM_FEATURES_server="compiler1 compiler2 $NON_MINIMAL_FEATURES $JVM_FEATURES $JVM_FEATURES_jvmci"
+ JVM_FEATURES_client="compiler1 $NON_MINIMAL_FEATURES $JVM_FEATURES"
+ JVM_FEATURES_core="$NON_MINIMAL_FEATURES $JVM_FEATURES"
+ JVM_FEATURES_minimal="compiler1 minimal $JVM_FEATURES"
+ JVM_FEATURES_zero="zero $NON_MINIMAL_FEATURES $JVM_FEATURES"
+ JVM_FEATURES_zeroshark="zero shark $NON_MINIMAL_FEATURES $JVM_FEATURES"
+ JVM_FEATURES_custom="$JVM_FEATURES"
+
+
+
+
+
+
+
+
+
+ # Used for verification of Makefiles by check-jvm-feature
+
+
+ # We don't support --with-jvm-interpreter anymore, use zero instead.
+
+
+# Check whether --with-jvm-interpreter was given.
+if test "${with_jvm_interpreter+set}" = set; then :
+ withval=$with_jvm_interpreter; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-jvm-interpreter is deprecated and will be ignored." >&5
+$as_echo "$as_me: WARNING: Option --with-jvm-interpreter is deprecated and will be ignored." >&2;}
+fi
+
+
+
+
###############################################################################
#
# Check dependencies for external and internal libraries.
@@ -51023,7 +52721,7 @@
fi
# Check if ffi is needed
- if test "x$JVM_VARIANT_ZERO" = xtrue || test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+ if [[ " $JVM_VARIANTS " =~ " zero " ]] || [[ " $JVM_VARIANTS " =~ " zeroshark " ]] ; then
NEEDS_LIB_FFI=true
else
NEEDS_LIB_FFI=false
@@ -51146,14 +52844,26 @@
# If dynamic wasn't requested, go with static unless it isn't available.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libstdc++" >&5
$as_echo_n "checking how to link with libstdc++... " >&6; }
- if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno || test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+ if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno || [[ " $JVM_VARIANTS " =~ " zeroshark " ]] ; then
LIBCXX="$LIBCXX -lstdc++"
+ # To help comparisons with old build, put stdc++ first in JVM_LIBS
+ JVM_LIBS="-lstdc++ $JVM_LIBS"
+ # Ideally, we should test stdc++ for the BUILD toolchain separately. For now
+ # just use the same setting as for the TARGET toolchain.
+ OPENJDK_BUILD_JVM_LIBS="-lstdc++ $OPENJDK_BUILD_JVM_LIBS"
LDCXX="$CXX"
STATIC_CXX_SETTING="STATIC_CXX=false"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: dynamic" >&5
$as_echo "dynamic" >&6; }
else
LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS"
+ JVM_LDFLAGS="$JVM_LDFLAGS -static-libgcc"
+ # To help comparisons with old build, put stdc++ first in JVM_LIBS
+ JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $JVM_LIBS"
+ # Ideally, we should test stdc++ for the BUILD toolchain separately. For now
+ # just use the same setting as for the TARGET toolchain.
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -static-libgcc"
+ OPENJDK_BUILD_JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $OPENJDK_BUILD_JVM_LIBS"
LDCXX="$CC"
STATIC_CXX_SETTING="STATIC_CXX=true"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
@@ -61305,7 +63015,7 @@
- if test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+ if [[ " $JVM_VARIANTS " =~ " zeroshark " ]] ; then
# Extract the first word of "llvm-config", so it can be a program name with args.
set dummy llvm-config; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@@ -62031,9 +63741,143 @@
###############################################################################
+ # Check whether --enable-new-hotspot-build was given.
+if test "${enable_new_hotspot_build+set}" = set; then :
+ enableval=$enable_new_hotspot_build;
+fi
+
+
+ if test "x$enable_new_hotspot_build" = "x" || test "x$enable_new_hotspot_build" = "xyes"; then
+ USE_NEW_HOTSPOT_BUILD=true
+ else
+ USE_NEW_HOTSPOT_BUILD=false
+ fi
+
+
+ case $HOTSPOT_DEBUG_LEVEL in
+ product )
+ VARIANT="OPT"
+ FASTDEBUG="false"
+ DEBUG_CLASSFILES="false"
+ ;;
+ fastdebug )
+ VARIANT="DBG"
+ FASTDEBUG="true"
+ DEBUG_CLASSFILES="true"
+ ;;
+ debug )
+ VARIANT="DBG"
+ FASTDEBUG="false"
+ DEBUG_CLASSFILES="true"
+ ;;
+ optimized )
+ VARIANT="OPT"
+ FASTDEBUG="false"
+ DEBUG_CLASSFILES="false"
+ ;;
+ esac
+
+
+
+
+ if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
+ MACOSX_UNIVERSAL="true"
+ fi
+
+
+
+ # Make sure JVM_VARIANTS_COMMA use minimal1 for backwards compatibility
+ JVM_VARIANTS_COMMA=`$ECHO ,$JVM_VARIANTS_OPT, | $SED -e 's/,minimal,/,minimal1,/'`
+
+ JVM_VARIANT_SERVER=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,server,/!s/.*/false/g' -e '/,server,/s/.*/true/g'`
+ JVM_VARIANT_CLIENT=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,client,/!s/.*/false/g' -e '/,client,/s/.*/true/g'`
+ JVM_VARIANT_MINIMAL1=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,minimal1\?,/!s/.*/false/g' -e '/,minimal1\?,/s/.*/true/g'`
+ JVM_VARIANT_CORE=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,core,/!s/.*/false/g' -e '/,core,/s/.*/true/g'`
+ JVM_VARIANT_ZERO=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,zero,/!s/.*/false/g' -e '/,zero,/s/.*/true/g'`
+ JVM_VARIANT_ZEROSHARK=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,zeroshark,/!s/.*/false/g' -e '/,zeroshark,/s/.*/true/g'`
+ JVM_VARIANT_CUSTOM=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,custom,/!s/.*/false/g' -e '/,custom,/s/.*/true/g'`
+
+ #####
+ # Generate the legacy makefile targets for hotspot.
+ HOTSPOT_TARGET=""
+
+ if test "x$JVM_VARIANT_SERVER" = xtrue; then
+ HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL} "
+ fi
+
+ if test "x$JVM_VARIANT_CLIENT" = xtrue; then
+ HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}1 "
+ fi
+
+ if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
+ HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}minimal1 "
+ fi
+
+ if test "x$JVM_VARIANT_ZERO" = xtrue; then
+ HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}zero "
+ fi
+
+ if test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+ HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}shark "
+ fi
+
+ if test "x$JVM_VARIANT_CORE" = xtrue; then
+ HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}core "
+ fi
+
+ HOTSPOT_TARGET="$HOTSPOT_TARGET docs export_$HOTSPOT_DEBUG_LEVEL"
+
+ # On Macosx universal binaries are produced, but they only contain
+ # 64 bit intel. This invalidates control of which jvms are built
+ # from configure, but only server is valid anyway. Fix this
+ # when hotspot makefiles are rewritten.
+ if test "x$MACOSX_UNIVERSAL" = xtrue; then
+ HOTSPOT_TARGET=universal_${HOTSPOT_DEBUG_LEVEL}
+ fi
+
HOTSPOT_MAKE_ARGS="$HOTSPOT_TARGET"
+ # Control wether Hotspot runs Queens test after build.
+ # Check whether --enable-hotspot-test-in-build was given.
+if test "${enable_hotspot_test_in_build+set}" = set; then :
+ enableval=$enable_hotspot_test_in_build;
+else
+ enable_hotspot_test_in_build=no
+fi
+
+ if test "x$enable_hotspot_test_in_build" = "xyes"; then
+ TEST_IN_BUILD=true
+ else
+ TEST_IN_BUILD=false
+ fi
+
+
+ if test "x$USE_NEW_HOTSPOT_BUILD" = xfalse; then
+ if test "x$JVM_VARIANT_CLIENT" = xtrue; then
+ if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+ as_fn_error $? "You cannot build a client JVM for a 64-bit machine." "$LINENO" 5
+ fi
+ fi
+ if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
+ if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+ as_fn_error $? "You cannot build a minimal JVM for a 64-bit machine." "$LINENO" 5
+ fi
+ fi
+ if test "x$JVM_VARIANT_CUSTOM" = xtrue; then
+ as_fn_error $? "You cannot build a custom JVM using the old hotspot build system." "$LINENO" 5
+ fi
+ fi
+
+
+
+
+
+
+
+
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if elliptic curve crypto implementation is present" >&5
$as_echo_n "checking if elliptic curve crypto implementation is present... " >&6; }
@@ -63322,6 +65166,10 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no, does not work effectively with icecc" >&5
$as_echo "no, does not work effectively with icecc" >&6; }
USE_PRECOMPILED_HEADER=0
+ elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, does not work with Solaris Studio" >&5
+$as_echo "no, does not work with Solaris Studio" >&6; }
+ USE_PRECOMPILED_HEADER=0
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
@@ -63742,6 +65590,32 @@
# At the end, call the custom hook. (Dummy macro if no custom sources available)
+# This needs to be done after CUSTOM_LATE_HOOK since we can setup custom features.
+
+ # Keep feature lists sorted and free of duplicates
+ JVM_FEATURES_server="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_server | $SORT -u))"
+ JVM_FEATURES_client="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_client | $SORT -u))"
+ JVM_FEATURES_core="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_core | $SORT -u))"
+ JVM_FEATURES_minimal="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_minimal | $SORT -u))"
+ JVM_FEATURES_zero="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_zero | $SORT -u))"
+ JVM_FEATURES_zeroshark="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_zeroshark | $SORT -u))"
+ JVM_FEATURES_custom="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_custom | $SORT -u))"
+
+ # Validate features
+ for variant in $JVM_VARIANTS; do
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking JVM features for JVM variant '$variant'" >&5
+$as_echo_n "checking JVM features for JVM variant '$variant'... " >&6; }
+ features_var_name=JVM_FEATURES_$variant
+ JVM_FEATURES_TO_TEST=${!features_var_name}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JVM_FEATURES_TO_TEST" >&5
+$as_echo "$JVM_FEATURES_TO_TEST" >&6; }
+ INVALID_FEATURES=`$GREP -Fvx "${VALID_JVM_FEATURES// /$'\n'}" <<< "${JVM_FEATURES_TO_TEST// /$'\n'}"`
+ if test "x$INVALID_FEATURES" != x; then
+ as_fn_error $? "Invalid JVM feature(s): $INVALID_FEATURES" "$LINENO" 5
+ fi
+ done
+
+
# We're messing a bit with internal autoconf variables to put the config.status
# in the output directory instead of the current directory.
CONFIG_STATUS="$CONFIGURESUPPORT_OUTPUTDIR/config.status"
@@ -64965,7 +66839,7 @@
printf "* Debug level: $DEBUG_LEVEL\n"
printf "* HS debug level: $HOTSPOT_DEBUG_LEVEL\n"
printf "* JDK variant: $JDK_VARIANT\n"
- printf "* JVM variants: $with_jvm_variants\n"
+ printf "* JVM variants: $JVM_VARIANTS\n"
printf "* OpenJDK target: OS: $OPENJDK_TARGET_OS, CPU architecture: $OPENJDK_TARGET_CPU_ARCH, address length: $OPENJDK_TARGET_CPU_BITS\n"
printf "* Version string: $VERSION_STRING ($VERSION_SHORT)\n"
@@ -64991,7 +66865,7 @@
fi
printf "\n"
- if test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = "xyes"; then
+ if test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = "xtrue"; then
printf "NOTE: You have requested to build more than one version of the JVM, which\n"
printf "will result in longer build times.\n"
printf "\n"
--- a/common/autoconf/help.m4 Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/help.m4 Thu Apr 28 23:08:17 2016 -0700
@@ -119,6 +119,8 @@
PKGHANDLER_COMMAND="sudo apt-get install libX11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev" ;;
ccache)
PKGHANDLER_COMMAND="sudo apt-get install ccache" ;;
+ dtrace)
+ PKGHANDLER_COMMAND="sudo apt-get install systemtap-sdt-dev" ;;
esac
}
@@ -170,6 +172,13 @@
TOOLCHAIN_DESCRIPTION=${!toolchain_var_name}
$PRINTF " %-10s %s\n" $toolchain "$TOOLCHAIN_DESCRIPTION"
done
+ $PRINTF "\n"
+
+ # Print available jvm features
+ $PRINTF "The following JVM features are available as arguments to --with-jvm-features.\n"
+ $PRINTF "Which are valid to use depends on the target platform.\n "
+ $PRINTF "%s " $VALID_JVM_FEATURES
+ $PRINTF "\n"
# And now exit directly
exit 0
@@ -206,7 +215,7 @@
printf "* Debug level: $DEBUG_LEVEL\n"
printf "* HS debug level: $HOTSPOT_DEBUG_LEVEL\n"
printf "* JDK variant: $JDK_VARIANT\n"
- printf "* JVM variants: $with_jvm_variants\n"
+ printf "* JVM variants: $JVM_VARIANTS\n"
printf "* OpenJDK target: OS: $OPENJDK_TARGET_OS, CPU architecture: $OPENJDK_TARGET_CPU_ARCH, address length: $OPENJDK_TARGET_CPU_BITS\n"
printf "* Version string: $VERSION_STRING ($VERSION_SHORT)\n"
@@ -232,7 +241,7 @@
fi
printf "\n"
- if test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = "xyes"; then
+ if test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = "xtrue"; then
printf "NOTE: You have requested to build more than one version of the JVM, which\n"
printf "will result in longer build times.\n"
printf "\n"
--- a/common/autoconf/hotspot-spec.gmk.in Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/hotspot-spec.gmk.in Thu Apr 28 23:08:17 2016 -0700
@@ -38,6 +38,16 @@
# Legacy defines controlled by the SUPPORT_HEADLESS and SUPPORT_HEADFUL options.
@BUILD_HEADLESS@
+JVM_VARIANTS:=@JVM_VARIANTS_COMMA@
+
+JVM_VARIANT_SERVER:=@JVM_VARIANT_SERVER@
+JVM_VARIANT_CLIENT:=@JVM_VARIANT_CLIENT@
+JVM_VARIANT_MINIMAL1:=@JVM_VARIANT_MINIMAL1@
+JVM_VARIANT_CORE:=@JVM_VARIANT_CORE@
+JVM_VARIANT_ZERO:=@JVM_VARIANT_ZERO@
+JVM_VARIANT_ZEROSHARK:=@JVM_VARIANT_ZEROSHARK@
+JVM_VARIANT_CUSTOM:=@JVM_VARIANT_HOTSPOT@
+
# Legacy setting: OPT or DBG
VARIANT:=@VARIANT@
# Legacy setting: true or false
@@ -92,8 +102,7 @@
ALT_OUTPUTDIR=$(HOTSPOT_OUTPUTDIR)
ALT_EXPORT_PATH=$(HOTSPOT_DIST)
-JVM_INTERPRETER:=@JVM_INTERPRETER@
-ifeq ($(JVM_INTERPRETER), cpp)
+ifeq ($(HOTSPOT_TARGET_CPU), zero)
CC_INTERP=true
endif
--- a/common/autoconf/hotspot.m4 Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/hotspot.m4 Thu Apr 28 23:08:17 2016 -0700
@@ -23,170 +23,344 @@
# questions.
#
-###############################################################################
-# Check which interpreter of the JVM we want to build.
-# Currently we have:
-# template: Template interpreter (the default)
-# cpp : C++ interpreter
-AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_INTERPRETER],
-[
- AC_ARG_WITH([jvm-interpreter], [AS_HELP_STRING([--with-jvm-interpreter],
- [JVM interpreter to build (template, cpp) @<:@template@:>@])])
+# All valid JVM features, regardless of platform
+VALID_JVM_FEATURES="compiler1 compiler2 zero shark minimal dtrace jvmti jvmci \
+ fprof vm-structs jni-check services management all-gcs nmt cds static-build"
+
+# All valid JVM variants
+VALID_JVM_VARIANTS="server client minimal core zero zeroshark custom"
- AC_MSG_CHECKING([which interpreter of the JVM to build])
- if test "x$with_jvm_interpreter" = x; then
- JVM_INTERPRETER="template"
- else
- JVM_INTERPRETER="$with_jvm_interpreter"
- fi
- AC_MSG_RESULT([$JVM_INTERPRETER])
+###############################################################################
+# Check if the specified JVM variant should be built. To be used in shell if
+# constructs, like this:
+# if HOTSPOT_CHECK_JVM_VARIANT(server); then
+#
+# Only valid to use after HOTSPOT_SETUP_JVM_VARIANTS has setup variants.
- if test "x$JVM_INTERPRETER" != xtemplate && test "x$JVM_INTERPRETER" != xcpp; then
- AC_MSG_ERROR([The available JVM interpreters are: template, cpp])
- fi
-
- AC_SUBST(JVM_INTERPRETER)
-])
+# Definition kept in one line to allow inlining in if statements.
+# Additional [] needed to keep m4 from mangling shell constructs.
+AC_DEFUN([HOTSPOT_CHECK_JVM_VARIANT],
+[ [ [[ " $JVM_VARIANTS " =~ " $1 " ]] ] ])
###############################################################################
-# Check which variants of the JVM that we want to build.
-# Currently we have:
-# server: normal interpreter and a C2 or tiered C1/C2 compiler
-# client: normal interpreter and C1 (no C2 compiler) (only 32-bit platforms)
-# minimal1: reduced form of client with optional VM services and features stripped out
-# zero: no machine code interpreter, no compiler
-# zeroshark: zero interpreter and shark/llvm compiler backend
-# core: interpreter only, no compiler (only works on some platforms)
+# Check if the specified JVM features are explicitly enabled. To be used in
+# shell if constructs, like this:
+# if HOTSPOT_CHECK_JVM_FEATURE(jvmti); then
+#
+# Only valid to use after HOTSPOT_SETUP_JVM_FEATURES has setup features.
+
+# Definition kept in one line to allow inlining in if statements.
+# Additional [] needed to keep m4 from mangling shell constructs.
+AC_DEFUN([HOTSPOT_CHECK_JVM_FEATURE],
+[ [ [[ " $JVM_FEATURES " =~ " $1 " ]] ] ])
+
+###############################################################################
+# Check which variants of the JVM that we want to build. Available variants are:
+# server: normal interpreter, and a tiered C1/C2 compiler
+# client: normal interpreter, and C1 (no C2 compiler)
+# minimal: reduced form of client with optional features stripped out
+# core: normal interpreter only, no compiler
+# zero: C++ based interpreter only, no compiler
+# zeroshark: C++ based interpreter, and a llvm-based compiler
+# custom: baseline JVM with no default features
+#
AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_VARIANTS],
[
- AC_MSG_CHECKING([which variants of the JVM to build])
AC_ARG_WITH([jvm-variants], [AS_HELP_STRING([--with-jvm-variants],
- [JVM variants (separated by commas) to build (server, client, minimal1, zero, zeroshark, core) @<:@server@:>@])])
+ [JVM variants (separated by commas) to build (server,client,minimal,core,zero,zeroshark,custom) @<:@server@:>@])])
if test "x$with_jvm_variants" = x; then
with_jvm_variants="server"
fi
+ JVM_VARIANTS_OPT="$with_jvm_variants"
- JVM_VARIANTS=",$with_jvm_variants,"
- TEST_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/server,//' -e 's/client,//' -e 's/minimal1,//' -e 's/zero,//' -e 's/zeroshark,//' -e 's/core,//'`
+ # Has the user listed more than one variant?
+ # Additional [] needed to keep m4 from mangling shell constructs.
+ if [ [[ "$JVM_VARIANTS_OPT" =~ "," ]] ]; then
+ BUILDING_MULTIPLE_JVM_VARIANTS=true
+ else
+ BUILDING_MULTIPLE_JVM_VARIANTS=false
+ fi
+ # Replace the commas with AND for use in the build directory name.
+ JVM_VARIANTS_WITH_AND=`$ECHO "$JVM_VARIANTS_OPT" | $SED -e 's/,/AND/g'`
+
+ AC_MSG_CHECKING([which variants of the JVM to build])
+ # JVM_VARIANTS is a space-separated list.
+ # Also use minimal, not minimal1 (which is kept for backwards compatibility).
+ JVM_VARIANTS=`$ECHO $JVM_VARIANTS_OPT | $SED -e 's/,/ /g' -e 's/minimal1/minimal/'`
+ AC_MSG_RESULT([$JVM_VARIANTS])
+
+ # Check that the selected variants are valid
+
+ # grep filter function inspired by a comment to http://stackoverflow.com/a/1617326
+ INVALID_VARIANTS=`$GREP -Fvx "${VALID_JVM_VARIANTS// /$'\n'}" <<< "${JVM_VARIANTS// /$'\n'}"`
+ if test "x$INVALID_VARIANTS" != x; then
+ AC_MSG_NOTICE([Unknown variant(s) specified: $INVALID_VARIANTS])
+ AC_MSG_ERROR([The available JVM variants are: $VALID_JVM_VARIANTS])
+ fi
+
+ # All "special" variants share the same output directory ("server")
+ VALID_MULTIPLE_JVM_VARIANTS="server client minimal"
+ INVALID_MULTIPLE_VARIANTS=`$GREP -Fvx "${VALID_MULTIPLE_JVM_VARIANTS// /$'\n'}" <<< "${JVM_VARIANTS// /$'\n'}"`
+ if test "x$INVALID_MULTIPLE_VARIANTS" != x && test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = xtrue; then
+ AC_MSG_ERROR([You cannot build multiple variants with anything else than $VALID_MULTIPLE_JVM_VARIANTS.])
+ fi
- if test "x$TEST_VARIANTS" != "x,"; then
- AC_MSG_ERROR([The available JVM variants are: server, client, minimal1, zero, zeroshark, core])
+ AC_SUBST(JVM_VARIANTS)
+ AC_SUBST(VALID_JVM_VARIANTS)
+
+ if HOTSPOT_CHECK_JVM_VARIANT(zero) || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
+ # zero behaves as a platform and rewrites these values. This is really weird. :(
+ # We are guaranteed that we do not build any other variants when building zero.
+ HOTSPOT_TARGET_CPU=zero
+ HOTSPOT_TARGET_CPU_ARCH=zero
fi
- AC_MSG_RESULT([$with_jvm_variants])
+])
+
+###############################################################################
+# Check if dtrace should be enabled and has all prerequisites present.
+#
+AC_DEFUN_ONCE([HOTSPOT_SETUP_DTRACE],
+[
+ # Test for dtrace dependencies
+ AC_ARG_ENABLE([dtrace], [AS_HELP_STRING([--enable-dtrace@<:@=yes/no/auto@:>@],
+ [enable dtrace. Default is auto, where dtrace is enabled if all dependencies
+ are present.])])
+
+ DTRACE_DEP_MISSING=false
+
+ AC_MSG_CHECKING([for dtrace tool])
+ if test "x$DTRACE" != "x" && test -x "$DTRACE"; then
+ AC_MSG_RESULT([$DTRACE])
+ else
+ AC_MSG_RESULT([not found, cannot build dtrace])
+ DTRACE_DEP_MISSING=true
+ fi
+
+ AC_CHECK_HEADERS([sys/sdt.h], [DTRACE_HEADERS_OK=yes],[DTRACE_HEADERS_OK=no])
+ if test "x$DTRACE_HEADERS_OK" != "xyes"; then
+ DTRACE_DEP_MISSING=true
+ fi
- JVM_VARIANT_SERVER=`$ECHO "$JVM_VARIANTS" | $SED -e '/,server,/!s/.*/false/g' -e '/,server,/s/.*/true/g'`
- JVM_VARIANT_CLIENT=`$ECHO "$JVM_VARIANTS" | $SED -e '/,client,/!s/.*/false/g' -e '/,client,/s/.*/true/g'`
- JVM_VARIANT_MINIMAL1=`$ECHO "$JVM_VARIANTS" | $SED -e '/,minimal1,/!s/.*/false/g' -e '/,minimal1,/s/.*/true/g'`
- JVM_VARIANT_ZERO=`$ECHO "$JVM_VARIANTS" | $SED -e '/,zero,/!s/.*/false/g' -e '/,zero,/s/.*/true/g'`
- JVM_VARIANT_ZEROSHARK=`$ECHO "$JVM_VARIANTS" | $SED -e '/,zeroshark,/!s/.*/false/g' -e '/,zeroshark,/s/.*/true/g'`
- JVM_VARIANT_CORE=`$ECHO "$JVM_VARIANTS" | $SED -e '/,core,/!s/.*/false/g' -e '/,core,/s/.*/true/g'`
+ AC_MSG_CHECKING([if dtrace should be built])
+ if test "x$enable_dtrace" = "xyes"; then
+ if test "x$DTRACE_DEP_MISSING" = "xtrue"; then
+ AC_MSG_RESULT([no, missing dependencies])
+ HELP_MSG_MISSING_DEPENDENCY([dtrace])
+ AC_MSG_ERROR([Cannot enable dtrace with missing dependencies. See above. $HELP_MSG])
+ else
+ INCLUDE_DTRACE=true
+ AC_MSG_RESULT([yes, forced])
+ fi
+ elif test "x$enable_dtrace" = "xno"; then
+ INCLUDE_DTRACE=false
+ AC_MSG_RESULT([no, forced])
+ elif test "x$enable_dtrace" = "xauto" || test "x$enable_dtrace" = "x"; then
+ if test "x$OPENJDK_TARGET_OS" = "xlinux" && test "x$OPENJDK" != "xtrue"; then
+ INCLUDE_DTRACE=false
+ AC_MSG_RESULT([no, non-open linux build])
+ elif test "x$DTRACE_DEP_MISSING" = "xtrue"; then
+ INCLUDE_DTRACE=false
+ AC_MSG_RESULT([no, missing dependencies])
+ else
+ INCLUDE_DTRACE=true
+ AC_MSG_RESULT([yes, dependencies present])
+ fi
+ else
+ AC_MSG_ERROR([Invalid value for --enable-dtrace: $enable_dtrace])
+ fi
+ AC_SUBST(INCLUDE_DTRACE)
+])
- if test "x$JVM_VARIANT_CLIENT" = xtrue; then
- if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
- AC_MSG_ERROR([You cannot build a client JVM for a 64-bit machine.])
- fi
+###############################################################################
+# Set up all JVM features for each JVM variant.
+#
+AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_FEATURES],
+[
+ # The user can in some cases supply additional jvm features. For the custom
+ # variant, this defines the entire variant.
+ AC_ARG_WITH([jvm-features], [AS_HELP_STRING([--with-jvm-features],
+ [additional JVM features to enable (separated by comma), use '--help' to show possible values @<:@none@:>@])])
+ if test "x$with_jvm_features" != x; then
+ AC_MSG_CHECKING([additional JVM features])
+ JVM_FEATURES=`$ECHO $with_jvm_features | $SED -e 's/,/ /g'`
+ AC_MSG_RESULT([$JVM_FEATURES])
+ fi
+
+ # Verify that dependencies are met for explicitly set features.
+ if HOTSPOT_CHECK_JVM_FEATURE(jvmti) && ! HOTSPOT_CHECK_JVM_FEATURE(services); then
+ AC_MSG_ERROR([Specified JVM feature 'jvmti' requires feature 'services'])
fi
- if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
- if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
- AC_MSG_ERROR([You cannot build a minimal JVM for a 64-bit machine.])
+
+ if HOTSPOT_CHECK_JVM_FEATURE(management) && ! HOTSPOT_CHECK_JVM_FEATURE(nmt); then
+ AC_MSG_ERROR([Specified JVM feature 'management' requires feature 'nmt'])
+ fi
+
+ if HOTSPOT_CHECK_JVM_FEATURE(jvmci) && ! HOTSPOT_CHECK_JVM_FEATURE(compiler2); then
+ AC_MSG_ERROR([Specified JVM feature 'jvmci' requires feature 'compiler2'])
+ fi
+
+ if HOTSPOT_CHECK_JVM_FEATURE(compiler2) && ! HOTSPOT_CHECK_JVM_FEATURE(all-gcs); then
+ AC_MSG_ERROR([Specified JVM feature 'compiler2' requires feature 'all-gcs'])
+ fi
+
+ if HOTSPOT_CHECK_JVM_FEATURE(vm-structs) && ! HOTSPOT_CHECK_JVM_FEATURE(all-gcs); then
+ AC_MSG_ERROR([Specified JVM feature 'vm-structs' requires feature 'all-gcs'])
+ fi
+
+ # Turn on additional features based on other parts of configure
+ if test "x$INCLUDE_DTRACE" = "xtrue"; then
+ JVM_FEATURES="$JVM_FEATURES dtrace"
+ else
+ if HOTSPOT_CHECK_JVM_FEATURE(dtrace); then
+ AC_MSG_ERROR([To enable dtrace, you must use --enable-dtrace])
fi
fi
- # Replace the commas with AND for use in the build directory name.
- ANDED_JVM_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/^,//' -e 's/,$//' -e 's/,/AND/g'`
- COUNT_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/server,/1/' -e 's/client,/1/' -e 's/minimal1,/1/' -e 's/zero,/1/' -e 's/zeroshark,/1/' -e 's/core,/1/'`
- if test "x$COUNT_VARIANTS" != "x,1"; then
- BUILDING_MULTIPLE_JVM_VARIANTS=yes
+ if test "x$STATIC_BUILD" = "xtrue"; then
+ JVM_FEATURES="$JVM_FEATURES static-build"
else
- BUILDING_MULTIPLE_JVM_VARIANTS=no
+ if HOTSPOT_CHECK_JVM_FEATURE(static-build); then
+ AC_MSG_ERROR([To enable static-build, you must use --enable-static-build])
+ fi
+ fi
+
+ if ! HOTSPOT_CHECK_JVM_VARIANT(zero) && ! HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
+ if HOTSPOT_CHECK_JVM_FEATURE(zero); then
+ AC_MSG_ERROR([To enable zero/zeroshark, you must use --with-jvm-variants=zero/zeroshark])
+ fi
+ fi
+
+ if ! HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
+ if HOTSPOT_CHECK_JVM_FEATURE(shark); then
+ AC_MSG_ERROR([To enable shark, you must use --with-jvm-variants=zeroshark])
+ fi
+ fi
+
+ # Only enable jvmci on x86_64, sparcv9 and aarch64, and only on server.
+ if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || \
+ test "x$OPENJDK_TARGET_CPU" = "xsparcv9" || \
+ test "x$OPENJDK_TARGET_CPU" = "xaarch64" ; then
+ JVM_FEATURES_jvmci="jvmci"
+ else
+ JVM_FEATURES_jvmci=""
fi
- if test "x$JVM_VARIANT_ZERO" = xtrue && test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = xyes; then
- AC_MSG_ERROR([You cannot build multiple variants with zero.])
- fi
+ # All variants but minimal (and custom) get these features
+ NON_MINIMAL_FEATURES="$NON_MINIMAL_FEATURES jvmti fprof vm-structs jni-check services management all-gcs nmt cds"
+
+ # Enable features depending on variant.
+ JVM_FEATURES_server="compiler1 compiler2 $NON_MINIMAL_FEATURES $JVM_FEATURES $JVM_FEATURES_jvmci"
+ JVM_FEATURES_client="compiler1 $NON_MINIMAL_FEATURES $JVM_FEATURES"
+ JVM_FEATURES_core="$NON_MINIMAL_FEATURES $JVM_FEATURES"
+ JVM_FEATURES_minimal="compiler1 minimal $JVM_FEATURES"
+ JVM_FEATURES_zero="zero $NON_MINIMAL_FEATURES $JVM_FEATURES"
+ JVM_FEATURES_zeroshark="zero shark $NON_MINIMAL_FEATURES $JVM_FEATURES"
+ JVM_FEATURES_custom="$JVM_FEATURES"
+
+ AC_SUBST(JVM_FEATURES_server)
+ AC_SUBST(JVM_FEATURES_client)
+ AC_SUBST(JVM_FEATURES_core)
+ AC_SUBST(JVM_FEATURES_minimal)
+ AC_SUBST(JVM_FEATURES_zero)
+ AC_SUBST(JVM_FEATURES_zeroshark)
+ AC_SUBST(JVM_FEATURES_custom)
+
+ # Used for verification of Makefiles by check-jvm-feature
+ AC_SUBST(VALID_JVM_FEATURES)
+
+ # We don't support --with-jvm-interpreter anymore, use zero instead.
+ BASIC_DEPRECATED_ARG_WITH(jvm-interpreter)
+])
+
+###############################################################################
+# Validate JVM features once all setup is complete, including custom setup.
+#
+AC_DEFUN_ONCE([HOTSPOT_VALIDATE_JVM_FEATURES],
+[
+ # Keep feature lists sorted and free of duplicates
+ JVM_FEATURES_server="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_server | $SORT -u))"
+ JVM_FEATURES_client="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_client | $SORT -u))"
+ JVM_FEATURES_core="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_core | $SORT -u))"
+ JVM_FEATURES_minimal="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_minimal | $SORT -u))"
+ JVM_FEATURES_zero="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_zero | $SORT -u))"
+ JVM_FEATURES_zeroshark="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_zeroshark | $SORT -u))"
+ JVM_FEATURES_custom="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_custom | $SORT -u))"
- AC_SUBST(JVM_VARIANTS)
- AC_SUBST(JVM_VARIANT_SERVER)
- AC_SUBST(JVM_VARIANT_CLIENT)
- AC_SUBST(JVM_VARIANT_MINIMAL1)
- AC_SUBST(JVM_VARIANT_ZERO)
- AC_SUBST(JVM_VARIANT_ZEROSHARK)
- AC_SUBST(JVM_VARIANT_CORE)
+ # Validate features
+ for variant in $JVM_VARIANTS; do
+ AC_MSG_CHECKING([JVM features for JVM variant '$variant'])
+ features_var_name=JVM_FEATURES_$variant
+ JVM_FEATURES_TO_TEST=${!features_var_name}
+ AC_MSG_RESULT([$JVM_FEATURES_TO_TEST])
+ INVALID_FEATURES=`$GREP -Fvx "${VALID_JVM_FEATURES// /$'\n'}" <<< "${JVM_FEATURES_TO_TEST// /$'\n'}"`
+ if test "x$INVALID_FEATURES" != x; then
+ AC_MSG_ERROR([Invalid JVM feature(s): $INVALID_FEATURES])
+ fi
+ done
+])
+
+###############################################################################
+# Support for old hotspot build. Remove once new hotspot build has proven
+# to work satisfactory.
+#
+AC_DEFUN_ONCE([HOTSPOT_SETUP_LEGACY_BUILD],
+[
+ AC_ARG_ENABLE(new-hotspot-build, [AS_HELP_STRING([--disable-new-hotspot-build],
+ [disable the new hotspot build system (use the old) @<:@enabled@:>@])])
+
+ if test "x$enable_new_hotspot_build" = "x" || test "x$enable_new_hotspot_build" = "xyes"; then
+ USE_NEW_HOTSPOT_BUILD=true
+ else
+ USE_NEW_HOTSPOT_BUILD=false
+ fi
+ AC_SUBST(USE_NEW_HOTSPOT_BUILD)
+
+ case $HOTSPOT_DEBUG_LEVEL in
+ product )
+ VARIANT="OPT"
+ FASTDEBUG="false"
+ DEBUG_CLASSFILES="false"
+ ;;
+ fastdebug )
+ VARIANT="DBG"
+ FASTDEBUG="true"
+ DEBUG_CLASSFILES="true"
+ ;;
+ debug )
+ VARIANT="DBG"
+ FASTDEBUG="false"
+ DEBUG_CLASSFILES="true"
+ ;;
+ optimized )
+ VARIANT="OPT"
+ FASTDEBUG="false"
+ DEBUG_CLASSFILES="false"
+ ;;
+ esac
+ AC_SUBST(VARIANT)
+ AC_SUBST(FASTDEBUG)
+ AC_SUBST(DEBUG_CLASSFILES)
if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
MACOSX_UNIVERSAL="true"
fi
AC_SUBST(MACOSX_UNIVERSAL)
-])
+ # Make sure JVM_VARIANTS_COMMA use minimal1 for backwards compatibility
+ JVM_VARIANTS_COMMA=`$ECHO ,$JVM_VARIANTS_OPT, | $SED -e 's/,minimal,/,minimal1,/'`
-###############################################################################
-# Setup legacy vars/targets and new vars to deal with different debug levels.
-#
-# release: no debug information, all optimizations, no asserts.
-# optimized: no debug information, all optimizations, no asserts, HotSpot target is 'optimized'.
-# fastdebug: debug information (-g), all optimizations, all asserts
-# slowdebug: debug information (-g), no optimizations, all asserts
-#
-AC_DEFUN_ONCE([HOTSPOT_SETUP_DEBUG_LEVEL],
-[
- case $DEBUG_LEVEL in
- release )
- VARIANT="OPT"
- FASTDEBUG="false"
- DEBUG_CLASSFILES="false"
- BUILD_VARIANT_RELEASE=""
- HOTSPOT_DEBUG_LEVEL="product"
- HOTSPOT_EXPORT="product"
- ;;
- fastdebug )
- VARIANT="DBG"
- FASTDEBUG="true"
- DEBUG_CLASSFILES="true"
- BUILD_VARIANT_RELEASE="-fastdebug"
- HOTSPOT_DEBUG_LEVEL="fastdebug"
- HOTSPOT_EXPORT="fastdebug"
- ;;
- slowdebug )
- VARIANT="DBG"
- FASTDEBUG="false"
- DEBUG_CLASSFILES="true"
- BUILD_VARIANT_RELEASE="-debug"
- HOTSPOT_DEBUG_LEVEL="debug"
- HOTSPOT_EXPORT="debug"
- ;;
- optimized )
- VARIANT="OPT"
- FASTDEBUG="false"
- DEBUG_CLASSFILES="false"
- BUILD_VARIANT_RELEASE="-optimized"
- HOTSPOT_DEBUG_LEVEL="optimized"
- HOTSPOT_EXPORT="optimized"
- ;;
- esac
-
- # The debug level 'optimized' is a little special because it is currently only
- # applicable to the HotSpot build where it means to build a completely
- # optimized version of the VM without any debugging code (like for the
- # 'release' debug level which is called 'product' in the HotSpot build) but
- # with the exception that it can contain additional code which is otherwise
- # protected by '#ifndef PRODUCT' macros. These 'optimized' builds are used to
- # test new and/or experimental features which are not intended for customer
- # shipment. Because these new features need to be tested and benchmarked in
- # real world scenarios, we want to build the containing JDK at the 'release'
- # debug level.
- if test "x$DEBUG_LEVEL" = xoptimized; then
- DEBUG_LEVEL="release"
- fi
+ JVM_VARIANT_SERVER=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,server,/!s/.*/false/g' -e '/,server,/s/.*/true/g'`
+ JVM_VARIANT_CLIENT=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,client,/!s/.*/false/g' -e '/,client,/s/.*/true/g'`
+ JVM_VARIANT_MINIMAL1=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,minimal1\?,/!s/.*/false/g' -e '/,minimal1\?,/s/.*/true/g'`
+ JVM_VARIANT_CORE=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,core,/!s/.*/false/g' -e '/,core,/s/.*/true/g'`
+ JVM_VARIANT_ZERO=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,zero,/!s/.*/false/g' -e '/,zero,/s/.*/true/g'`
+ JVM_VARIANT_ZEROSHARK=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,zeroshark,/!s/.*/false/g' -e '/,zeroshark,/s/.*/true/g'`
+ JVM_VARIANT_CUSTOM=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,custom,/!s/.*/false/g' -e '/,custom,/s/.*/true/g'`
#####
# Generate the legacy makefile targets for hotspot.
- # The hotspot api for selecting the build artifacts, really, needs to be improved.
- # JDK-7195896 will fix this on the hotspot side by using the JVM_VARIANT_* variables to
- # determine what needs to be built. All we will need to set here is all_product, all_fastdebug etc
- # But until then ...
HOTSPOT_TARGET=""
if test "x$JVM_VARIANT_SERVER" = xtrue; then
@@ -213,27 +387,19 @@
HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}core "
fi
- HOTSPOT_TARGET="$HOTSPOT_TARGET docs export_$HOTSPOT_EXPORT"
+ HOTSPOT_TARGET="$HOTSPOT_TARGET docs export_$HOTSPOT_DEBUG_LEVEL"
# On Macosx universal binaries are produced, but they only contain
# 64 bit intel. This invalidates control of which jvms are built
# from configure, but only server is valid anyway. Fix this
# when hotspot makefiles are rewritten.
if test "x$MACOSX_UNIVERSAL" = xtrue; then
- HOTSPOT_TARGET=universal_${HOTSPOT_EXPORT}
+ HOTSPOT_TARGET=universal_${HOTSPOT_DEBUG_LEVEL}
fi
- #####
+ HOTSPOT_MAKE_ARGS="$HOTSPOT_TARGET"
+ AC_SUBST(HOTSPOT_MAKE_ARGS)
- AC_SUBST(DEBUG_LEVEL)
- AC_SUBST(VARIANT)
- AC_SUBST(FASTDEBUG)
- AC_SUBST(DEBUG_CLASSFILES)
- AC_SUBST(BUILD_VARIANT_RELEASE)
-])
-
-AC_DEFUN_ONCE([HOTSPOT_SETUP_HOTSPOT_OPTIONS],
-[
# Control wether Hotspot runs Queens test after build.
AC_ARG_ENABLE([hotspot-test-in-build], [AS_HELP_STRING([--enable-hotspot-test-in-build],
[run the Queens test after Hotspot build @<:@disabled@:>@])],,
@@ -244,10 +410,29 @@
TEST_IN_BUILD=false
fi
AC_SUBST(TEST_IN_BUILD)
-])
-AC_DEFUN_ONCE([HOTSPOT_SETUP_BUILD_TWEAKS],
-[
- HOTSPOT_MAKE_ARGS="$HOTSPOT_TARGET"
- AC_SUBST(HOTSPOT_MAKE_ARGS)
+ if test "x$USE_NEW_HOTSPOT_BUILD" = xfalse; then
+ if test "x$JVM_VARIANT_CLIENT" = xtrue; then
+ if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+ AC_MSG_ERROR([You cannot build a client JVM for a 64-bit machine.])
+ fi
+ fi
+ if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
+ if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+ AC_MSG_ERROR([You cannot build a minimal JVM for a 64-bit machine.])
+ fi
+ fi
+ if test "x$JVM_VARIANT_CUSTOM" = xtrue; then
+ AC_MSG_ERROR([You cannot build a custom JVM using the old hotspot build system.])
+ fi
+ fi
+
+ AC_SUBST(JVM_VARIANTS_COMMA)
+ AC_SUBST(JVM_VARIANT_SERVER)
+ AC_SUBST(JVM_VARIANT_CLIENT)
+ AC_SUBST(JVM_VARIANT_MINIMAL1)
+ AC_SUBST(JVM_VARIANT_HOTSPOT)
+ AC_SUBST(JVM_VARIANT_ZERO)
+ AC_SUBST(JVM_VARIANT_ZEROSHARK)
+ AC_SUBST(JVM_VARIANT_CORE)
])
--- a/common/autoconf/jdk-options.m4 Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/jdk-options.m4 Thu Apr 28 23:08:17 2016 -0700
@@ -81,6 +81,31 @@
test "x$DEBUG_LEVEL" != xslowdebug; then
AC_MSG_ERROR([Allowed debug levels are: release, fastdebug, slowdebug and optimized])
fi
+
+ # Translate DEBUG_LEVEL to debug level used by Hotspot
+ HOTSPOT_DEBUG_LEVEL="$DEBUG_LEVEL"
+ if test "x$DEBUG_LEVEL" = xrelease; then
+ HOTSPOT_DEBUG_LEVEL="product"
+ elif test "x$DEBUG_LEVEL" = xslowdebug; then
+ HOTSPOT_DEBUG_LEVEL="debug"
+ fi
+
+ if test "x$DEBUG_LEVEL" = xoptimized; then
+ # The debug level 'optimized' is a little special because it is currently only
+ # applicable to the HotSpot build where it means to build a completely
+ # optimized version of the VM without any debugging code (like for the
+ # 'release' debug level which is called 'product' in the HotSpot build) but
+ # with the exception that it can contain additional code which is otherwise
+ # protected by '#ifndef PRODUCT' macros. These 'optimized' builds are used to
+ # test new and/or experimental features which are not intended for customer
+ # shipment. Because these new features need to be tested and benchmarked in
+ # real world scenarios, we want to build the containing JDK at the 'release'
+ # debug level.
+ DEBUG_LEVEL="release"
+ fi
+
+ AC_SUBST(HOTSPOT_DEBUG_LEVEL)
+ AC_SUBST(DEBUG_LEVEL)
])
###############################################################################
@@ -178,10 +203,7 @@
# Should we build the serviceability agent (SA)?
INCLUDE_SA=true
- if test "x$JVM_VARIANT_ZERO" = xtrue ; then
- INCLUDE_SA=false
- fi
- if test "x$JVM_VARIANT_ZEROSHARK" = xtrue ; then
+ if HOTSPOT_CHECK_JVM_VARIANT(zero) || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
INCLUDE_SA=false
fi
if test "x$OPENJDK_TARGET_OS" = xaix ; then
--- a/common/autoconf/jdk-version.m4 Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/jdk-version.m4 Thu Apr 28 23:08:17 2016 -0700
@@ -72,6 +72,7 @@
AC_SUBST(PRODUCT_SUFFIX)
AC_SUBST(JDK_RC_PLATFORM_NAME)
AC_SUBST(COMPANY_NAME)
+ AC_SUBST(HOTSPOT_VM_DISTRO)
AC_SUBST(MACOSX_BUNDLE_NAME_BASE)
AC_SUBST(MACOSX_BUNDLE_ID_BASE)
--- a/common/autoconf/lib-std.m4 Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/lib-std.m4 Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -88,13 +88,25 @@
# If dynamic was requested, it's available since it would fail above otherwise.
# If dynamic wasn't requested, go with static unless it isn't available.
AC_MSG_CHECKING([how to link with libstdc++])
- if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno || test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+ if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
LIBCXX="$LIBCXX -lstdc++"
+ # To help comparisons with old build, put stdc++ first in JVM_LIBS
+ JVM_LIBS="-lstdc++ $JVM_LIBS"
+ # Ideally, we should test stdc++ for the BUILD toolchain separately. For now
+ # just use the same setting as for the TARGET toolchain.
+ OPENJDK_BUILD_JVM_LIBS="-lstdc++ $OPENJDK_BUILD_JVM_LIBS"
LDCXX="$CXX"
STATIC_CXX_SETTING="STATIC_CXX=false"
AC_MSG_RESULT([dynamic])
else
LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS"
+ JVM_LDFLAGS="$JVM_LDFLAGS -static-libgcc"
+ # To help comparisons with old build, put stdc++ first in JVM_LIBS
+ JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $JVM_LIBS"
+ # Ideally, we should test stdc++ for the BUILD toolchain separately. For now
+ # just use the same setting as for the TARGET toolchain.
+ OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -static-libgcc"
+ OPENJDK_BUILD_JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $OPENJDK_BUILD_JVM_LIBS"
LDCXX="$CC"
STATIC_CXX_SETTING="STATIC_CXX=true"
AC_MSG_RESULT([static])
--- a/common/autoconf/libraries.m4 Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/libraries.m4 Thu Apr 28 23:08:17 2016 -0700
@@ -74,7 +74,7 @@
fi
# Check if ffi is needed
- if test "x$JVM_VARIANT_ZERO" = xtrue || test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+ if HOTSPOT_CHECK_JVM_VARIANT(zero) || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
NEEDS_LIB_FFI=true
else
NEEDS_LIB_FFI=false
@@ -102,7 +102,7 @@
################################################################################
AC_DEFUN_ONCE([LIB_SETUP_LLVM],
[
- if test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+ if HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
AC_CHECK_PROG([LLVM_CONFIG], [llvm-config], [llvm-config])
if test "x$LLVM_CONFIG" != xllvm-config; then
--- a/common/autoconf/platform.m4 Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/platform.m4 Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -274,168 +274,172 @@
#
AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS],
[
+ PLATFORM_SETUP_LEGACY_VARS_HELPER([TARGET])
+ PLATFORM_SETUP_LEGACY_VARS_HELPER([BUILD])
+
+ # ZERO_ARCHDEF is used to enable architecture-specific code.
+ # This is used in legacy hotspot build.
+ ZERO_ARCHDEF="$HOTSPOT_TARGET_CPU_DEFINE"
+ AC_SUBST(ZERO_ARCHDEF)
+
+])
+
+# $1 - Either TARGET or BUILD to setup the variables for.
+AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS_HELPER],
+[
# Also store the legacy naming of the cpu.
# Ie i586 and amd64 instead of x86 and x86_64
- OPENJDK_TARGET_CPU_LEGACY="$OPENJDK_TARGET_CPU"
- if test "x$OPENJDK_TARGET_CPU" = xx86; then
- OPENJDK_TARGET_CPU_LEGACY="i586"
- elif test "x$OPENJDK_TARGET_OS" != xmacosx && test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+ OPENJDK_$1_CPU_LEGACY="$OPENJDK_$1_CPU"
+ if test "x$OPENJDK_$1_CPU" = xx86; then
+ OPENJDK_$1_CPU_LEGACY="i586"
+ elif test "x$OPENJDK_$1_OS" != xmacosx && test "x$OPENJDK_$1_CPU" = xx86_64; then
# On all platforms except MacOSX replace x86_64 with amd64.
- OPENJDK_TARGET_CPU_LEGACY="amd64"
+ OPENJDK_$1_CPU_LEGACY="amd64"
fi
- AC_SUBST(OPENJDK_TARGET_CPU_LEGACY)
+ AC_SUBST(OPENJDK_$1_CPU_LEGACY)
# And the second legacy naming of the cpu.
# Ie i386 and amd64 instead of x86 and x86_64.
- OPENJDK_TARGET_CPU_LEGACY_LIB="$OPENJDK_TARGET_CPU"
- if test "x$OPENJDK_TARGET_CPU" = xx86; then
- OPENJDK_TARGET_CPU_LEGACY_LIB="i386"
- elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then
- OPENJDK_TARGET_CPU_LEGACY_LIB="amd64"
- fi
- AC_SUBST(OPENJDK_TARGET_CPU_LEGACY_LIB)
-
- # This is the name of the cpu (but using i386 and amd64 instead of
- # x86 and x86_64, respectively), preceeded by a /, to be used when
- # locating libraries. On macosx, it's empty, though.
- OPENJDK_TARGET_CPU_LIBDIR="/$OPENJDK_TARGET_CPU_LEGACY_LIB"
- if test "x$OPENJDK_TARGET_OS" = xmacosx; then
- OPENJDK_TARGET_CPU_LIBDIR=""
+ OPENJDK_$1_CPU_LEGACY_LIB="$OPENJDK_$1_CPU"
+ if test "x$OPENJDK_$1_CPU" = xx86; then
+ OPENJDK_$1_CPU_LEGACY_LIB="i386"
+ elif test "x$OPENJDK_$1_CPU" = xx86_64; then
+ OPENJDK_$1_CPU_LEGACY_LIB="amd64"
fi
- AC_SUBST(OPENJDK_TARGET_CPU_LIBDIR)
-
- # Now do the same for OPENJDK_BUILD_CPU...
- # Also store the legacy naming of the cpu.
- # Ie i586 and amd64 instead of x86 and x86_64
- OPENJDK_BUILD_CPU_LEGACY="$OPENJDK_BUILD_CPU"
- if test "x$OPENJDK_BUILD_CPU" = xx86; then
- OPENJDK_BUILD_CPU_LEGACY="i586"
- elif test "x$OPENJDK_BUILD_OS" != xmacosx && test "x$OPENJDK_BUILD_CPU" = xx86_64; then
- # On all platforms except MacOSX replace x86_64 with amd64.
- OPENJDK_BUILD_CPU_LEGACY="amd64"
- fi
- AC_SUBST(OPENJDK_BUILD_CPU_LEGACY)
-
- # And the second legacy naming of the cpu.
- # Ie i386 and amd64 instead of x86 and x86_64.
- OPENJDK_BUILD_CPU_LEGACY_LIB="$OPENJDK_BUILD_CPU"
- if test "x$OPENJDK_BUILD_CPU" = xx86; then
- OPENJDK_BUILD_CPU_LEGACY_LIB="i386"
- elif test "x$OPENJDK_BUILD_CPU" = xx86_64; then
- OPENJDK_BUILD_CPU_LEGACY_LIB="amd64"
- fi
- AC_SUBST(OPENJDK_BUILD_CPU_LEGACY_LIB)
+ AC_SUBST(OPENJDK_$1_CPU_LEGACY_LIB)
# This is the name of the cpu (but using i386 and amd64 instead of
# x86 and x86_64, respectively), preceeded by a /, to be used when
# locating libraries. On macosx, it's empty, though.
- OPENJDK_BUILD_CPU_LIBDIR="/$OPENJDK_BUILD_CPU_LEGACY_LIB"
- if test "x$OPENJDK_BUILD_OS" = xmacosx; then
- OPENJDK_BUILD_CPU_LIBDIR=""
+ OPENJDK_$1_CPU_LIBDIR="/$OPENJDK_$1_CPU_LEGACY_LIB"
+ if test "x$OPENJDK_$1_OS" = xmacosx; then
+ OPENJDK_$1_CPU_LIBDIR=""
fi
- AC_SUBST(OPENJDK_BUILD_CPU_LIBDIR)
+ AC_SUBST(OPENJDK_$1_CPU_LIBDIR)
- # OPENJDK_TARGET_CPU_ISADIR is normally empty. On 64-bit Solaris systems, it is set to
+ # OPENJDK_$1_CPU_ISADIR is normally empty. On 64-bit Solaris systems, it is set to
# /amd64 or /sparcv9. This string is appended to some library paths, like this:
- # /usr/lib${OPENJDK_TARGET_CPU_ISADIR}/libexample.so
- OPENJDK_TARGET_CPU_ISADIR=""
- if test "x$OPENJDK_TARGET_OS" = xsolaris; then
- if test "x$OPENJDK_TARGET_CPU" = xx86_64; then
- OPENJDK_TARGET_CPU_ISADIR="/amd64"
- elif test "x$OPENJDK_TARGET_CPU" = xsparcv9; then
- OPENJDK_TARGET_CPU_ISADIR="/sparcv9"
+ # /usr/lib${OPENJDK_$1_CPU_ISADIR}/libexample.so
+ OPENJDK_$1_CPU_ISADIR=""
+ if test "x$OPENJDK_$1_OS" = xsolaris; then
+ if test "x$OPENJDK_$1_CPU" = xx86_64; then
+ OPENJDK_$1_CPU_ISADIR="/amd64"
+ elif test "x$OPENJDK_$1_CPU" = xsparcv9; then
+ OPENJDK_$1_CPU_ISADIR="/sparcv9"
fi
fi
- AC_SUBST(OPENJDK_TARGET_CPU_ISADIR)
+ AC_SUBST(OPENJDK_$1_CPU_ISADIR)
- # Setup OPENJDK_TARGET_CPU_OSARCH, which is used to set the os.arch Java system property
- OPENJDK_TARGET_CPU_OSARCH="$OPENJDK_TARGET_CPU"
- if test "x$OPENJDK_TARGET_OS" = xlinux && test "x$OPENJDK_TARGET_CPU" = xx86; then
+ # Setup OPENJDK_$1_CPU_OSARCH, which is used to set the os.arch Java system property
+ OPENJDK_$1_CPU_OSARCH="$OPENJDK_$1_CPU"
+ if test "x$OPENJDK_$1_OS" = xlinux && test "x$OPENJDK_$1_CPU" = xx86; then
# On linux only, we replace x86 with i386.
- OPENJDK_TARGET_CPU_OSARCH="i386"
- elif test "x$OPENJDK_TARGET_OS" != xmacosx && test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+ OPENJDK_$1_CPU_OSARCH="i386"
+ elif test "x$OPENJDK_$1_OS" != xmacosx && test "x$OPENJDK_$1_CPU" = xx86_64; then
# On all platforms except macosx, we replace x86_64 with amd64.
- OPENJDK_TARGET_CPU_OSARCH="amd64"
+ OPENJDK_$1_CPU_OSARCH="amd64"
fi
- AC_SUBST(OPENJDK_TARGET_CPU_OSARCH)
+ AC_SUBST(OPENJDK_$1_CPU_OSARCH)
- OPENJDK_TARGET_CPU_JLI="$OPENJDK_TARGET_CPU"
- if test "x$OPENJDK_TARGET_CPU" = xx86; then
- OPENJDK_TARGET_CPU_JLI="i386"
- elif test "x$OPENJDK_TARGET_OS" != xmacosx && test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+ OPENJDK_$1_CPU_JLI="$OPENJDK_$1_CPU"
+ if test "x$OPENJDK_$1_CPU" = xx86; then
+ OPENJDK_$1_CPU_JLI="i386"
+ elif test "x$OPENJDK_$1_OS" != xmacosx && test "x$OPENJDK_$1_CPU" = xx86_64; then
# On all platforms except macosx, we replace x86_64 with amd64.
- OPENJDK_TARGET_CPU_JLI="amd64"
+ OPENJDK_$1_CPU_JLI="amd64"
fi
# Now setup the -D flags for building libjli.
- OPENJDK_TARGET_CPU_JLI_CFLAGS="-DLIBARCHNAME='\"$OPENJDK_TARGET_CPU_JLI\"'"
- if test "x$OPENJDK_TARGET_OS" = xsolaris; then
- if test "x$OPENJDK_TARGET_CPU_ARCH" = xsparc; then
- OPENJDK_TARGET_CPU_JLI_CFLAGS="$OPENJDK_TARGET_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"sparc\"' -DLIBARCH64NAME='\"sparcv9\"'"
- elif test "x$OPENJDK_TARGET_CPU_ARCH" = xx86; then
- OPENJDK_TARGET_CPU_JLI_CFLAGS="$OPENJDK_TARGET_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"i386\"' -DLIBARCH64NAME='\"amd64\"'"
+ OPENJDK_$1_CPU_JLI_CFLAGS="-DLIBARCHNAME='\"$OPENJDK_$1_CPU_JLI\"'"
+ if test "x$OPENJDK_$1_OS" = xsolaris; then
+ if test "x$OPENJDK_$1_CPU_ARCH" = xsparc; then
+ OPENJDK_$1_CPU_JLI_CFLAGS="$OPENJDK_$1_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"sparc\"' -DLIBARCH64NAME='\"sparcv9\"'"
+ elif test "x$OPENJDK_$1_CPU_ARCH" = xx86; then
+ OPENJDK_$1_CPU_JLI_CFLAGS="$OPENJDK_$1_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"i386\"' -DLIBARCH64NAME='\"amd64\"'"
fi
fi
- AC_SUBST(OPENJDK_TARGET_CPU_JLI_CFLAGS)
+ AC_SUBST(OPENJDK_$1_CPU_JLI_CFLAGS)
- OPENJDK_BUILD_CPU_JLI="$OPENJDK_BUILD_CPU"
- if test "x$OPENJDK_BUILD_CPU" = xx86; then
- OPENJDK_BUILD_CPU_JLI="i386"
- elif test "x$OPENJDK_BUILD_OS" != xmacosx && test "x$OPENJDK_BUILD_CPU" = xx86_64; then
- # On all platforms except macosx, we replace x86_64 with amd64.
- OPENJDK_BUILD_CPU_JLI="amd64"
+ if test "x$OPENJDK_$1_OS" = xmacosx; then
+ OPENJDK_$1_OS_EXPORT_DIR=macosx
+ else
+ OPENJDK_$1_OS_EXPORT_DIR=${OPENJDK_$1_OS_TYPE}
fi
- # Now setup the -D flags for building libjli.
- OPENJDK_BUILD_CPU_JLI_CFLAGS="-DLIBARCHNAME='\"$OPENJDK_BUILD_CPU_JLI\"'"
- if test "x$OPENJDK_BUILD_OS" = xsolaris; then
- if test "x$OPENJDK_BUILD_CPU_ARCH" = xsparc; then
- OPENJDK_BUILD_CPU_JLI_CFLAGS="$OPENJDK_BUILD_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"sparc\"' -DLIBARCH64NAME='\"sparcv9\"'"
- elif test "x$OPENJDK_BUILD_CPU_ARCH" = xx86; then
- OPENJDK_BUILD_CPU_JLI_CFLAGS="$OPENJDK_BUILD_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"i386\"' -DLIBARCH64NAME='\"amd64\"'"
- fi
- fi
- AC_SUBST(OPENJDK_BUILD_CPU_JLI_CFLAGS)
+ AC_SUBST(OPENJDK_$1_OS_EXPORT_DIR)
- if test "x$OPENJDK_TARGET_OS" = xmacosx; then
- OPENJDK_TARGET_OS_EXPORT_DIR=macosx
- else
- OPENJDK_TARGET_OS_EXPORT_DIR=${OPENJDK_TARGET_OS_TYPE}
- fi
- AC_SUBST(OPENJDK_TARGET_OS_EXPORT_DIR)
-
- if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+ if test "x$OPENJDK_$1_CPU_BITS" = x64; then
A_LP64="LP64:="
# -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in
# unpack200.exe
- if test "x$OPENJDK_TARGET_OS" = xlinux || test "x$OPENJDK_TARGET_OS" = xmacosx; then
- ADD_LP64="-D_LP64=1"
+ if test "x$OPENJDK_$1_OS" = xlinux || test "x$OPENJDK_$1_OS" = xmacosx; then
+ OPENJDK_$1_ADD_LP64="-D_LP64=1"
fi
fi
AC_SUBST(LP64,$A_LP64)
- if test "x$OPENJDK_BUILD_CPU_BITS" = x64; then
- if test "x$OPENJDK_BUILD_OS" = xlinux || test "x$OPENJDK_BUILD_OS" = xmacosx; then
- OPENJDK_BUILD_ADD_LP64="-D_LP64=1"
- fi
- fi
if test "x$COMPILE_TYPE" = "xcross"; then
# FIXME: ... or should this include reduced builds..?
- DEFINE_CROSS_COMPILE_ARCH="CROSS_COMPILE_ARCH:=$OPENJDK_TARGET_CPU_LEGACY"
+ DEFINE_CROSS_COMPILE_ARCH="CROSS_COMPILE_ARCH:=$OPENJDK_$1_CPU_LEGACY"
else
DEFINE_CROSS_COMPILE_ARCH=""
fi
AC_SUBST(DEFINE_CROSS_COMPILE_ARCH)
- # ZERO_ARCHDEF is used to enable architecture-specific code
- case "${OPENJDK_TARGET_CPU}" in
- ppc) ZERO_ARCHDEF=PPC32 ;;
- ppc64) ZERO_ARCHDEF=PPC64 ;;
- s390*) ZERO_ARCHDEF=S390 ;;
- sparc*) ZERO_ARCHDEF=SPARC ;;
- x86_64*) ZERO_ARCHDEF=AMD64 ;;
- x86) ZERO_ARCHDEF=IA32 ;;
- *) ZERO_ARCHDEF=$(echo "${OPENJDK_TARGET_CPU_LEGACY_LIB}" | tr a-z A-Z)
- esac
- AC_SUBST(ZERO_ARCHDEF)
+ # Convert openjdk platform names to hotspot names
+
+ HOTSPOT_$1_OS=${OPENJDK_$1_OS}
+ if test "x$OPENJDK_$1_OS" = xmacosx; then
+ HOTSPOT_$1_OS=bsd
+ fi
+ AC_SUBST(HOTSPOT_$1_OS)
+
+ HOTSPOT_$1_OS_TYPE=${OPENJDK_$1_OS_TYPE}
+ if test "x$OPENJDK_$1_OS_TYPE" = xunix; then
+ HOTSPOT_$1_OS_TYPE=posix
+ fi
+ AC_SUBST(HOTSPOT_$1_OS_TYPE)
+
+ HOTSPOT_$1_CPU=${OPENJDK_$1_CPU}
+ if test "x$OPENJDK_$1_CPU" = xx86; then
+ HOTSPOT_$1_CPU=x86_32
+ elif test "x$OPENJDK_$1_CPU" = xsparcv9; then
+ HOTSPOT_$1_CPU=sparc
+ elif test "x$OPENJDK_$1_CPU" = xppc64; then
+ HOTSPOT_$1_CPU=ppc_64
+ elif test "x$OPENJDK_$1_CPU" = xppc64le; then
+ HOTSPOT_$1_CPU=ppc_64
+ fi
+ AC_SUBST(HOTSPOT_$1_CPU)
+
+ # This is identical with OPENJDK_*, but define anyway for consistency.
+ HOTSPOT_$1_CPU_ARCH=${OPENJDK_$1_CPU_ARCH}
+ AC_SUBST(HOTSPOT_$1_CPU_ARCH)
+
+ # Setup HOTSPOT_$1_CPU_DEFINE
+ if test "x$OPENJDK_$1_CPU" = xx86; then
+ HOTSPOT_$1_CPU_DEFINE=IA32
+ elif test "x$OPENJDK_$1_CPU" = xx86_64; then
+ HOTSPOT_$1_CPU_DEFINE=AMD64
+ elif test "x$OPENJDK_$1_CPU" = xsparcv9; then
+ HOTSPOT_$1_CPU_DEFINE=SPARC
+ elif test "x$OPENJDK_$1_CPU" = xaarch64; then
+ HOTSPOT_$1_CPU_DEFINE=AARCH64
+ elif test "x$OPENJDK_$1_CPU" = xppc64; then
+ HOTSPOT_$1_CPU_DEFINE=PPC64
+ elif test "x$OPENJDK_$1_CPU" = xppc64le; then
+ HOTSPOT_$1_CPU_DEFINE=PPC64
+
+ # The cpu defines below are for zero, we don't support them directly.
+ elif test "x$OPENJDK_$1_CPU" = xsparc; then
+ HOTSPOT_$1_CPU_DEFINE=SPARC
+ elif test "x$OPENJDK_$1_CPU" = xppc; then
+ HOTSPOT_$1_CPU_DEFINE=PPC32
+ elif test "x$OPENJDK_$1_CPU" = xs390; then
+ HOTSPOT_$1_CPU_DEFINE=S390
+ elif test "x$OPENJDK_$1_CPU" = ss390x; then
+ HOTSPOT_$1_CPU_DEFINE=S390
+ fi
+ AC_SUBST(HOTSPOT_$1_CPU_DEFINE)
+
])
AC_DEFUN([PLATFORM_SET_RELEASE_FILE_OS_VALUES],
@@ -521,6 +525,10 @@
CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}"
CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
+
+ JVM_CFLAGS="$JVM_CFLAGS $ADDED_CFLAGS"
+ JVM_LDFLAGS="$JVM_LDFLAGS $ADDED_LDFLAGS"
+ JVM_ASFLAGS="$JVM_ASFLAGS $ADDED_CFLAGS"
])
AC_DEFUN_ONCE([PLATFORM_SETUP_OPENJDK_TARGET_BITS],
@@ -542,6 +550,11 @@
PLATFORM_SET_COMPILER_TARGET_BITS_FLAGS
fi
fi
+ if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+ JVM_CFLAGS="$JVM_CFLAGS ${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
+ JVM_LDFLAGS="$JVM_LDFLAGS ${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
+ JVM_ASFLAGS="$JVM_ASFLAGS ${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
+ fi
# Make compilation sanity check
AC_CHECK_HEADERS([stdio.h], , [
--- a/common/autoconf/spec.gmk.in Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/spec.gmk.in Thu Apr 28 23:08:17 2016 -0700
@@ -82,6 +82,13 @@
OPENJDK_TARGET_CPU_JLI_CFLAGS:=@OPENJDK_TARGET_CPU_JLI_CFLAGS@
OPENJDK_TARGET_OS_EXPORT_DIR:=@OPENJDK_TARGET_OS_EXPORT_DIR@
+HOTSPOT_TARGET_OS := @HOTSPOT_TARGET_OS@
+HOTSPOT_TARGET_OS_TYPE := @HOTSPOT_TARGET_OS_TYPE@
+
+HOTSPOT_TARGET_CPU := @HOTSPOT_TARGET_CPU@
+HOTSPOT_TARGET_CPU_ARCH := @HOTSPOT_TARGET_CPU_ARCH@
+HOTSPOT_TARGET_CPU_DEFINE := @HOTSPOT_TARGET_CPU_DEFINE@
+
# We are building on this build system.
# When not cross-compiling, it is the same as the target.
OPENJDK_BUILD_OS:=@OPENJDK_BUILD_OS@
@@ -192,6 +199,7 @@
PRODUCT_SUFFIX:=@PRODUCT_SUFFIX@
JDK_RC_PLATFORM_NAME:=@JDK_RC_PLATFORM_NAME@
COMPANY_NAME:=@COMPANY_NAME@
+HOTSPOT_VM_DISTRO:=@HOTSPOT_VM_DISTRO@
MACOSX_BUNDLE_NAME_BASE=@MACOSX_BUNDLE_NAME_BASE@
MACOSX_BUNDLE_ID_BASE=@MACOSX_BUNDLE_ID_BASE@
USERNAME:=@USERNAME@
@@ -201,11 +209,32 @@
# How to compile the code: release, fastdebug or slowdebug
DEBUG_LEVEL:=@DEBUG_LEVEL@
+HOTSPOT_DEBUG_LEVEL:=@HOTSPOT_DEBUG_LEVEL@
# This is the JDK variant to build.
# The JDK variant is a name for a specific set of modules to be compiled for the JDK.
JDK_VARIANT:=@JDK_VARIANT@
+# Which JVM variants to build (space-separated list)
+JVM_VARIANTS := @JVM_VARIANTS@
+
+# Lists of features per variant. Only relevant for the variants listed in
+# JVM_VARIANTS.
+JVM_FEATURES_server := @JVM_FEATURES_server@
+JVM_FEATURES_client := @JVM_FEATURES_client@
+JVM_FEATURES_core := @JVM_FEATURES_core@
+JVM_FEATURES_minimal := @JVM_FEATURES_minimal@
+JVM_FEATURES_zero := @JVM_FEATURES_zero@
+JVM_FEATURES_zeroshark := @JVM_FEATURES_zeroshark@
+JVM_FEATURES_custom := @JVM_FEATURES_custom@
+
+# Used for make-time verifications
+VALID_JVM_FEATURES := @VALID_JVM_FEATURES@
+VALID_JVM_VARIANTS := @VALID_JVM_VARIANTS@
+
+# Control use of precompiled header in hotspot libjvm build
+USE_PRECOMPILED_HEADER := @USE_PRECOMPILED_HEADER@
+
# Should we compile support for running with a graphical UI? (ie headful)
# Should we compile support for running without? (ie headless)
SUPPORT_HEADFUL:=@SUPPORT_HEADFUL@
@@ -213,25 +242,11 @@
# Legacy defines controlled by the SUPPORT_HEADLESS and SUPPORT_HEADFUL options.
@BUILD_HEADLESS@
-# These are the libjvms that we want to build.
-# The java launcher uses the default.
-# The others can be selected by specifying -client -server -minimal1 -zero or -zeroshark
-# on the java launcher command line.
-JVM_VARIANTS:=@JVM_VARIANTS@
-JVM_VARIANT_SERVER:=@JVM_VARIANT_SERVER@
-JVM_VARIANT_CLIENT:=@JVM_VARIANT_CLIENT@
-JVM_VARIANT_MINIMAL1:=@JVM_VARIANT_MINIMAL1@
-JVM_VARIANT_ZERO:=@JVM_VARIANT_ZERO@
-JVM_VARIANT_ZEROSHARK:=@JVM_VARIANT_ZEROSHARK@
-JVM_VARIANT_CORE:=@JVM_VARIANT_CORE@
+# Legacy support
+USE_NEW_HOTSPOT_BUILD:=@USE_NEW_HOTSPOT_BUILD@
-# Universal binaries on macosx
MACOSX_UNIVERSAL=@MACOSX_UNIVERSAL@
-# Legacy setting: -debug or -fastdebug
-# Still used in version string...
-BUILD_VARIANT_RELEASE:=@BUILD_VARIANT_RELEASE@
-
# JDK_OUTPUTDIR specifies where a working jvm is built.
# You can run $(JDK_OUTPUTDIR)/bin/java
# Though the layout of the contents of $(JDK_OUTPUTDIR) is not
@@ -320,6 +335,11 @@
# Toolchain type: gcc, clang, solstudio, lxc, microsoft...
TOOLCHAIN_TYPE:=@TOOLCHAIN_TYPE@
TOOLCHAIN_VERSION := @TOOLCHAIN_VERSION@
+CC_VERSION_NUMBER := @CC_VERSION_NUMBER@
+CXX_VERSION_NUMBER := @CXX_VERSION_NUMBER@
+
+# Legacy support
+HOTSPOT_TOOLCHAIN_TYPE := @HOTSPOT_TOOLCHAIN_TYPE@
# Option used to tell the compiler whether to create 32- or 64-bit executables
COMPILER_TARGET_BITS_FLAG:=@COMPILER_TARGET_BITS_FLAG@
@@ -338,14 +358,18 @@
AR_OUT_OPTION:=@AR_OUT_OPTION@
# Flags used for overriding the default opt setting for a C/C++ source file.
+C_O_FLAG_HIGHEST_JVM:=@C_O_FLAG_HIGHEST_JVM@
C_O_FLAG_HIGHEST:=@C_O_FLAG_HIGHEST@
C_O_FLAG_HI:=@C_O_FLAG_HI@
C_O_FLAG_NORM:=@C_O_FLAG_NORM@
C_O_FLAG_NONE:=@C_O_FLAG_NONE@
+C_O_FLAG_SIZE:=@C_O_FLAG_SIZE@
+CXX_O_FLAG_HIGHEST_JVM:=@CXX_O_FLAG_HIGHEST_JVM@
CXX_O_FLAG_HIGHEST:=@CXX_O_FLAG_HIGHEST@
CXX_O_FLAG_HI:=@CXX_O_FLAG_HI@
CXX_O_FLAG_NORM:=@CXX_O_FLAG_NORM@
CXX_O_FLAG_NONE:=@CXX_O_FLAG_NONE@
+CXX_O_FLAG_SIZE:=@CXX_O_FLAG_SIZE@
C_FLAG_DEPS:=@C_FLAG_DEPS@
CXX_FLAG_DEPS:=@CXX_FLAG_DEPS@
@@ -374,6 +398,23 @@
LDFLAGS_HASH_STYLE := @LDFLAGS_HASH_STYLE@
+JVM_CFLAGS := @JVM_CFLAGS@
+JVM_CFLAGS_SYMBOLS := @JVM_CFLAGS_SYMBOLS@
+JVM_LDFLAGS := @JVM_LDFLAGS@
+JVM_ASFLAGS := @JVM_ASFLAGS@
+JVM_LIBS := @JVM_LIBS@
+JVM_RCFLAGS := @JVM_RCFLAGS@
+
+# Flags for zeroshark
+LLVM_CFLAGS := @LLVM_CFLAGS@
+LLVM_LIBS := @LLVM_LIBS@
+LLVM_LDFLAGS := @LLVM_LDFLAGS@
+
+# These flags might contain variables set by a custom extension that is included later.
+EXTRA_CFLAGS = @EXTRA_CFLAGS@
+EXTRA_CXXFLAGS = @EXTRA_CXXFLAGS@
+EXTRA_LDFLAGS = @EXTRA_LDFLAGS@
+
CXX:=@FIXPATH@ @CCACHE@ @ICECC@ @CXX@
CPP:=@FIXPATH@ @CPP@
@@ -630,6 +671,7 @@
JT_HOME:=@JT_HOME@
JTREGEXE:=@JTREGEXE@
XCODEBUILD=@XCODEBUILD@
+DTRACE := @DTRACE@
FIXPATH:=@FIXPATH@
# Build setup
--- a/common/autoconf/toolchain.m4 Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/toolchain.m4 Thu Apr 28 23:08:17 2016 -0700
@@ -930,6 +930,17 @@
rm -rf version-script.map main.c a.out
fi
AC_SUBST(USING_BROKEN_SUSE_LD)
+
+ # Setup hotspot lecagy names for toolchains
+ HOTSPOT_TOOLCHAIN_TYPE=$TOOLCHAIN_TYPE
+ if test "x$TOOLCHAIN_TYPE" = xclang; then
+ HOTSPOT_TOOLCHAIN_TYPE=gcc
+ elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+ HOTSPOT_TOOLCHAIN_TYPE=sparcWorks
+ elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+ HOTSPOT_TOOLCHAIN_TYPE=visCPP
+ fi
+ AC_SUBST(HOTSPOT_TOOLCHAIN_TYPE)
])
# Setup the JTReg Regression Test Harness.
--- a/common/autoconf/version-numbers Thu Apr 28 00:38:21 2016 -0700
+++ b/common/autoconf/version-numbers Thu Apr 28 23:08:17 2016 -0700
@@ -32,6 +32,7 @@
PRODUCT_SUFFIX="Runtime Environment"
JDK_RC_PLATFORM_NAME=Platform
COMPANY_NAME=N/A
+HOTSPOT_VM_DISTRO="OpenJDK"
# Might need better names for these
MACOSX_BUNDLE_NAME_BASE="OpenJDK"
--- a/common/conf/jib-profiles.js Thu Apr 28 00:38:21 2016 -0700
+++ b/common/conf/jib-profiles.js Thu Apr 28 23:08:17 2016 -0700
@@ -241,7 +241,7 @@
target_os: "linux",
target_cpu: "x64",
dependencies: concat(common.dependencies, "devkit"),
- configure_args: concat(common.configure_args, "--with-zlib=system"),
+ configure_args: concat(common.configure_args, "--with-zlib=system"),
make_args: common.make_args
},
@@ -259,7 +259,7 @@
target_os: "macosx",
target_cpu: "x64",
dependencies: concat(common.dependencies, "devkit"),
- configure_args: concat(common.configure_args, "--with-zlib=system"),
+ configure_args: concat(common.configure_args, "--with-zlib=system"),
make_args: common.make_args
},
@@ -267,7 +267,7 @@
target_os: "solaris",
target_cpu: "x64",
dependencies: concat(common.dependencies, "devkit", "cups"),
- configure_args: concat(common.configure_args, "--with-zlib=system"),
+ configure_args: concat(common.configure_args, "--with-zlib=system"),
make_args: common.make_args
},
@@ -275,7 +275,7 @@
target_os: "solaris",
target_cpu: "sparcv9",
dependencies: concat(common.dependencies, "devkit", "cups"),
- configure_args: concat(common.configure_args, "--with-zlib=system"),
+ configure_args: concat(common.configure_args, "--with-zlib=system"),
make_args: common.make_args
},
--- a/corba/.hgtags Thu Apr 28 00:38:21 2016 -0700
+++ b/corba/.hgtags Thu Apr 28 23:08:17 2016 -0700
@@ -357,3 +357,4 @@
780d0620add32bf545471cf65038c9ac6d9c036d jdk-9+112
cc30faa2da498c478e89ab062ff160653ca1b170 jdk-9+113
10d175b0368c30f54350fc648adc41b94ce357ee jdk-9+114
+7bab1b1b36824924b1c657a8419369ba93d198d3 jdk-9+115
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/corba/RequestImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/corba/RequestImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -255,7 +255,7 @@
public synchronized void send_deferred()
{
AsynchInvoke invokeObject = new AsynchInvoke(_orb, this, false);
- new sun.misc.ManagedLocalsThread(invokeObject).start();
+ new Thread(null, invokeObject, "Async-Request-Invoker-Thread", 0, false).start();
}
public synchronized boolean poll_response()
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java Thu Apr 28 00:38:21 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java Thu Apr 28 23:08:17 2016 -0700
@@ -751,12 +751,13 @@
}
}
-class KeepAlive extends sun.misc.ManagedLocalsThread
+class KeepAlive extends Thread
{
boolean quit = false;
public KeepAlive ()
{
+ super(null, null, "Servant-KeepAlive-Thread", 0, false);
setDaemon(false);
}
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -516,7 +516,7 @@
// Converted from anonymous class to local class
// so that we can call performDestroy() directly.
- static class DestroyThread extends sun.misc.ManagedLocalsThread {
+ static class DestroyThread extends Thread {
private boolean wait ;
private boolean etherealize ;
private boolean debug ;
@@ -524,6 +524,7 @@
public DestroyThread( boolean etherealize, boolean debug )
{
+ super(null, null, "POA-Destroy-Thread", 0, false);
this.etherealize = etherealize ;
this.debug = debug ;
}
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAManagerImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAManagerImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -357,7 +357,7 @@
if (wait_for_completion)
deactivator.run() ;
else {
- Thread thr = new sun.misc.ManagedLocalsThread(deactivator) ;
+ Thread thr = new Thread(null, deactivator, "POA-Deactivator-Thread", 0, false) ;
thr.start() ;
}
} finally {
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAPolicyMediatorImpl_R_USM.java Thu Apr 28 00:38:21 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAPolicyMediatorImpl_R_USM.java Thu Apr 28 23:08:17 2016 -0700
@@ -302,7 +302,7 @@
throw new WrongPolicy();
}
- class Etherealizer extends sun.misc.ManagedLocalsThread {
+ class Etherealizer extends Thread {
private POAPolicyMediatorImpl_R_USM mediator ;
private ActiveObjectMap.Key key ;
private AOMEntry entry ;
@@ -314,6 +314,7 @@
ActiveObjectMap.Key key, AOMEntry entry, Servant servant,
boolean debug )
{
+ super(null, null, "PAO-Etherealizer-Thread", 0, false);
this.mediator = mediator ;
this.key = key ;
this.entry = entry;
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -691,7 +691,7 @@
for (int i = 0; i < req.length; i++) {
AsynchInvoke invokeObject = new AsynchInvoke( this,
(com.sun.corba.se.impl.corba.RequestImpl)req[i], true);
- new sun.misc.ManagedLocalsThread(invokeObject).start();
+ new Thread(null, invokeObject, "ORB-Request-Thread", 0, false).start();
}
}
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -459,7 +459,7 @@
}
- private class WorkerThread extends sun.misc.ManagedLocalsThread implements Closeable
+ private class WorkerThread extends Thread implements Closeable
{
private Work currentWork;
private int threadId = 0; // unique id for the thread
@@ -469,7 +469,7 @@
private StringBuffer workerThreadName = new StringBuffer();
WorkerThread(ThreadGroup tg, String threadPoolName) {
- super(tg, "Idle");
+ super(tg, null, "Idle", 0, false);
this.threadId = ThreadPoolImpl.getUniqueThreadId();
this.threadPoolName = threadPoolName;
setName(composeWorkerThreadName(threadPoolName, "Idle"));
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -61,7 +61,7 @@
*/
class SelectorImpl
extends
- sun.misc.ManagedLocalsThread
+ Thread
implements
com.sun.corba.se.pept.transport.Selector
{
@@ -79,6 +79,7 @@
public SelectorImpl(ORB orb)
{
+ super(null, null, "ORB-Selector-Thread", 0, false);
this.orb = orb;
selector = null;
selectorStarted = false;
@@ -277,7 +278,6 @@
public void run()
{
- setName("SelectorThread");
while (!closed) {
try {
int n = 0;
--- a/corba/src/java.corba/share/classes/module-info.java Thu Apr 28 00:38:21 2016 -0700
+++ b/corba/src/java.corba/share/classes/module-info.java Thu Apr 28 23:08:17 2016 -0700
@@ -29,8 +29,6 @@
requires java.logging;
requires java.naming;
requires java.transaction;
- // 8148863
- requires jdk.unsupported;
exports javax.activity;
exports javax.rmi;
--- a/hotspot/.hgtags Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/.hgtags Thu Apr 28 23:08:17 2016 -0700
@@ -517,3 +517,4 @@
76582e8dc9e6374e4f99ab797c8d364b6e9449b4 jdk-9+112
c569f8d89269fb6205b90f727581eb8cc04132f9 jdk-9+113
b64432bae5271735fd53300b2005b713e98ef411 jdk-9+114
+88dd08d7be0fe7fb9f1914b1628f0aae9bf56e25 jdk-9+115
--- a/hotspot/make/Makefile Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/make/Makefile Thu Apr 28 23:08:17 2016 -0700
@@ -237,19 +237,21 @@
$(MAKE_ARGS) $(VM_TARGET)
endif
+# NOTE: Changes in this file was just to facilitate comparison when
+# developing the new build, and should not be integrated.
generic_buildcore: $(HOTSPOT_SCRIPT)
-ifeq ($(HS_ARCH),ppc)
- ifeq ($(ARCH_DATA_MODEL),64)
+#ifeq ($(HS_ARCH),ppc)
+# ifeq ($(ARCH_DATA_MODEL),64)
$(MKDIR) -p $(OUTPUTDIR)
$(CD) $(OUTPUTDIR); \
$(MAKE) -f $(ABS_OS_MAKEFILE) \
$(MAKE_ARGS) $(VM_TARGET)
- else
- @$(ECHO) "No ($(VM_TARGET)) for ppc ARCH_DATA_MODEL=$(ARCH_DATA_MODEL)"
- endif
-else
- @$(ECHO) "No ($(VM_TARGET)) for $(HS_ARCH)"
-endif
+# else
+# @$(ECHO) "No ($(VM_TARGET)) for ppc ARCH_DATA_MODEL=$(ARCH_DATA_MODEL)"
+# endif
+#else
+# @$(ECHO) "No ($(VM_TARGET)) for $(HS_ARCH)"
+#endif
generic_buildzero: $(HOTSPOT_SCRIPT)
$(MKDIR) -p $(OUTPUTDIR)
--- a/hotspot/make/aix/makefiles/trace.make Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/make/aix/makefiles/trace.make Thu Apr 28 23:08:17 2016 -0700
@@ -53,13 +53,13 @@
TraceGeneratedNames = \
traceEventClasses.hpp \
- traceEventIds.hpp \
- traceTypes.hpp
+ traceEventIds.hpp \
+ traceTypes.hpp
ifeq ($(HAS_ALT_SRC), true)
- TraceGeneratedNames += \
- traceRequestables.hpp \
- traceEventControl.hpp
+TraceGeneratedNames += \
+ traceRequestables.hpp \
+ traceEventControl.hpp
endif
TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
--- a/hotspot/make/bsd/makefiles/trace.make Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/make/bsd/makefiles/trace.make Thu Apr 28 23:08:17 2016 -0700
@@ -53,13 +53,13 @@
TraceGeneratedNames = \
traceEventClasses.hpp \
- traceEventIds.hpp \
- traceTypes.hpp
+ traceEventIds.hpp \
+ traceTypes.hpp
ifeq ($(HAS_ALT_SRC), true)
- TraceGeneratedNames += \
- traceRequestables.hpp \
- traceEventControl.hpp
+TraceGeneratedNames += \
+ traceRequestables.hpp \
+ traceEventControl.hpp
endif
TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
--- a/hotspot/make/linux/makefiles/gcc.make Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/make/linux/makefiles/gcc.make Thu Apr 28 23:08:17 2016 -0700
@@ -221,7 +221,7 @@
ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
# GCC < 4.3
WARNING_FLAGS += -Wconversion
- endif
+ endif
ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 8 \) \))" "1"
# GCC >= 4.8
# This flag is only known since GCC 4.3. Gcc 4.8 contains a fix so that with templates no
@@ -260,7 +260,7 @@
OPT_CFLAGS = $(OPT_CFLAGS/$(OPT_CFLAGS_DEFAULT)) $(OPT_EXTRAS)
-# Variable tracking size limit exceeded for VMStructs::init()
+# Variable tracking size limit exceeded for VMStructs::init()
ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "1"
# GCC >= 4.3
# Gcc 4.1.2 does not support this flag, nor does it have problems compiling the file.
--- a/hotspot/make/linux/makefiles/trace.make Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/make/linux/makefiles/trace.make Thu Apr 28 23:08:17 2016 -0700
@@ -53,13 +53,13 @@
TraceGeneratedNames = \
traceEventClasses.hpp \
- traceEventIds.hpp \
- traceTypes.hpp
+ traceEventIds.hpp \
+ traceTypes.hpp
ifeq ($(HAS_ALT_SRC), true)
- TraceGeneratedNames += \
- traceRequestables.hpp \
- traceEventControl.hpp
+TraceGeneratedNames += \
+ traceRequestables.hpp \
+ traceEventControl.hpp
endif
TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
--- a/hotspot/make/linux/makefiles/zero.make Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/make/linux/makefiles/zero.make Thu Apr 28 23:08:17 2016 -0700
@@ -30,3 +30,8 @@
# Install libjvm.so, etc in in server directory.
VM_SUBDIR = server
+
+# Disable trace for zero builds
+# NOTE: This is used for simple comparison with the new build system, and
+# should not be merged into mainline with build-infra.
+INCLUDE_TRACE := false
--- a/hotspot/make/share/makefiles/mapfile-vers Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/make/share/makefiles/mapfile-vers Thu Apr 28 23:08:17 2016 -0700
@@ -41,7 +41,6 @@
JVM_DumpAllStacks;
JVM_DumpThreads;
JVM_FillInStackTrace;
- JVM_FillStackFrames;
JVM_FindClassFromCaller;
JVM_FindClassFromClass;
JVM_FindClassFromBootLoader;
@@ -157,13 +156,13 @@
JVM_SetClassSigners;
JVM_SetNativeThreadName;
JVM_SetPrimitiveArrayElement;
- JVM_SetMethodInfo;
JVM_SetThreadPriority;
JVM_Sleep;
JVM_StartThread;
JVM_StopThread;
JVM_SuspendThread;
JVM_SupportsCX8;
+ JVM_ToStackTraceElement;
JVM_TotalMemory;
JVM_UnloadLibrary;
JVM_Yield;
--- a/hotspot/make/solaris/makefiles/dtrace.make Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/make/solaris/makefiles/dtrace.make Thu Apr 28 23:08:17 2016 -0700
@@ -270,7 +270,7 @@
@echo $(LOG_INFO) Compiling $(DTRACE).d
$(QUIETLY) $(DTRACE_PROG) $(DTRACE_OPTS) -C -I. -G -xlazyload -o $@ -s $(DTRACE).d \
- $(DTraced_Files) ||\
+ $(sort $(DTraced_Files)) ||\
STATUS=$$?;\
if [ x"$$STATUS" = x"1" ]; then \
if [ x`uname -r` = x"5.10" -a \
--- a/hotspot/make/solaris/makefiles/trace.make Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/make/solaris/makefiles/trace.make Thu Apr 28 23:08:17 2016 -0700
@@ -53,13 +53,13 @@
TraceGeneratedNames = \
traceEventClasses.hpp \
- traceEventIds.hpp \
- traceTypes.hpp
+ traceEventIds.hpp \
+ traceTypes.hpp
ifeq ($(HAS_ALT_SRC), true)
- TraceGeneratedNames += \
- traceRequestables.hpp \
- traceEventControl.hpp
+TraceGeneratedNames += \
+ traceRequestables.hpp \
+ traceEventControl.hpp
endif
TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
--- a/hotspot/make/test/JtregNative.gmk Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/make/test/JtregNative.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -47,6 +47,7 @@
$(HOTSPOT_TOPDIR)/test/runtime/jni/ToStringInInterfaceTest \
$(HOTSPOT_TOPDIR)/test/runtime/modules/getModuleJNI \
$(HOTSPOT_TOPDIR)/test/runtime/SameObject \
+ $(HOTSPOT_TOPDIR)/test/runtime/BoolReturn \
$(HOTSPOT_TOPDIR)/test/compiler/floatingpoint/ \
$(HOTSPOT_TOPDIR)/test/compiler/calls \
$(HOTSPOT_TOPDIR)/test/compiler/native \
--- a/hotspot/make/windows/makefiles/debug.make Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/make/windows/makefiles/debug.make Thu Apr 28 23:08:17 2016 -0700
@@ -48,10 +48,10 @@
# Force resources to be rebuilt every time
$(Res_Files): FORCE
+# NOTE: Changes in this file was just to give a proper command line when linking
+# for use when developing the new build, and should not be integrated.
$(AOUT): $(Res_Files) $(Obj_Files) vm.def
- $(LD) @<<
- $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
-<<
+ $(LD) $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
!if "$(MT)" != ""
# The previous link command created a .manifest file that we want to
# insert into the linked artifact so we do not need to track it
--- a/hotspot/make/windows/makefiles/fastdebug.make Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/make/windows/makefiles/fastdebug.make Thu Apr 28 23:08:17 2016 -0700
@@ -47,10 +47,10 @@
# Force resources to be rebuilt every time
$(Res_Files): FORCE
+# NOTE: Changes in this file was just to give a proper command line when linking
+# for use when developing the new build, and should not be integrated.
$(AOUT): $(Res_Files) $(Obj_Files) vm.def
- $(LD) @<<
- $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
-<<
+ $(LD) $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
!if "$(MT)" != ""
# The previous link command created a .manifest file that we want to
# insert into the linked artifact so we do not need to track it
--- a/hotspot/make/windows/makefiles/product.make Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/make/windows/makefiles/product.make Thu Apr 28 23:08:17 2016 -0700
@@ -51,10 +51,11 @@
# Force resources to be rebuilt every time
$(Res_Files): FORCE
+# NOTE: Changes in this file was just to give a proper command line when linking
+# for use when developing the new build, and should not be integrated.
$(AOUT): $(Res_Files) $(Obj_Files) vm.def
- $(LD) @<<
- $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
-<<
+ $(LD) $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
+
!if "$(MT)" != ""
# The previous link command created a .manifest file that we want to
# insert into the linked artifact so we do not need to track it
--- a/hotspot/make/windows/makefiles/trace.make Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/make/windows/makefiles/trace.make Thu Apr 28 23:08:17 2016 -0700
@@ -41,6 +41,12 @@
!endif
!endif
+!ifndef OPENJDK
+!if EXISTS($(TraceAltSrcDir))
+HAS_ALT_SRC = true
+!endif
+!endif
+
TraceGeneratedNames = \
traceEventClasses.hpp \
traceEventIds.hpp \
--- a/hotspot/make/windows/makefiles/vm.make Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/make/windows/makefiles/vm.make Thu Apr 28 23:08:17 2016 -0700
@@ -305,8 +305,10 @@
# This guy should remain a single colon rule because
# otherwise we can't specify the output filename.
+# NOTE: Changes in this file was just to give a proper command line when linking
+# for use when developing the new build, and should not be integrated.
{$(COMMONSRC)\os\windows\vm}.rc.res:
- @$(RC) $(RC_FLAGS) /fo"$@" $<
+ $(RC) $(RC_FLAGS) /fo"$@" $<
{$(COMMONSRC)\cpu\$(Platform_arch)\vm}.cpp.obj::
$(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/BuildHotspot.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,54 @@
+#
+# 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. 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 must be the first rule
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+
+VARIANT_TARGETS := $(foreach v, $(JVM_VARIANTS), variant-$v)
+VARIANT_GENSRC_TARGETS := $(addsuffix -gensrc, $(VARIANT_TARGETS))
+VARIANT_LIBS_TARGETS := $(addsuffix -libs, $(VARIANT_TARGETS))
+
+$(VARIANT_GENSRC_TARGETS): variant-%-gensrc:
+ $(call LogWarn, Building JVM variant '$*' with features '$(JVM_FEATURES_$*)')
+ +$(MAKE) -f gensrc/GenerateSources.gmk JVM_VARIANT=$*
+
+$(VARIANT_LIBS_TARGETS): variant-%-libs: variant-%-gensrc
+ +$(MAKE) -f lib/CompileLibraries.gmk JVM_VARIANT=$*
+
+$(VARIANT_TARGETS): variant-%: variant-%-gensrc variant-%-libs
+
+jsig:
+ +$(MAKE) -f lib/CompileLibjsig.gmk
+
+dist: $(VARIANT_TARGETS) jsig
+ +$(MAKE) -f Dist.gmk
+
+all: dist
+
+.PHONY: $(VARIANT_TARGETS) $(VARIANT_GENSRC_TARGETS) $(VARIANT_LIBS_TARGETS) \
+ jsig dist all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/Dist.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,239 @@
+#
+# 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. 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.
+#
+
+################################################################################
+# Copy the generated output into well-defined places in the dist directory.
+
+# This must be the first rule
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+
+$(eval $(call IncludeCustomExtension, hotspot, Dist.gmk))
+
+DIST_OUTPUTDIR := $(HOTSPOT_OUTPUTDIR)/dist
+
+# Unfortunately, all platforms have different target subdirs.
+ifeq ($(OPENJDK_TARGET_OS), windows)
+ LIB_SUBDIR := bin
+else ifeq ($(OPENJDK_TARGET_OS), macosx)
+ LIB_SUBDIR := lib
+else
+ LIB_SUBDIR := lib$(OPENJDK_TARGET_CPU_LIBDIR)
+endif
+
+################################################################################
+# Functions to setup copying of files for variants
+
+# Support macro for SetupDistLibFile
+define macosx_universalize
+ $(MKDIR) -p $(@D)
+ $(LIPO) -create -output $@ $<
+endef
+
+################################################################################
+# Setup make rules to copy a native library and associated data.
+#
+# Parameter 1 is the name of the rule. This name is used as variable prefix,
+# and the targets generated are listed in a variable by that name.
+#
+# Remaining parameters are named arguments. These include:
+# NAME -- The base name of the native library (e.g. 'jvm')
+# VARIANT -- The variant to copy from
+# VARIANT_TARGET_DIR -- The variant target sub dir, with trailing slash, optional
+SetupDistLibFile = $(NamedParamsMacroTemplate)
+define SetupDistLibFileBody
+ ifneq ($$($1_VARIANT), )
+ $1_SRC_DIR := $$(HOTSPOT_OUTPUTDIR)/variant-$$($1_VARIANT)/lib$$($1_NAME)
+ else
+ $1_SRC_DIR := $$(HOTSPOT_OUTPUTDIR)/lib$$($1_NAME)
+ endif
+ $1_LIB_NAME := $(LIBRARY_PREFIX)$$($1_NAME)
+ $1_TARGET_DIR := $$(DIST_OUTPUTDIR)/$$(LIB_SUBDIR)/$$($1_VARIANT_TARGET_DIR)
+
+ ifeq ($(OPENJDK_TARGET_OS), macosx)
+ # We must use the 'universalize' macro to run lipo on shared libraries, at
+ # least until JDK-8069540 is fixed.
+ $1_MACRO := macosx_universalize
+ endif
+
+ # Copy the the native library.
+ $$(eval $$(call SetupCopyFiles, $1_COPY_LIB, \
+ DEST := $$($1_TARGET_DIR), \
+ MACRO := $$($1_MACRO), \
+ FILES := $$(wildcard \
+ $$($1_SRC_DIR)/$$($1_LIB_NAME)$(SHARED_LIBRARY_SUFFIX)), \
+ ))
+
+ TARGETS += $$($1_COPY_LIB)
+
+ # Copy related data (debug symbols, static-build symbols file etc)
+ $$(eval $$(call SetupCopyFiles, $1_COPY_FILES, \
+ DEST := $$($1_TARGET_DIR), \
+ FILES := $$(wildcard \
+ $$(addprefix $$($1_SRC_DIR)/$$($1_LIB_NAME), \
+ .diz .debuginfo .pdb .map .symbols)), \
+ ))
+
+ TARGETS += $$($1_COPY_FILES)
+
+ ifeq ($(OPENJDK_TARGET_OS), macosx)
+ # Debug symbols on macosx is a directory, not a single file, per library.
+ $1_DSYM_SRC := $$($1_SRC_DIR)/$$($1_LIB_NAME)$(SHARED_LIBRARY_SUFFIX).dSYM)
+ ifneq ($$(wildcard $$($1_DSYM_SRC)), )
+ $$(eval $$(call SetupCopyFiles, $1_COPY_DSYM_DIR, \
+ DEST := $$($1_TARGET_DIR), \
+ SRC := $$($1_SRC_DIR), \
+ FILES := $$(shell $(FIND) $$($1_DSYM_SRC) -type f), \
+ ))
+ TARGETS += $$($1_COPY_DSYM_DIR)
+ endif
+ endif
+endef
+
+################################################################################
+# Copy common files, which are independent on the jvm variant(s) being built.
+# For files that were generated during the build, we assume all versions of
+# these files are identical, and just pick one arbitrarily to use as source.
+
+ANY_JVM_VARIANT := $(firstword $(JVM_VARIANTS))
+JVM_VARIANT_OUTPUTDIR := $(HOTSPOT_OUTPUTDIR)/variant-$(ANY_JVM_VARIANT)
+
+### Copy platform-independent .h files
+INCLUDE_FILES_SRC_DIR := $(HOTSPOT_TOPDIR)/src/share/vm
+$(eval $(call SetupCopyFiles, COPY_INCLUDE, \
+ SRC := $(INCLUDE_FILES_SRC_DIR), \
+ DEST := $(DIST_OUTPUTDIR)/include, \
+ FLATTEN := true, \
+ FILES := $(INCLUDE_FILES_SRC_DIR)/prims/jni.h \
+ $(INCLUDE_FILES_SRC_DIR)/code/jvmticmlr.h \
+ $(INCLUDE_FILES_SRC_DIR)/services/jmm.h))
+
+TARGETS += $(COPY_INCLUDE)
+
+### Copy jni_md.h
+
+# This might have been defined in a custom extension
+ifeq ($(JNI_MD_H_SRC), )
+ JNI_MD_H_SRC := $(HOTSPOT_TOPDIR)/src/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/vm/jni_$(HOTSPOT_TARGET_CPU_ARCH).h
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), macosx)
+ # NOTE: This should most likely be darwin, but the old hotspot build uses bsd
+ JNI_MD_SUBDIR := bsd
+else ifeq ($(OPENJDK_TARGET_OS), windows)
+ JNI_MD_SUBDIR := win32
+else
+ JNI_MD_SUBDIR := $(OPENJDK_TARGET_OS)
+endif
+
+# SetupCopyFiles is not used here since it's non-trivial to copy a single
+# file with a different target name.
+$(DIST_OUTPUTDIR)/include/$(JNI_MD_SUBDIR)/jni_md.h: $(JNI_MD_H_SRC)
+ $(call LogInfo, Copying hotspot/dist/include/$(JNI_MD_SUBDIR)/jni_md.h)
+ $(install-file)
+
+TARGETS += $(DIST_OUTPUTDIR)/include/$(JNI_MD_SUBDIR)/jni_md.h
+
+$(eval $(call SetupCopyFiles, COPY_JVMTI_H, \
+ DEST := $(DIST_OUTPUTDIR)/include, \
+ FLATTEN := true, \
+ FILES := $(JVM_VARIANT_OUTPUTDIR)/gensrc/jvmtifiles/jvmti.h))
+
+TARGETS += $(COPY_JVMTI_H)
+
+# NOTE: In the old build, this file was not copied on Windows.
+ifneq ($(OPENJDK_TARGET_OS), windows)
+ $(eval $(call SetupCopyFiles, COPY_JVMTI_HTML, \
+ DEST := $(DIST_OUTPUTDIR)/docs/platform/jvmti, \
+ FILES := $(JVM_VARIANT_OUTPUTDIR)/gensrc/jvmtifiles/jvmti.html))
+endif
+
+TARGETS += $(COPY_JVMTI_HTML)
+
+ifeq ($(OPENJDK_TARGET_OS), windows)
+ $(eval $(call SetupCopyFiles, COPY_JVM_LIB, \
+ DEST := $(DIST_OUTPUTDIR)/lib, \
+ FILES :=$(JVM_VARIANT_OUTPUTDIR)/libjvm/objs/jvm.lib))
+
+ TARGETS += $(COPY_JVM_LIB)
+endif
+
+# Copy libjsig, if it exists
+$(eval $(call SetupDistLibFile, DIST_jsig, \
+ NAME := jsig, \
+))
+
+################################################################################
+# Copy variant-specific files
+
+# Setup make rules to copy a single variant to dist.
+# $1: The name of the variant
+define SetupDistForVariant
+ ifneq ($$(filter client minimal, $1), )
+ VARIANT_TARGET_DIR := $1
+ else
+ # Use 'server' as default target directory name for all other variants.
+ VARIANT_TARGET_DIR := server
+ endif
+
+ $$(eval $$(call SetupDistLibFile, DIST_$(strip $1)_jvm, \
+ NAME := jvm, \
+ VARIANT := $1, \
+ VARIANT_TARGET_DIR := $$(VARIANT_TARGET_DIR)/, \
+ ))
+
+ # Copy the dtrace libraries, if they exist
+ $$(eval $$(call SetupDistLibFile, DIST_$(strip $1)_jvm_db, \
+ NAME := jvm_db, \
+ VARIANT := $1, \
+ VARIANT_TARGET_DIR := $$(VARIANT_TARGET_DIR)/, \
+ ))
+
+ $$(eval $$(call SetupDistLibFile, DIST_$(strip $1)_jvm_dtrace, \
+ NAME := jvm_dtrace, \
+ VARIANT := $1, \
+ VARIANT_TARGET_DIR := $$(VARIANT_TARGET_DIR)/, \
+ ))
+
+ # Copy the Xusage.txt file
+ $$(eval $$(call SetupCopyFiles, DIST_$(strip $1)_Xusage, \
+ DEST := $$(DIST_OUTPUTDIR)/$$(LIB_SUBDIR)/$(strip $1), \
+ FILES := $$(HOTSPOT_OUTPUTDIR)/variant-$(strip $1)/support/misc/Xusage.txt, \
+ ))
+
+ TARGETS += $$(DIST_$(strip $1)_Xusage)
+endef
+
+$(foreach variant, $(JVM_VARIANTS), \
+ $(eval $(call SetupDistForVariant, $(variant))) \
+)
+
+################################################################################
+
+all: $(TARGETS)
+
+.PHONY: all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/HotspotCommon.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+ifeq ($(JVM_VARIANT), )
+ $(error This makefile must be called with JVM_VARIANT set)
+endif
+
+JVM_VARIANT_OUTPUTDIR := $(HOTSPOT_OUTPUTDIR)/variant-$(JVM_VARIANT)
+JVM_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm
+JVM_SUPPORT_DIR := $(JVM_VARIANT_OUTPUTDIR)/support
+
+DTRACE_SUPPORT_DIR := $(JVM_SUPPORT_DIR)/dtrace
+
+################################################################################
+
+# Test if a feature is available in the present build of JVM_VARIANT. Will return
+# 'true' or 'false'.
+# $1 - the feature to test for
+check-jvm-feature = \
+ $(strip \
+ $(if $(filter-out $(VALID_JVM_FEATURES), $1), \
+ $(error Internal error: Invalid feature tested: $1)) \
+ $(if $(filter $1, $(JVM_FEATURES_$(JVM_VARIANT))), true, false))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/gensrc/GenerateSources.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,75 @@
+#
+# 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. 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.
+#
+
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+include JavaCompilation.gmk
+include NativeCompilation.gmk
+include TextFileProcessing.gmk
+
+include HotspotCommon.gmk
+
+# The real work is done in these files
+
+include gensrc/GensrcAdlc.gmk
+include gensrc/GensrcDtrace.gmk
+include gensrc/GensrcJvmti.gmk
+
+$(eval $(call IncludeCustomExtension, hotspot, gensrc/GenerateSources.gmk))
+
+# While technically the rules below are "gendata" which can be done in parallel
+# with native compilation, let's keep it here for simplicity.
+
+# The Xusage.txt file needs to have platform specific path separator
+$(eval $(call SetupTextFileProcessing, CREATE_XUSAGE, \
+ SOURCE_FILES := $(HOTSPOT_TOPDIR)/src/share/vm/Xusage.txt, \
+ OUTPUT_FILE := $(JVM_SUPPORT_DIR)/misc/Xusage.txt, \
+ REPLACEMENTS := separated by ;> => separated by $(PATH_SEP)> ; , \
+))
+
+TARGETS += $(CREATE_XUSAGE)
+
+# Setup the hotspot launcher script for developer use
+$(eval $(call SetupTextFileProcessing, CREATE_HOTSPOT_LAUNCHER, \
+ SOURCE_FILES := $(HOTSPOT_TOPDIR)/make/hotspot.script, \
+ OUTPUT_FILE := $(JVM_OUTPUTDIR)/hotspot, \
+ REPLACEMENTS := \
+ @@LIBARCH@@ => $(OPENJDK_TARGET_CPU_LEGACY_LIB) ; \
+ @@JDK_IMPORT_PATH@@ => $(JDK_OUTPUTDIR) ; , \
+))
+
+CHMOD_HOTSPOT_LAUNCHER := $(JVM_VARIANT_OUTPUTDIR)/libjvm/_hotspot-script-chmod.marker
+
+$(CHMOD_HOTSPOT_LAUNCHER): $(CREATE_HOTSPOT_LAUNCHER)
+ $(CHMOD) +x $<
+ $(TOUCH) $@
+
+TARGETS += $(CREATE_HOTSPOT_LAUNCHER) $(CHMOD_HOTSPOT_LAUNCHER)
+
+all: $(TARGETS)
+
+.PHONY: all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/gensrc/GensrcAdlc.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,191 @@
+#
+# 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. 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.
+#
+
+$(eval $(call IncludeCustomExtension, hotspot, gensrc/GensrcAdlc.gmk))
+
+ifeq ($(call check-jvm-feature, compiler2), true)
+
+ ADLC_SUPPORT_DIR := $(JVM_SUPPORT_DIR)/adlc
+
+ ##############################################################################
+ # Build the ad compiler (the adlc build tool)
+
+ # Flags depending on the build platform/tool chain
+ # NOTE: No optimization or debug flags set here
+ ifeq ($(OPENJDK_BUILD_OS), linux)
+ ADLC_CFLAGS := -fno-exceptions -DLINUX
+ else ifeq ($(OPENJDK_BUILD_OS), solaris)
+ ADLC_LDFLAGS := -m64
+ ADLC_CFLAGS := -m64
+ ADLC_CFLAGS_WARNINGS := +w
+ else ifeq ($(OPENJDK_BUILD_OS), aix)
+ ADLC_LDFLAGS := -q64
+ ADLC_CFLAGS := -qnortti -qeh -q64 -DAIX
+ else ifeq ($(OPENJDK_BUILD_OS), windows)
+ ADLC_LDFLAGS := -nologo
+ ADLC_CFLAGS := -nologo -EHsc
+ # NOTE: The old build also have -D_CRT_SECURE_NO_DEPRECATE but it doesn't
+ # seem needed any more.
+ ADLC_CFLAGS_WARNINGS := -W3 -D_CRT_SECURE_NO_WARNINGS
+ endif
+
+ # NOTE: The old build didn't set -DASSERT for windows but it doesn't seem to
+ # hurt.
+ ADLC_CFLAGS += -DASSERT
+
+ ADLC_CFLAGS += -D$(HOTSPOT_TARGET_CPU_DEFINE)
+
+ ADLC_CFLAGS += -I$(HOTSPOT_TOPDIR)/src/share/vm
+
+ $(eval $(call SetupNativeCompilation, BUILD_ADLC, \
+ TOOLCHAIN := TOOLCHAIN_BUILD_LINK_CXX, \
+ SRC := $(HOTSPOT_TOPDIR)/src/share/vm/adlc, \
+ EXTRA_FILES := $(HOTSPOT_TOPDIR)/src/share/vm/opto/opcodes.cpp, \
+ CFLAGS := $(ADLC_CFLAGS) $(ADLC_CFLAGS_WARNINGS), \
+ LDFLAGS := $(ADLC_LDFLAGS), \
+ LIBS := $(ADLC_LIBS), \
+ OBJECT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/adlc/objs, \
+ OUTPUT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/adlc, \
+ PROGRAM := adlc, \
+ DEBUG_SYMBOLS := false, \
+ DISABLED_WARNINGS_clang := parentheses tautological-compare, \
+ DISABLED_WARNINGS_solstudio := notemsource, \
+ ))
+
+ ADLC_TOOL := $(BUILD_ADLC_TARGET)
+
+ ##############################################################################
+ # Transform the ad source files into C++ source files using adlc
+
+ # Setup flags for the adlc build tool (ADLCFLAGS).
+ ADLCFLAGS += -q -T
+
+ # ADLC flags depending on target OS
+ ifeq ($(OPENJDK_TARGET_OS), linux)
+ ADLCFLAGS += -DLINUX=1 -D_GNU_SOURCE=1
+ else ifeq ($(OPENJDK_TARGET_OS), solaris)
+ ADLCFLAGS += -DSOLARIS=1 -DSPARC_WORKS=1
+ else ifeq ($(OPENJDK_TARGET_OS), aix)
+ ADLCFLAGS += -DAIX=1
+ else ifeq ($(OPENJDK_TARGET_OS), macosx)
+ ADLCFLAGS += -D_ALLBSD_SOURCE=1 -D_GNU_SOURCE=1
+ endif
+
+ ifneq ($(OPENJDK_TARGET_OS), windows)
+ # NOTE: Windows adlc flags was different in the old build. Is this really
+ # correct?
+
+ # -g makes #line directives in the generated C++ files.
+ ADLCFLAGS += -g
+
+ ADLCFLAGS += -D$(HOTSPOT_TARGET_CPU_DEFINE)=1
+ endif
+
+ # This generates checks in the generated C++ files that _LP64 is correctly
+ # (un)defined when compiling them.
+ ifeq ($(OPENJDK_TARGET_CPU_BITS), 64)
+ ADLCFLAGS += -D_LP64=1
+ else
+ ADLCFLAGS += -U_LP64
+ endif
+
+ ##############################################################################
+ # Concatenate all ad source files into a single file, which will be fed to
+ # adlc. Also include a #line directive at the start of every included file
+ # (after the initial header block), stating the original source file name.
+ #
+ # Normally, debugging is done directly on the ad_<arch>*.cpp files, but the
+ # #line directives in those files will be pointing back to <arch>.ad.
+
+ # AD_SRC_ROOTS might have been added to by a custom extension
+ AD_SRC_ROOTS += $(HOTSPOT_TOPDIR)/src
+
+ AD_SRC_FILES := $(call uniq, $(wildcard $(foreach d, $(AD_SRC_ROOTS), \
+ $d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/vm/$(HOTSPOT_TARGET_CPU).ad \
+ $d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/vm/$(HOTSPOT_TARGET_CPU_ARCH).ad \
+ $d/os_cpu/$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU_ARCH)/vm/$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU_ARCH).ad \
+ )))
+
+ SINGLE_AD_SRCFILE := $(ADLC_SUPPORT_DIR)/all-ad-src.ad
+
+ INSERT_FILENAME_AWK_SCRIPT := \
+ '{ \
+ if (CUR_FN != FILENAME) { CUR_FN=FILENAME; NR_BASE=NR-1; need_lineno=1 } \
+ if (need_lineno && $$0 !~ /\/\//) \
+ { print "\n\n\#line " (NR-NR_BASE) " \"" FILENAME "\""; need_lineno=0 }; \
+ print \
+ }'
+
+ $(SINGLE_AD_SRCFILE): $(AD_SRC_FILES)
+ $(call LogInfo, Preprocessing adlc files $(^F))
+ $(call MakeDir, $(@D))
+ $(NAWK) $(INSERT_FILENAME_AWK_SCRIPT) $^ > $@
+
+ ##############################################################################
+ # Run the adlc tool on the single concatenated ad source file, and store the
+ # output in support/adlc for further processing.
+ ADLC_RUN_MARKER := $(ADLC_SUPPORT_DIR)/_adlc_run.marker
+
+ $(ADLC_RUN_MARKER): $(BUILD_ADLC) $(SINGLE_AD_SRCFILE)
+ $(call LogInfo, Generating adlc files)
+ $(call MakeDir, $(@D))
+ $(call ExecuteWithLog, $(ADLC_SUPPORT_DIR)/adlc_run, \
+ $(FIXPATH) $(ADLC_TOOL) $(ADLCFLAGS) $(SINGLE_AD_SRCFILE) \
+ -c$(ADLC_SUPPORT_DIR)/ad_$(HOTSPOT_TARGET_CPU).cpp \
+ -h$(ADLC_SUPPORT_DIR)/ad_$(HOTSPOT_TARGET_CPU).hpp \
+ -a$(ADLC_SUPPORT_DIR)/dfa_$(HOTSPOT_TARGET_CPU).cpp \
+ -v$(ADLC_SUPPORT_DIR)/adGlobals_$(HOTSPOT_TARGET_CPU).hpp)
+ $(TOUCH) $@
+
+ ##############################################################################
+ # Finally copy the generated files from support/adlc into gensrc/adfiles,
+ # and postprocess them by fixing dummy #line directives.
+
+ ADLC_GENERATED_FILES := $(addprefix $(JVM_VARIANT_OUTPUTDIR)/gensrc/adfiles/, \
+ ad_$(HOTSPOT_TARGET_CPU).cpp \
+ ad_$(HOTSPOT_TARGET_CPU).hpp \
+ ad_$(HOTSPOT_TARGET_CPU)_clone.cpp \
+ ad_$(HOTSPOT_TARGET_CPU)_expand.cpp \
+ ad_$(HOTSPOT_TARGET_CPU)_format.cpp \
+ ad_$(HOTSPOT_TARGET_CPU)_gen.cpp \
+ ad_$(HOTSPOT_TARGET_CPU)_misc.cpp \
+ ad_$(HOTSPOT_TARGET_CPU)_peephole.cpp \
+ ad_$(HOTSPOT_TARGET_CPU)_pipeline.cpp \
+ adGlobals_$(HOTSPOT_TARGET_CPU).hpp \
+ dfa_$(HOTSPOT_TARGET_CPU).cpp \
+ )
+
+ $(JVM_VARIANT_OUTPUTDIR)/gensrc/adfiles/%: $(ADLC_RUN_MARKER)
+ $(call LogInfo, Postprocessing adlc file $*)
+ $(call MakeDir, $(@D))
+ $(NAWK) \
+ 'BEGIN { print "#line 1 \"$*\""; } \
+ /^#line 999999$$/ {print "#line " (NR+1) " \"$*\""; next} \
+ {print}' \
+ < $(ADLC_SUPPORT_DIR)/$* > $@
+
+ TARGETS := $(ADLC_GENERATED_FILES)
+
+endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/gensrc/GensrcDtrace.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,56 @@
+#
+# 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. 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.
+#
+
+################################################################################
+# Gensrc support for dtrace. The files generated here are included by dtrace.hpp
+
+ifeq ($(call check-jvm-feature, dtrace), true)
+
+ ifeq ($(OPENJDK_TARGET_OS), solaris)
+ DTRACE_FLAGS := -64
+ DTRACE_CPP_FLAGS := -D_LP64
+ else ifeq ($(OPENJDK_TARGET_OS), macosx)
+ DTRACE_CPP_FLAGS := -D_LP64 -x c
+ else ifeq ($(OPENJDK_TARGET_OS), linux)
+ DTRACE_CPP_FLAGS := -x c
+ endif
+
+ DTRACE_SOURCE_DIR := $(HOTSPOT_TOPDIR)/src/os/posix/dtrace
+ DTRACE_GENSRC_DIR := $(JVM_VARIANT_OUTPUTDIR)/gensrc/dtracefiles
+
+ # Make sure we run our selected compiler for preprocessing instead of letting
+ # the dtrace tool pick it on it's own.
+ $(DTRACE_GENSRC_DIR)/%.h: $(DTRACE_SOURCE_DIR)/%.d
+ $(call LogInfo, Generating dtrace header file $(@F))
+ $(call MakeDir, $(@D) $(DTRACE_SUPPORT_DIR))
+ $(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).d, $(CC) -E $(DTRACE_CPP_FLAGS) $< > $(DTRACE_SUPPORT_DIR)/$(@F).d)
+ $(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -h -o $@ -s $(DTRACE_SUPPORT_DIR)/$(@F).d)
+
+ # Process all .d files in DTRACE_SOURCE_DIR. They are:
+ # hotspot_jni.d hotspot.d hs_private.d
+ TARGETS += $(patsubst $(DTRACE_SOURCE_DIR)/%.d, \
+ $(DTRACE_GENSRC_DIR)/%.h, $(wildcard $(DTRACE_SOURCE_DIR)/*.d))
+
+endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/gensrc/GensrcJvmti.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,174 @@
+#
+# 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. 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.
+#
+
+$(eval $(call IncludeCustomExtension, hotspot, gensrc/GensrcJvmti.gmk))
+
+################################################################################
+# Build tools needed for the JVMTI source code generation
+
+JVMTI_TOOLS_SRCDIR := $(HOTSPOT_TOPDIR)/src/share/vm/prims
+JVMTI_TOOLS_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/tools/jvmti
+
+$(eval $(call SetupJavaCompiler, GENERATE_OLDBYTECODE, \
+ JAVAC := $(JAVAC), \
+ FLAGS := $(DISABLE_WARNINGS), \
+ SERVER_DIR := $(SJAVAC_SERVER_DIR), \
+ SERVER_JVM := $(SJAVAC_SERVER_JAVA), \
+ DISABLE_SJAVAC := true, \
+))
+
+$(eval $(call SetupJavaCompilation, BUILD_JVMTI_TOOLS, \
+ SETUP := GENERATE_OLDBYTECODE, \
+ SRC := $(JVMTI_TOOLS_SRCDIR), \
+ INCLUDE_FILES := jvmtiGen.java jvmtiEnvFill.java, \
+ BIN := $(JVMTI_TOOLS_OUTPUTDIR), \
+))
+
+TOOL_JVMTI_GEN := $(JAVA_SMALL) -cp $(JVMTI_TOOLS_OUTPUTDIR) jvmtiGen
+TOOL_JVMTI_ENV_FILL := $(JAVA_SMALL) -cp $(JVMTI_TOOLS_OUTPUTDIR) jvmtiEnvFill
+
+################################################################################
+# Setup make rules for an xml transform for jvmti/trace file generation.
+#
+# Parameter 1 is the name of the rule. This name is used as variable prefix,
+# and the targets generated are listed in a variable by that name. This name is
+# also used as the name of the output file.
+#
+# Remaining parameters are named arguments. These include:
+# XML_FILE -- The input source file to use
+# XSL_FILE -- The xsl file to use
+# OUTPUT_DIR -- The directory to put the generated file in
+# ARGS -- Additional arguments to the jvmtiGen tool
+# DEPS -- Additional dependencies
+SetupXslTransform = $(NamedParamsMacroTemplate)
+define SetupXslTransformBody
+ $$($1_OUTPUT_DIR)/$1: $$($1_XML_FILE) $$($1_XSL_FILE) $$($1_DEPS) $$(BUILD_JVMTI_TOOLS)
+ $$(call LogInfo, Generating $$(@F))
+ $$(call MakeDir, $$(@D))
+ $$(call ExecuteWithLog, $$@, $$(TOOL_JVMTI_GEN) -IN $$($1_XML_FILE) -XSL $$($1_XSL_FILE) -OUT $$@ $$($1_ARGS))
+ # jvmtiGen does not return error code properly on fail.
+ # NOTE: We should really fix jvmtiGen.java instead.
+ test -f $$@
+
+ TARGETS += $$($1_OUTPUT_DIR)/$1
+endef
+
+################################################################################
+# Create JVMTI files in gensrc/jvmtifiles
+
+JVMTI_SRCDIR := $(HOTSPOT_TOPDIR)/src/share/vm/prims
+JVMTI_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/gensrc/jvmtifiles
+
+# Setup rule for generating a jvmti file
+#
+# $1 is generated source file name in $(JVMTI_OUTPUTDIR)
+# $2 is XSL file to use in $(JVMTI_SRCDIR)
+# $3 is optional extra arguments to jvmtiGen
+define SetupJvmtiGeneration
+ $$(eval $$(call SetupXslTransform, $1, \
+ XML_FILE := $$(JVMTI_SRCDIR)/jvmti.xml, \
+ XSL_FILE := $$(JVMTI_SRCDIR)/$(strip $2), \
+ OUTPUT_DIR := $$(JVMTI_OUTPUTDIR), \
+ ARGS := $3, \
+ DEPS := $$(JVMTI_SRCDIR)/jvmtiLib.xsl, \
+ ))
+endef
+
+$(eval $(call SetupJvmtiGeneration, jvmtiEnter.cpp, jvmtiEnter.xsl, \
+ -PARAM interface jvmti))
+$(eval $(call SetupJvmtiGeneration, jvmtiEnterTrace.cpp, jvmtiEnter.xsl, \
+ -PARAM interface jvmti -PARAM trace Trace))
+$(eval $(call SetupJvmtiGeneration, jvmtiEnv.hpp, jvmtiHpp.xsl))
+$(eval $(call SetupJvmtiGeneration, jvmti.h, jvmtiH.xsl))
+$(eval $(call SetupJvmtiGeneration, jvmti.html, jvmti.xsl))
+$(eval $(call SetupJvmtiGeneration, jvmtiEnvStub.cpp, jvmtiEnv.xsl))
+
+JVMTI_BC_SRCDIR := $(HOTSPOT_TOPDIR)/src/share/vm/interpreter
+
+$(eval $(call SetupXslTransform, bytecodeInterpreterWithChecks.cpp, \
+ XML_FILE := $(JVMTI_BC_SRCDIR)/bytecodeInterpreterWithChecks.xml, \
+ XSL_FILE := $(JVMTI_BC_SRCDIR)/bytecodeInterpreterWithChecks.xsl, \
+ OUTPUT_DIR := $(JVMTI_OUTPUTDIR), \
+ DEPS := $(JVMTI_BC_SRCDIR)/bytecodeInterpreter.cpp, \
+))
+
+# We need $(JVMTI_OUTPUTDIR)/jvmtiEnvStub.cpp (generated above) as input
+$(JVMTI_OUTPUTDIR)/jvmtiEnvRecommended.cpp: $(JVMTI_SRCDIR)/jvmtiEnv.cpp \
+ $(JVMTI_OUTPUTDIR)/jvmtiEnvStub.cpp $(BUILD_JVMTI_TOOLS)
+ $(call LogInfo, Generating $(@F))
+ $(call MakeDir, $(@D))
+ $(call ExecuteWithLog, $@, $(TOOL_JVMTI_ENV_FILL) $(JVMTI_SRCDIR)/jvmtiEnv.cpp \
+ $(JVMTI_OUTPUTDIR)/jvmtiEnvStub.cpp \
+ $(JVMTI_OUTPUTDIR)/jvmtiEnvRecommended.cpp)
+ # jvmtiEnvFill does not necessarily return an error code on failure.
+ # NOTE: We should really fix jvmtiEnvFill.java instead.
+ test -f $@
+
+TARGETS += $(JVMTI_OUTPUTDIR)/jvmtiEnvRecommended.cpp
+
+################################################################################
+# Create trace files in gensrc/tracefiles
+
+TRACE_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/gensrc/tracefiles
+TRACE_SRCDIR := $(HOTSPOT_TOPDIR)/src/share/vm/trace
+
+# Append directories to search (might have been set by custom extensions)
+TRACE_SEARCH_DIRS += $(TRACE_SRCDIR)
+
+TRACE_XML ?= $(TRACE_SRCDIR)/trace.xml
+
+# Changing these will trigger a rebuild of generated trace files.
+TRACE_DEPS += \
+ $(TRACE_XML) \
+ $(TRACE_SRCDIR)/tracetypes.xml \
+ $(TRACE_SRCDIR)/tracerelationdecls.xml \
+ $(TRACE_SRCDIR)/traceevents.xml \
+ $(TRACE_SRCDIR)/trace.dtd \
+ $(TRACE_SRCDIR)/xinclude.mod \
+ #
+
+# Setup rule for generating a trace file
+#
+# $1 is generated source file name in $(TRACE_OUTPUTDIR)
+define SetupTraceGeneration
+ $$(eval $$(call SetupXslTransform, $1, \
+ XML_FILE := $$(TRACE_XML), \
+ XSL_FILE := $$(firstword $$(wildcard $$(addsuffix /$$(basename $1).xsl, $$(TRACE_SEARCH_DIRS)))), \
+ OUTPUT_DIR := $$(TRACE_OUTPUTDIR), \
+ DEPS := $$(TRACE_DEPS), \
+ ))
+endef
+
+# Append files to generated (might have been set by custom extensions)
+TRACE_GENSRC_FILES += \
+ traceEventClasses.hpp \
+ traceEventIds.hpp \
+ traceTypes.hpp \
+ #
+
+# Call SetupTraceGeneration for all trace gensrc files
+$(foreach tracefile, $(TRACE_GENSRC_FILES), \
+ $(eval $(call SetupTraceGeneration, $(tracefile))) \
+)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/ide/CreateVSProject.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,153 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# This must be the first rule
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+include JavaCompilation.gmk
+include SetupJavaCompilers.gmk
+
+ifeq ($(OPENJDK_TARGET_OS), windows)
+ # The next part is a bit hacky. We include the CompileJvm.gmk to be
+ # able to extact flags, but we do not wish to execute the rules.
+
+ # Use client as base for defines and includes
+ JVM_VARIANT=client
+
+ include HotspotCommon.gmk
+ include lib/CompileJvm.gmk
+
+ # Reset targets so we don't build libjvm.
+ TARGETS :=
+
+ # Helper macro to convert a unix path to a Windows path, suitable for
+ # inclusion in a command line.
+ FixPath = \
+ $(strip $(subst \,\\,$(shell $(CYGPATH) -w $1)))
+
+ JVM_DEFINES_client := $(patsubst -D%,%, $(filter -D%, $(JVM_CFLAGS)))
+ EXTRACTED_DEFINES_client := $(addprefix -define , $(JVM_DEFINES_client))
+
+ JVM_INCLUDES_client := $(patsubst -I%,%, $(filter -I%, $(JVM_CFLAGS)))
+ EXTRACTED_INCLUDES_client := $(foreach path, $(JVM_INCLUDES_client), -absoluteInclude $(call FixPath, $(path)))
+
+ # Hand-code variant-specific arguments, based on the fact that we use
+ # client for general arguments. Not optimal but other solutions require
+ # major changes in ProjectCreator.
+ ADDITIONAL_VARIANT_ARGS := \
+ -define_server COMPILER2 \
+ -ignorePath_client adfiles \
+ -ignorePath_client c2_ \
+ -ignorePath_client runtime_ \
+ -ignorePath_client libadt \
+ -ignorePath_client opto \
+ #
+
+ IGNORED_PLATFORMS_ARGS := \
+ -ignorePath aarch64 \
+ -ignorePath aix \
+ -ignorePath arm \
+ -ignorePath bsd \
+ -ignorePath linux \
+ -ignorePath posix \
+ -ignorePath ppc \
+ -ignorePath shark \
+ -ignorePath solaris \
+ -ignorePath sparc \
+ -ignorePath x86_32 \
+ -ignorePath zero \
+ #
+
+ ################################################################################
+ # Build the ProjectCreator java tool.
+
+ TOOLS_OUTPUTDIR := $(HOTSPOT_OUTPUTDIR)/support/tools_classes
+
+ $(eval $(call SetupJavaCompilation, BUILD_PROJECT_CREATOR, \
+ SETUP := GENERATE_OLDBYTECODE, \
+ ADD_JAVAC_FLAGS := -Xlint:-auxiliaryclass, \
+ SRC := $(HOTSPOT_TOPDIR)/makefiles/src/classes, \
+ BIN := $(TOOLS_OUTPUTDIR), \
+ ))
+
+ TARGETS += $(BUILD_PROJECT_CREATOR)
+
+ # Run the ProjectCreator tool
+ PROJECT_CREATOR_TOOL := $(JAVA_SMALL) -cp $(TOOLS_OUTPUTDIR) build.tools.projectcreator.ProjectCreator
+
+ IDE_OUTPUTDIR := $(BUILD_OUTPUT)/ide/hotspot-visualstudio
+
+ VCPROJ_FILE := $(IDE_OUTPUTDIR)/jvm.vcxproj
+
+ PROJECT_CREATOR_CLASS := build.tools.projectcreator.WinGammaPlatformVC10
+
+ # We hard-code gensrc dir to server (since this includes adfiles)
+ PROJECT_CREATOR_ARGS := \
+ -sourceBase $(call FixPath, $(HOTSPOT_TOPDIR)) \
+ -startAt src \
+ -relativeSrcInclude src \
+ -hidePath .hg \
+ -hidePath .jcheck \
+ -hidePath jdk.hotspot.agent \
+ -hidePath jdk.vm.ci \
+ -hidePath jdk.jfr \
+ -compiler VC10 \
+ -jdkTargetRoot $(call FixPath, $(JDK_OUTPUTDIR)) \
+ -platformName x64 \
+ -buildBase $(call FixPath, $(IDE_OUTPUTDIR)/vs-output) \
+ -buildSpace $(call FixPath, $(IDE_OUTPUTDIR)) \
+ -makeBinary $(call FixPath, $(MAKE)) \
+ -makeOutput $(call FixPath, $(HOTSPOT_OUTPUTDIR)/variant-%f/libjvm) \
+ -absoluteInclude $(call FixPath, $(HOTSPOT_OUTPUTDIR)/variant-server/gensrc) \
+ -absoluteSrcInclude $(call FixPath, $(HOTSPOT_OUTPUTDIR)/variant-server/gensrc) \
+ $(EXTRACTED_DEFINES_client) \
+ $(EXTRACTED_INCLUDES_client) \
+ $(ADDITIONAL_VARIANT_ARGS) \
+ $(IGNORED_PLATFORMS_ARGS) \
+ #
+
+ VCPROJ_VARDEPS := $(PROJECT_CREATOR_CLASS) $(PROJECT_CREATOR_ARGS)
+ VCPROJ_VARDEPS_FILE := $(call DependOnVariable, VCPROJ_VARDEPS, \
+ $(VCPROJ_FILE).vardeps)
+
+ $(VCPROJ_FILE): $(BUILD_PROJECT_CREATOR) $(VCPROJ_VARDEPS_FILE)
+ $(call MakeDir, $(@D))
+ $(call ExecuteWithLog, $@, \
+ $(PROJECT_CREATOR_TOOL) $(PROJECT_CREATOR_CLASS) \
+ $(PROJECT_CREATOR_ARGS) -projectFileName $(call FixPath, $@)) \
+ $(LOG_INFO)
+
+ TARGETS += $(VCPROJ_FILE)
+
+ all: $(TARGETS)
+
+else
+ all:
+ $(info Hotspot Visual Studio generation only supported on Windows)
+endif
+
+.PHONY: all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/lib/CompileDtracePostJvm.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,217 @@
+#
+# 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. 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.
+#
+
+################################################################################
+# Support for dtrace integration with libjvm, and stand-alone dtrace library
+# compilation.
+
+ifeq ($(call check-jvm-feature, dtrace), true)
+ ##############################################################################
+
+ ifeq ($(OPENJDK_TARGET_OS), solaris)
+ ############################################################################
+ # Integrate with libjvm. Here we generate three object files which are
+ # linked with libjvm.so. This step is complicated from a dependency
+ # perspective, since it needs the rest of the compiled object files from the
+ # libjvm compilation, but the output is object files that are to be included
+ # when linking libjvm.so. So this generation must happen as a part of the
+ # libjvm compilation.
+
+ # First we need to generate the dtraceGenOffsets tool. When run, this will
+ # produce more header files and a C++ file.
+
+ # Note that generateJvmOffsets.cpp must be compiled as if it were a file
+ # in the libjvm.so, using JVM_CFLAGS as setup in CompileJvm.gmk. Otherwise
+ # this would preferrably have been done as a part of GensrcDtrace.gmk.
+ $(eval $(call SetupNativeCompilation, BUILD_DTRACE_GEN_OFFSETS, \
+ SRC := $(HOTSPOT_TOPDIR)/src/os/$(OPENJDK_TARGET_OS)/dtrace, \
+ INCLUDE_FILES := generateJvmOffsets.cpp generateJvmOffsetsMain.c, \
+ CC := $(BUILD_CXX), \
+ CXX := $(BUILD_CXX), \
+ LDEXE := $(BUILD_CXX), \
+ generateJvmOffsets.cpp_CXXFLAGS := $(JVM_CFLAGS) -mt -xnolib -norunpath, \
+ generateJvmOffsetsMain.c_CFLAGS := -library=%none -mt -m64 -norunpath -z nodefs, \
+ LDFLAGS := -m64, \
+ LIBS := -lc, \
+ OBJECT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets/objs, \
+ OUTPUT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets, \
+ PROGRAM := dtraceGenOffsets, \
+ ))
+
+ DTRACE_GEN_OFFSETS_TOOL := $(BUILD_DTRACE_GEN_OFFSETS_TARGET)
+
+ # Argument 1: Output filename
+ # Argument 2: dtrace-gen-offset tool command line option
+ define SetupDtraceOffsetsGeneration
+ $1: $$(BUILD_DTRACE_GEN_OFFSETS)
+ $$(call LogInfo, Generating dtrace $2 file $$(@F))
+ $$(call MakeDir, $$(@D))
+ $$(call ExecuteWithLog, $$@, $$(DTRACE_GEN_OFFSETS_TOOL) -$$(strip $2) > $$@)
+
+ TARGETS += $1
+ endef
+
+ JVM_OFFSETS_H := $(DTRACE_SUPPORT_DIR)/JvmOffsets.h
+ JVM_OFFSETS_CPP := $(DTRACE_SUPPORT_DIR)/JvmOffsets.cpp
+ JVM_OFFSETS_INDEX_H := $(DTRACE_SUPPORT_DIR)/JvmOffsetsIndex.h
+
+ # Run the dtrace-gen-offset tool to generate these three files.
+ $(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_H), header))
+ $(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_INDEX_H), index))
+ $(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_CPP), table))
+
+ ############################################################################
+ # Compile JVM_OFFSETS_OBJ which is linked with libjvm.so.
+
+ # JvmOffsets.cpp is compiled without the common JVM_CFLAGS. Otherwise, the
+ # natural way would have been to included this source code in BUILD_LIBJVM.
+ JVM_OFFSETS_CFLAGS := -m64
+ ifeq ($(OPENJDK_TARGET_CPU), sparcv9)
+ JVM_OFFSETS_CFLAGS += -xarch=sparc
+ endif
+
+ $(JVM_OFFSETS_OBJ): $(JVM_OFFSETS_CPP) $(JVM_OFFSETS_H)
+ $(call LogInfo, Compiling dtrace file JvmOffsets.cpp (for libjvm.so))
+ $(call ExecuteWithLog, $@, $(CXX) -c -I$(<D) -o $@ $(JVM_OFFSETS_CFLAGS) $<)
+
+ ############################################################################
+ # Generate DTRACE_OBJ which is linked with libjvm.so.
+
+ # Concatenate all *.d files into a single file
+ DTRACE_SOURCE_FILES := $(addprefix $(HOTSPOT_TOPDIR)/src/os/posix/dtrace/, \
+ hotspot_jni.d \
+ hotspot.d \
+ hs_private.d \
+ )
+
+ $(JVM_OUTPUTDIR)/objs/dtrace.d: $(DTRACE_SOURCE_FILES)
+ $(call LogInfo, Generating $(@F))
+ $(call MakeDir, $(@D))
+ $(CAT) $^ > $@
+
+ DTRACE_INSTRUMENTED_OBJS := $(addprefix $(JVM_OUTPUTDIR)/objs/, \
+ ciEnv.o \
+ classLoadingService.o \
+ compileBroker.o \
+ hashtable.o \
+ instanceKlass.o \
+ java.o \
+ jni.o \
+ jvm.o \
+ memoryManager.o \
+ nmethod.o \
+ objectMonitor.o \
+ runtimeService.o \
+ sharedRuntime.o \
+ synchronizer.o \
+ thread.o \
+ unsafe.o \
+ vmThread.o \
+ vmGCOperations.o \
+ )
+
+ ifeq ($(call check-jvm-feature, all-gcs), true)
+ DTRACE_INSTRUMENTED_OBJS += $(addprefix $(JVM_OUTPUTDIR)/objs/, \
+ vmCMSOperations.o \
+ vmPSOperations.o \
+ )
+ endif
+
+ DTRACE_FLAGS := -64 -G
+ DTRACE_CPP_FLAGS := -D_LP64
+
+ # Make sure we run our selected compiler for preprocessing instead of letting
+ # the dtrace tool pick it on it's own.
+ $(DTRACE_OBJ): $(JVM_OUTPUTDIR)/objs/dtrace.d $(DTRACE_INSTRUMENTED_OBJS)
+ $(call LogInfo, Generating $(@F) from $(<F) and object files)
+ $(call MakeDir, $(DTRACE_SUPPORT_DIR))
+ $(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).d, $(CC) -E \
+ $(DTRACE_CPP_FLAGS) $< > $(DTRACE_SUPPORT_DIR)/$(@F).d)
+ $(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -xlazyload -o $@ \
+ -s $(DTRACE_SUPPORT_DIR)/$(@F).d $(sort $(DTRACE_INSTRUMENTED_OBJS)))
+
+ ############################################################################
+ # Generate DTRACE_JHELPER_OBJ which is linked with libjvm.so.
+
+ # Unfortunately dtrace generates incorrect types for some symbols in
+ # dtrace_jhelper.o, resulting in "warning: symbol X has differing types"
+ # This is tracked in JDK-6890703.
+ $(DTRACE_JHELPER_OBJ): $(HOTSPOT_TOPDIR)/src/os/solaris/dtrace/jhelper.d \
+ $(JVM_OFFSETS_INDEX_H)
+ $(call LogInfo, Running dtrace for $(<F))
+ $(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) $(DTRACE_CPP_FLAGS) -C \
+ -I$(DTRACE_SUPPORT_DIR) -o $@ -s $<)
+
+ # NOTE: We should really do something like this, but unfortunately this
+ # results in a compilation error. :-(
+ # $(call MakeDir, $(DTRACE_SUPPORT_DIR))
+ # $(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).d, $(CC) -E \
+ # $(DTRACE_CPP_FLAGS) -I$(DTRACE_SUPPORT_DIR) $^ \
+ # > $(DTRACE_SUPPORT_DIR)/$(@F).d)
+ # $(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -o $@ \
+ # -s $(DTRACE_SUPPORT_DIR)/$(@F).d)
+
+ ############################################################################
+ # Build the stand-alone dtrace libraries
+
+ LIBJVM_DTRACE_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm_dtrace
+
+ $(eval $(call SetupNativeCompilation, BUILD_LIBJVM_DTRACE, \
+ LIBRARY := jvm_dtrace, \
+ OUTPUT_DIR := $(LIBJVM_DTRACE_OUTPUTDIR), \
+ SRC := $(HOTSPOT_TOPDIR)/src/os/solaris/dtrace, \
+ INCLUDE_FILES := jvm_dtrace.c, \
+ CFLAGS := -m64 -G -mt -KPIC, \
+ LDFLAGS := -m64 -mt -xnolib $(SHARED_LIBRARY_FLAGS), \
+ LIBS := $(LIBDL) -lc -lthread -ldoor, \
+ MAPFILE := $(HOTSPOT_TOPDIR)/makefiles/mapfiles/libjvm_dtrace/mapfile-vers, \
+ OBJECT_DIR := $(LIBJVM_DTRACE_OUTPUTDIR)/objs, \
+ STRIP_SYMBOLS := true, \
+ ))
+
+ LIBJVM_DB_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm_db
+
+ # Note that libjvm_db.c has tests for COMPILER2, but this was never set by
+ # the old build.
+ $(eval $(call SetupNativeCompilation, BUILD_LIBJVM_DB, \
+ LIBRARY := jvm_db, \
+ OUTPUT_DIR := $(LIBJVM_DB_OUTPUTDIR), \
+ SRC := $(HOTSPOT_TOPDIR)/src/os/solaris/dtrace, \
+ INCLUDE_FILES := libjvm_db.c, \
+ CFLAGS := -I$(JVM_VARIANT_OUTPUTDIR)/gensrc -I$(DTRACE_SUPPORT_DIR) \
+ -m64 -G -mt -KPIC, \
+ LDFLAGS := -m64 -mt -xnolib $(SHARED_LIBRARY_FLAGS), \
+ LIBS := -lc, \
+ MAPFILE := $(HOTSPOT_TOPDIR)/makefiles/mapfiles/libjvm_db/mapfile-vers, \
+ OBJECT_DIR := $(LIBJVM_DB_OUTPUTDIR)/objs, \
+ STRIP_SYMBOLS := true, \
+ ))
+
+ # We need the generated JvmOffsets.h before we can compile the libjvm_db source code.
+ $(BUILD_LIBJVM_DB_ALL_OBJS): $(JVM_OFFSETS_H)
+
+ TARGETS += $(BUILD_LIBJVM_DTRACE) $(BUILD_LIBJVM_DB)
+ endif
+endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/lib/CompileDtracePreJvm.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. 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.
+#
+
+ifeq ($(call check-jvm-feature, dtrace), true)
+ ifeq ($(OPENJDK_TARGET_OS), solaris)
+ # These files are are generated by CompileDtrace.gmk but consumed by
+ # CompileJvm.gmk
+ DTRACE_OBJ := $(JVM_OUTPUTDIR)/objs/dtrace.o
+ DTRACE_JHELPER_OBJ := $(JVM_OUTPUTDIR)/objs/dtrace_jhelper.o
+ JVM_OFFSETS_OBJ := $(JVM_OUTPUTDIR)/objs/JvmOffsets.o
+
+ DTRACE_EXTRA_OBJECT_FILES := $(DTRACE_OBJ) $(DTRACE_JHELPER_OBJ) $(JVM_OFFSETS_OBJ)
+ endif
+endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/lib/CompileJvm.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,242 @@
+#
+# 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. 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.
+#
+
+# Include support files that will setup compiler flags due to the selected
+# jvm feature set, and specific file overrides.
+include lib/JvmFeatures.gmk
+include lib/JvmOverrideFiles.gmk
+
+$(eval $(call IncludeCustomExtension, hotspot, lib/CompileJvm.gmk))
+
+################################################################################
+# Setup compilation of the main Hotspot native library (libjvm).
+
+JVM_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm
+JVM_MAPFILE := $(JVM_OUTPUTDIR)/mapfile
+
+################################################################################
+# Platform independent setup
+
+# This variable may be added to by a custom extension
+JVM_SRC_ROOTS += $(HOTSPOT_TOPDIR)/src
+
+JVM_SRC_DIRS += $(call uniq, $(wildcard $(foreach d, $(JVM_SRC_ROOTS), \
+ $d/share/vm \
+ $d/os/$(HOTSPOT_TARGET_OS)/vm \
+ $d/os/$(HOTSPOT_TARGET_OS_TYPE)/vm \
+ $d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/vm \
+ $d/os_cpu/$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU_ARCH)/vm \
+ ))) \
+ $(JVM_VARIANT_OUTPUTDIR)/gensrc/jvmtifiles \
+ $(JVM_VARIANT_OUTPUTDIR)/gensrc/tracefiles \
+ #
+
+JVM_CFLAGS_INCLUDES += \
+ $(patsubst %,-I%,$(filter-out $(JVM_VARIANT_OUTPUTDIR)/gensrc/%, $(JVM_SRC_DIRS))) \
+ -I$(JVM_VARIANT_OUTPUTDIR)/gensrc \
+ -I$(HOTSPOT_TOPDIR)/src/share/vm/precompiled \
+ -I$(HOTSPOT_TOPDIR)/src/share/vm/prims \
+ #
+
+JVM_CFLAGS_TARGET_DEFINES += \
+ -DTARGET_OS_FAMILY_$(HOTSPOT_TARGET_OS) \
+ -DTARGET_ARCH_MODEL_$(HOTSPOT_TARGET_CPU) \
+ -DTARGET_ARCH_$(HOTSPOT_TARGET_CPU_ARCH) \
+ -DTARGET_OS_ARCH_MODEL_$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU) \
+ -DTARGET_OS_ARCH_$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU_ARCH) \
+ -DTARGET_COMPILER_$(HOTSPOT_TOOLCHAIN_TYPE) \
+ -D$(HOTSPOT_TARGET_CPU_DEFINE) \
+ -DHOTSPOT_LIB_ARCH='"$(OPENJDK_TARGET_CPU_LEGACY_LIB)"' \
+ #
+
+ifeq ($(DEBUG_LEVEL), release)
+ # For hotspot, release builds differ internally between "optimized" and "product"
+ # in that "optimize" does not define PRODUCT.
+ ifneq ($(HOTSPOT_DEBUG_LEVEL), optimized)
+ JVM_CFLAGS_DEBUGLEVEL := -DPRODUCT
+ endif
+else ifeq ($(DEBUG_LEVEL), fastdebug)
+ JVM_CFLAGS_DEBUGLEVEL := -DASSERT
+ ifeq ($(filter $(OPENJDK_TARGET_OS), windows aix), )
+ # NOTE: Old build did not define CHECK_UNHANDLED_OOPS on Windows and AIX.
+ JVM_CFLAGS_DEBUGLEVEL += -DCHECK_UNHANDLED_OOPS
+ endif
+else ifeq ($(DEBUG_LEVEL), slowdebug)
+ # _NMT_NOINLINE_ informs NMT that no inlining is done by the compiler
+ JVM_CFLAGS_DEBUGLEVEL := -DASSERT -D_NMT_NOINLINE_
+endif
+
+JVM_CFLAGS += \
+ $(JVM_CFLAGS_DEBUGLEVEL) \
+ $(JVM_CFLAGS_TARGET_DEFINES) \
+ $(JVM_CFLAGS_FEATURES) \
+ $(JVM_CFLAGS_INCLUDES) \
+ $(EXTRA_CFLAGS) \
+ #
+
+JVM_LDFLAGS += \
+ $(SHARED_LIBRARY_FLAGS) \
+ $(JVM_LDFLAGS_FEATURES) \
+ $(EXTRA_LDFLAGS) \
+ #
+
+JVM_LIBS += \
+ $(JVM_LIBS_FEATURES) \
+ #
+
+# These files and directories are always excluded
+JVM_EXCLUDE_FILES += jsig.c jvmtiEnvRecommended.cpp jvmtiEnvStub.cpp args.cc
+JVM_EXCLUDES += adlc
+
+# Needed by vm_version.cpp
+ifeq ($(OPENJDK_TARGET_CPU), x86_64)
+ OPENJDK_TARGET_CPU_VM_VERSION := amd64
+else ifeq ($(OPENJDK_TARGET_CPU), sparcv9)
+ OPENJDK_TARGET_CPU_VM_VERSION := sparc
+else
+ OPENJDK_TARGET_CPU_VM_VERSION := $(OPENJDK_TARGET_CPU)
+endif
+
+CFLAGS_VM_VERSION := \
+ $(VERSION_CFLAGS) \
+ -DHOTSPOT_VERSION_STRING='"$(VERSION_STRING)"' \
+ -DDEBUG_LEVEL='"$(DEBUG_LEVEL)"' \
+ -DHOTSPOT_BUILD_USER='"$(USERNAME)"' \
+ -DHOTSPOT_VM_DISTRO='"$(HOTSPOT_VM_DISTRO)"' \
+ -DCPU='"$(OPENJDK_TARGET_CPU_VM_VERSION)"' \
+ #
+
+# -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
+ifeq ($(USE_PRECOMPILED_HEADER), 0)
+ JVM_CFLAGS += -DDONT_USE_PRECOMPILED_HEADER
+endif
+
+################################################################################
+# Platform specific setup
+
+ifneq ($(filter $(OPENJDK_TARGET_OS), linux macosx windows), )
+ JVM_PRECOMPILED_HEADER := $(HOTSPOT_TOPDIR)/src/share/vm/precompiled/precompiled.hpp
+endif
+
+ifneq ($(filter $(OPENJDK_TARGET_OS), macosx aix solaris), )
+ # On macosx, aix and solaris we have to link with the C++ compiler
+ JVM_TOOLCHAIN := TOOLCHAIN_LINK_CXX
+else
+ JVM_TOOLCHAIN := TOOLCHAIN_DEFAULT
+endif
+
+ifeq ($(OPENJDK_TARGET_CPU), x86)
+ JVM_EXCLUDE_PATTERNS += x86_64
+else ifeq ($(OPENJDK_TARGET_CPU), x86_64)
+ JVM_EXCLUDE_PATTERNS += x86_32
+endif
+
+# Inline assembly for solaris
+ifeq ($(OPENJDK_TARGET_OS), solaris)
+ ifeq ($(OPENJDK_TARGET_CPU), x86_64)
+ JVM_CFLAGS += $(HOTSPOT_TOPDIR)/src/os_cpu/solaris_x86/vm/solaris_x86_64.il
+ else ifeq ($(OPENJDK_TARGET_CPU), sparcv9)
+ JVM_CFLAGS += $(HOTSPOT_TOPDIR)/src/os_cpu/solaris_sparc/vm/solaris_sparc.il
+ endif
+endif
+
+ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU), solaris-sparcv9)
+ ifeq ($(COMPILE_WITH_DEBUG_SYMBOLS), false)
+ # NOTE: In the old build, we weirdly enough set -g/-g0 always, regardless
+ # of if debug symbols were needed. Without it, compilation fails on
+ # sparc! :-(
+ JVM_CFLAGS += -g0
+ endif
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), windows)
+ ifeq ($(OPENJDK_TARGET_CPU_BITS), 64)
+ RC_DESC := 64-Bit$(SPACE)
+ endif
+ JVM_RCFLAGS += -D"HS_FILEDESC=$(HOTSPOT_VM_DISTRO) $(RC_DESC)$(JVM_VARIANT) VM"
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), macosx)
+ # NOTE: The old build did not strip binaries on macosx.
+ JVM_STRIP_SYMBOLS := false
+else
+ JVM_STRIP_SYMBOLS := true
+endif
+
+JVM_OPTIMIZATION ?= HIGHEST_JVM
+
+################################################################################
+# Now set up the actual compilation of the main hotspot native library
+
+$(eval $(call SetupNativeCompilation, BUILD_LIBJVM, \
+ TOOLCHAIN := $(JVM_TOOLCHAIN), \
+ LIBRARY := jvm, \
+ OUTPUT_DIR := $(JVM_OUTPUTDIR), \
+ SRC := $(JVM_SRC_DIRS), \
+ EXCLUDES := $(JVM_EXCLUDES), \
+ EXCLUDE_FILES := $(JVM_EXCLUDE_FILES), \
+ EXCLUDE_PATTERNS := $(JVM_EXCLUDE_PATTERNS), \
+ EXTRA_OBJECT_FILES := $(DTRACE_EXTRA_OBJECT_FILES), \
+ CFLAGS := $(JVM_CFLAGS), \
+ CFLAGS_DEBUG_SYMBOLS := $(JVM_CFLAGS_SYMBOLS), \
+ CXXFLAGS_DEBUG_SYMBOLS := $(JVM_CFLAGS_SYMBOLS), \
+ vm_version.cpp_CXXFLAGS := $(CFLAGS_VM_VERSION), \
+ DISABLED_WARNINGS_clang := delete-non-virtual-dtor dynamic-class-memaccess \
+ empty-body format logical-op-parentheses parentheses \
+ parentheses-equality switch tautological-compare, \
+ DISABLED_WARNINGS_xlc := 1540-0216 1540-0198 1540-1090 1540-1639 \
+ 1540-1088 1500-010, \
+ ASFLAGS := $(JVM_ASFLAGS), \
+ LDFLAGS := $(JVM_LDFLAGS), \
+ LIBS := $(JVM_LIBS), \
+ OPTIMIZATION := $(JVM_OPTIMIZATION), \
+ OBJECT_DIR := $(JVM_OUTPUTDIR)/objs, \
+ MAPFILE := $(JVM_MAPFILE), \
+ USE_MAPFILE_FOR_SYMBOLS := true, \
+ STRIP_SYMBOLS := $(JVM_STRIP_SYMBOLS), \
+ EMBED_MANIFEST := true, \
+ RC_FLAGS := $(JVM_RCFLAGS), \
+ VERSIONINFO_RESOURCE := $(HOTSPOT_TOPDIR)/src/os/windows/vm/version.rc, \
+ PRECOMPILED_HEADER := $(JVM_PRECOMPILED_HEADER), \
+ PRECOMPILED_HEADER_EXCLUDE := $(JVM_PRECOMPILED_HEADER_EXCLUDE), \
+))
+
+# AIX warning explanation:
+# 1500-010 : (W) WARNING in ...: Infinite loop. Program may not stop.
+# There are several infinite loops in the vm, so better suppress.
+# 1540-0198 : (W) The omitted keyword "private" is assumed for base class "...".
+# 1540-0216 : (W) An expression of type .. cannot be converted to type ..
+# In hotspot this fires for functionpointer to pointer conversions
+# 1540-1088 : (W) The exception specification is being ignored.
+# In hotspot this is caused by throw() in declaration of new() in nmethod.hpp.
+# 1540-1090 : (I) The destructor of "..." might not be called.
+# 1540-1639 : (I) The behavior of long type bit fields has changed ...
+
+# Include mapfile generation. It relies on BUILD_LIBJVM_ALL_OBJS which is only
+# defined after the above call to BUILD_LIBJVM. Mapfile will be generated
+# after all object files are built, but before the jvm library is linked.
+include lib/JvmMapfile.gmk
+
+TARGETS += $(BUILD_LIBJVM)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/lib/CompileLibjsig.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,106 @@
+#
+# 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. 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.
+#
+
+################################################################################
+# Create the libjsig.so shared library
+
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+include NativeCompilation.gmk
+
+ifneq ($(OPENJDK_TARGET_OS), windows)
+ ifeq ($(STATIC_BUILD), false)
+ LIBJSIG_STRIP_SYMBOLS := true
+ ifeq ($(OPENJDK_TARGET_OS), linux)
+ LIBJSIG_CFLAGS := -fPIC -D_GNU_SOURCE -D_REENTRANT $(EXTRA_CFLAGS)
+ LIBJSIG_LDFLAGS := $(LDFLAGS_HASH_STYLE) $(EXTRA_CFLAGS)
+ LIBJSIG_LIBS := $(LIBDL)
+
+ # NOTE: The old build compiled this library without -soname.
+ # To emulate this, we need to clear out SET_SHARED_LIBRARY_NAME.
+ SET_SHARED_LIBRARY_NAME :=
+
+ # Flags for other CPUs can be provided in EXTRA_CFLAGS
+ ifeq ($(OPENJDK_TARGET_CPU), x86_64)
+ LIBJSIG_CPU_FLAGS := -m64
+ else ifeq ($(OPENJDK_TARGET_CPU), x86)
+ LIBJSIG_CPU_FLAGS := -m32 -march=i586
+ endif
+
+ else ifeq ($(OPENJDK_TARGET_OS), solaris)
+ LIBJSIG_CFLAGS := -m64 -KPIC -mt
+ LIBJSIG_LDFLAGS := -m64 -mt -xnolib
+ LIBJSIG_LIBS := $(LIBDL)
+
+ # NOTE: The old build compiled this library without -soname.
+ # To emulate this, we need to clear out SET_SHARED_LIBRARY_NAME.
+ SET_SHARED_LIBRARY_NAME :=
+
+ else ifeq ($(OPENJDK_TARGET_OS), aix)
+ LIBJSIG_CFLAGS := -q64 -D_GNU_SOURCE -D_REENTRANT -qpic=large
+ LIBJSIG_LDFLAGS := -b64 -bexpall -G -bnoentry -qmkshrobj -brtl -bnolibpath -bernotok
+ LIBJSIG_LIBS := $(LIBDL)
+
+ # NOTE: The old build compiled this library without -soname.
+ # To emulate this, we need to clear out SET_SHARED_LIBRARY_NAME.
+ SET_SHARED_LIBRARY_NAME :=
+
+ else ifeq ($(OPENJDK_TARGET_OS), macosx)
+ LIBJSIG_CFLAGS := -m64 -D_GNU_SOURCE -pthread -mno-omit-leaf-frame-pointer -mstack-alignment=16 -fPIC
+ LIBJSIG_LDFLAGS := $(LDFLAGS_HASH_STYLE)
+ # NOTE: This lib is not stripped on macosx in old build. Looks like a mistake.
+ LIBJSIG_STRIP_SYMBOLS := false
+ else
+ $(error Unknown target OS $(OPENJDK_TARGET_OS) in CompileLibjsig.gmk)
+ endif
+
+ LIBJSIG_SRC_FILE := $(HOTSPOT_TOPDIR)/src/os/$(HOTSPOT_TARGET_OS)/vm/jsig.c
+ LIBJSIG_MAPFILE := $(wildcard $(HOTSPOT_TOPDIR)/makefiles/mapfiles/libjsig/mapfile-vers-$(OPENJDK_TARGET_OS))
+ LIBJSIG_OUTPUTDIR := $(HOTSPOT_OUTPUTDIR)/libjsig
+
+ LIBJSIG_LDFLAGS += $(SHARED_LIBRARY_FLAGS)
+
+ $(eval $(call SetupNativeCompilation, BUILD_LIBJSIG, \
+ LIBRARY := jsig, \
+ EXTRA_FILES := $(LIBJSIG_SRC_FILE), \
+ OUTPUT_DIR := $(LIBJSIG_OUTPUTDIR), \
+ LANG := C, \
+ CFLAGS := $(LIBJSIG_CFLAGS) $(LIBJSIG_CPU_FLAGS), \
+ LDFLAGS := $(LIBJSIG_LDFLAGS) $(LIBJSIG_CPU_FLAGS), \
+ LIBS := $(LIBJSIG_LIBS), \
+ MAPFILE := $(LIBJSIG_MAPFILE), \
+ OBJECT_DIR := $(LIBJSIG_OUTPUTDIR)/objs, \
+ STRIP_SYMBOLS := $(LIBJSIG_STRIP_SYMBOLS), \
+ ))
+
+ TARGETS += $(BUILD_LIBJSIG)
+ endif
+endif
+
+all: $(TARGETS)
+
+.PHONY: all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/lib/CompileLibraries.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,42 @@
+#
+# 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. 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.
+#
+
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+include NativeCompilation.gmk
+
+include HotspotCommon.gmk
+
+# The dtrace setup must be done both before and after CompileJvm.gmk, due to
+# intricate dependencies.
+include lib/CompileDtracePreJvm.gmk
+include lib/CompileJvm.gmk
+include lib/CompileDtracePostJvm.gmk
+
+all: $(TARGETS)
+
+.PHONY: all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/lib/JvmFeatures.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,144 @@
+#
+# 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. 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.
+#
+
+$(eval $(call IncludeCustomExtension, hotspot, lib/JvmFeatures.gmk))
+
+################################################################################
+# Setup CFLAGS and EXCLUDES for the libjvm compilation, depending on which
+# jvm features are selected for this jvm variant.
+
+ifeq ($(call check-jvm-feature, compiler1), true)
+ JVM_CFLAGS_FEATURES += -DCOMPILER1
+else
+ JVM_EXCLUDE_PATTERNS += c1_
+endif
+
+ifeq ($(call check-jvm-feature, compiler2), true)
+ JVM_CFLAGS_FEATURES += -DCOMPILER2
+ JVM_SRC_DIRS += $(JVM_VARIANT_OUTPUTDIR)/gensrc/adfiles
+else
+ JVM_EXCLUDES += opto libadt
+ JVM_EXCLUDE_FILES += bcEscapeAnalyzer.cpp ciTypeFlow.cpp
+ JVM_EXCLUDE_PATTERNS += c2_ runtime_
+endif
+
+ifeq ($(call check-jvm-feature, zero), true)
+ JVM_CFLAGS_FEATURES += -DZERO -DCC_INTERP -DZERO_LIBARCH='"$(OPENJDK_TARGET_CPU_LEGACY_LIB)"' $(LIBFFI_CFLAGS)
+ JVM_LIBS_FEATURES += $(LIBFFI_LIBS)
+endif
+
+ifeq ($(call check-jvm-feature, shark), true)
+ JVM_CFLAGS_FEATURES += -DSHARK $(LLVM_CFLAGS)
+ JVM_LDFLAGS_FEATURES += $(LLVM_LDFLAGS)
+ JVM_LIBS_FEATURES += $(LLVM_LIBS)
+else
+ JVM_EXCLUDES += shark
+endif
+
+ifeq ($(call check-jvm-feature, minimal), true)
+ JVM_CFLAGS_FEATURES += -DMINIMAL_JVM -DVMTYPE=\"Minimal\"
+endif
+
+ifeq ($(call check-jvm-feature, dtrace), true)
+ JVM_CFLAGS_FEATURES += -DDTRACE_ENABLED
+endif
+
+ifeq ($(call check-jvm-feature, static-build), true)
+ JVM_CFLAGS_FEATURES += -DSTATIC_BUILD=1
+endif
+
+ifneq ($(call check-jvm-feature, jvmti), true)
+ JVM_CFLAGS_FEATURES += -DINCLUDE_JVMTI=0
+ JVM_EXCLUDE_FILES += jvmtiGetLoadedClasses.cpp jvmtiThreadState.cpp jvmtiExtensions.cpp \
+ jvmtiImpl.cpp jvmtiManageCapabilities.cpp jvmtiRawMonitor.cpp jvmtiUtil.cpp jvmtiTrace.cpp \
+ jvmtiCodeBlobEvents.cpp jvmtiEnv.cpp jvmtiRedefineClasses.cpp jvmtiEnvBase.cpp jvmtiEnvThreadState.cpp \
+ jvmtiTagMap.cpp jvmtiEventController.cpp evmCompat.cpp jvmtiEnter.xsl jvmtiExport.cpp \
+ jvmtiClassFileReconstituter.cpp
+endif
+
+ifneq ($(call check-jvm-feature, jvmci), true)
+ JVM_CFLAGS_FEATURES += -DINCLUDE_JVMCI=0
+ JVM_EXCLUDES += jvmci
+ JVM_EXCLUDE_FILES += jvmciCodeInstaller_$(HOTSPOT_TARGET_CPU_ARCH).cpp
+endif
+
+ifneq ($(call check-jvm-feature, fprof), true)
+ JVM_CFLAGS_FEATURES += -DINCLUDE_FPROF=0
+ JVM_EXCLUDE_FILES += fprofiler.cpp
+endif
+
+ifneq ($(call check-jvm-feature, vm-structs), true)
+ JVM_CFLAGS_FEATURES += -DINCLUDE_VM_STRUCTS=0
+ JVM_EXCLUDE_FILES += vmStructs.cpp
+endif
+
+ifneq ($(call check-jvm-feature, jni-check), true)
+ JVM_CFLAGS_FEATURES += -DINCLUDE_JNI_CHECK=0
+ JVM_EXCLUDE_FILES += jniCheck.cpp
+endif
+
+ifneq ($(call check-jvm-feature, services), true)
+ JVM_CFLAGS_FEATURES += -DINCLUDE_SERVICES=0
+ JVM_EXCLUDE_FILES += heapDumper.cpp heapInspection.cpp \
+ attachListener_$(HOTSPOT_TARGET_OS).cpp attachListener.cpp
+endif
+
+ifneq ($(call check-jvm-feature, management), true)
+ JVM_CFLAGS_FEATURES += -DINCLUDE_MANAGEMENT=0
+endif
+
+ifneq ($(call check-jvm-feature, cds), true)
+ JVM_CFLAGS_FEATURES += -DINCLUDE_CDS=0
+ JVM_EXCLUDE_FILES += \
+ classListParser.cpp \
+ classLoaderExt.cpp \
+ filemap.cpp \
+ metaspaceShared.cpp \
+ metaspaceShared_$(HOTSPOT_TARGET_CPU).cpp \
+ metaspaceShared_$(HOTSPOT_TARGET_CPU_ARCH).cpp \
+ sharedClassUtil.cpp \
+ sharedPathsMiscInfo.cpp \
+ systemDictionaryShared.cpp \
+ #
+endif
+
+ifneq ($(call check-jvm-feature, all-gcs), true)
+ JVM_CFLAGS_FEATURES += -DINCLUDE_ALL_GCS=0
+ JVM_EXCLUDE_PATTERNS += \
+ cms/ g1/ parallel/
+ JVM_EXCLUDE_FILES += \
+ concurrentGCThread.cpp \
+ plab.cpp
+ JVM_EXCLUDE_FILES += \
+ g1MemoryPool.cpp \
+ psMemoryPool.cpp
+endif
+
+ifneq ($(call check-jvm-feature, nmt), true)
+ JVM_CFLAGS_FEATURES += -DINCLUDE_NMT=0
+ JVM_EXCLUDE_FILES += \
+ memBaseline.cpp memReporter.cpp mallocTracker.cpp virtualMemoryTracker.cpp nmtCommon.cpp \
+ memTracker.cpp nmtDCmd.cpp mallocSiteTable.cpp
+endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/lib/JvmMapfile.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,172 @@
+#
+# 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. 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.
+#
+
+$(eval $(call IncludeCustomExtension, hotspot, lib/JvmMapfile.gmk))
+
+################################################################################
+# Combine a list of static symbols
+
+ifneq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU), windows-x86_64)
+ # On Windows x86_64, we should not have any symbols at all, since that
+ # results in duplicate warnings from the linker (JDK-8043491).
+ SYMBOLS_SRC += $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-shared
+endif
+
+ifeq ($(OPENJDK_TARGET_OS_TYPE), unix)
+ SYMBOLS_SRC += $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-unix
+endif
+
+ifneq ($(wildcard $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-$(OPENJDK_TARGET_OS)), )
+ SYMBOLS_SRC += $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-$(OPENJDK_TARGET_OS)
+endif
+
+ifneq ($(findstring debug, $(DEBUG_LEVEL)), )
+ ifneq ($(wildcard $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-$(OPENJDK_TARGET_OS)-debug), )
+ SYMBOLS_SRC += $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-$(OPENJDK_TARGET_OS)-debug
+ endif
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), solaris)
+ ifeq ($(call check-jvm-feature, dtrace), true)
+ # Additional mapfiles that are only used when dtrace is enabled
+ ifeq ($(call check-jvm-feature, compiler2), true)
+ # This also covers the case of compiler1+compiler2.
+ SYMBOLS_SRC += $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-solaris-dtrace-compiler2
+ else ifeq ($(call check-jvm-feature, compiler1), true)
+ SYMBOLS_SRC += $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-solaris-dtrace-compiler1
+ endif
+ endif
+endif
+
+################################################################################
+# Create a dynamic list of symbols from the built object files. This is highly
+# platform dependent.
+
+ifeq ($(OPENJDK_TARGET_OS), linux)
+ DUMP_SYMBOLS_CMD := $(NM) --defined-only *.o
+ ifneq ($(FILTER_SYMBOLS_PATTERN), )
+ FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)|
+ endif
+ FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)^_ZTV|^gHotSpotVM|^UseSharedSpaces$$
+ FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)|^_ZN9Arguments17SharedArchivePathE$$
+ FILTER_SYMBOLS_AWK_SCRIPT := \
+ '{ \
+ if ($$3 ~ /$(FILTER_SYMBOLS_PATTERN)/) print $$3; \
+ }'
+
+else ifeq ($(OPENJDK_TARGET_OS), solaris)
+ DUMP_SYMBOLS_CMD := $(NM) -p *.o
+ ifneq ($(FILTER_SYMBOLS_PATTERN), )
+ FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)|
+ endif
+ FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)^__1c.*__vtbl_$$|^gHotSpotVM
+ FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)|^UseSharedSpaces$$
+ FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)|^__1cJArgumentsRSharedArchivePath_$$
+ FILTER_SYMBOLS_AWK_SCRIPT := \
+ '{ \
+ if ($$2 == "U") next; \
+ if ($$3 ~ /$(FILTER_SYMBOLS_PATTERN)/) print $$3; \
+ }'
+
+else ifeq ($(OPENJDK_TARGET_OS), macosx)
+ # nm on macosx prints out "warning: nm: no name list" to stderr for
+ # files without symbols. Hide this, even at the expense of hiding real errors.
+ DUMP_SYMBOLS_CMD := $(NM) -Uj *.o 2> /dev/null
+ ifneq ($(FILTER_SYMBOLS_PATTERN), )
+ FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)|
+ endif
+ FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)^_ZTV|^gHotSpotVM
+ FILTER_SYMBOLS_AWK_SCRIPT := \
+ '{ \
+ if ($$3 ~ /$(FILTER_SYMBOLS_PATTERN)/) print $$3; \
+ }'
+
+# NOTE: The script is from the old build. It is broken and finds no symbols.
+# The script below might be what was intended, but it failes to link with tons
+# of 'cannot export hidden symbol vtable for X'.
+# '{ if ($$1 ~ /^__ZTV/ || $$1 ~ /^_gHotSpotVM/) print substr($$1, 2) }'
+else ifeq ($(OPENJDK_TARGET_OS), aix)
+ # NOTE: The old build had the solution below. This should to be fixed in
+ # configure instead.
+
+ # On AIX we have to prevent that we pick up the 'nm' version from the GNU binutils
+ # which may be installed under /opt/freeware/bin. So better use an absolute path here!
+ # NM=/usr/bin/nm
+
+ DUMP_SYMBOLS_CMD := $(NM) -X64 -B -C *.o
+ FILTER_SYMBOLS_AWK_SCRIPT := \
+ '{ \
+ if (($$2="d" || $$2="D") && ($$3 ~ /^__vft/ || $$3 ~ /^gHotSpotVM/)) print $$3; \
+ if ($$3 ~ /^UseSharedSpaces$$/) print $$3; \
+ if ($$3 ~ /^SharedArchivePath__9Arguments$$/) print $$3; \
+ }'
+
+else ifeq ($(OPENJDK_TARGET_OS), windows)
+ DUMP_SYMBOLS_CMD := $(DUMPBIN) -symbols *.obj
+ FILTER_SYMBOLS_AWK_SCRIPT := \
+ '{ \
+ if ($$7 ~ /??_7.*@@6B@/ && $$7 !~ /type_info/) print $$7; \
+ }'
+
+else
+ $(error Unknown target OS $(OPENJDK_TARGET_OS) in JvmMapfile.gmk)
+endif
+
+# A more correct solution would be to send BUILD_LIBJVM_ALL_OBJS instead of
+# cd && *.o, but this will result in very long command lines, which is
+# problematic on some platforms.
+$(JVM_OUTPUTDIR)/symbols-objects: $(BUILD_LIBJVM_ALL_OBJS)
+ $(call LogInfo, Generating symbol list from object files)
+ $(CD) $(JVM_OUTPUTDIR)/objs && \
+ $(DUMP_SYMBOLS_CMD) | $(NAWK) $(FILTER_SYMBOLS_AWK_SCRIPT) | $(SORT) -u > $@
+
+SYMBOLS_SRC += $(JVM_OUTPUTDIR)/symbols-objects
+
+################################################################################
+# Now concatenate all symbol lists into a single file and remove comments.
+
+$(JVM_OUTPUTDIR)/symbols: $(SYMBOLS_SRC)
+ $(SED) -e '/^#/d' $^ > $@
+
+################################################################################
+# Finally convert the symbol list into a platform-specific mapfile
+
+$(JVM_MAPFILE): $(JVM_OUTPUTDIR)/symbols
+ $(call LogInfo, Creating mapfile)
+ $(RM) $@
+ ifeq ($(OPENJDK_TARGET_OS), macosx)
+ # On macosx, we need to add a leading underscore
+ $(AWK) '{ if ($$0 ~ ".") { print " _" $$0 } }' < $^ > $@.tmp
+ else ifeq ($(OPENJDK_TARGET_OS), windows)
+ # On windows, add an 'EXPORTS' header
+ $(ECHO) "EXPORTS" > $@.tmp
+ $(AWK) '{ if ($$0 ~ ".") { print " " $$0 } }' < $^ >> $@.tmp
+ else
+ # Assume standard linker script
+ $(PRINTF) "SUNWprivate_1.1 { \n global: \n" > $@.tmp
+ $(AWK) '{ if ($$0 ~ ".") { print " " $$0 ";" } }' < $^ >> $@.tmp
+ $(PRINTF) " local: \n *; \n }; \n" >> $@.tmp
+ endif
+ $(MV) $@.tmp $@
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/lib/JvmOverrideFiles.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,168 @@
+#
+# 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. 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.
+#
+
+$(eval $(call IncludeCustomExtension, hotspot, lib/JvmOverrideFiles.gmk))
+
+################################################################################
+# This file contains explicit overrides of CFLAGS and/or precompiled header
+# status for individual files on specific platforms.
+
+ifeq ($(TOOLCHAIN_TYPE), gcc)
+ BUILD_LIBJVM_vmStructs.cpp_CXXFLAGS := -fno-var-tracking-assignments -O0
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), linux)
+ BUILD_LIBJVM_ostream.cpp_CXXFLAGS := -D_FILE_OFFSET_BITS=64
+
+ ifeq ($(OPENJDK_TARGET_CPU_ARCH), x86)
+ BUILD_LIBJVM_sharedRuntimeTrig.cpp_CXXFLAGS := -DNO_PCH $(CXX_O_FLAG_NONE)
+ BUILD_LIBJVM_sharedRuntimeTrans.cpp_CXXFLAGS := -DNO_PCH $(CXX_O_FLAG_NONE)
+
+ ifeq ($(TOOLCHAIN_TYPE), clang)
+ JVM_PRECOMPILED_HEADER_EXCLUDE := \
+ sharedRuntimeTrig.cpp \
+ sharedRuntimeTrans.cpp \
+ #
+ endif
+ endif
+
+ ifeq ($(OPENJDK_TARGET_CPU), x86)
+ # Performance measurements show that by compiling GC related code, we could
+ # significantly reduce the GC pause time on 32 bit Linux/Unix platforms by
+ # compiling without the PIC flag (-fPIC on linux).
+ # See 6454213 for more details.
+ ALL_SRC := $(filter %.cpp, $(call CacheFind, $(HOTSPOT_TOPDIR)/src/share/vm))
+ NONPIC_FILTER := $(addsuffix %, $(addprefix $(HOTSPOT_TOPDIR)/src/share/vm/, \
+ memory oops gc))
+ # Due to what looks like a bug in the old build implementation of this, add a
+ # couple of more files that were accidentally matched as substrings of GC related
+ # files.
+ NONPIC_SRC := $(filter $(NONPIC_FILTER), $(ALL_SRC)) globals.cpp location.cpp
+ # Declare variables for each source file that needs the pic flag like this:
+ # BUILD_JVM_<srcfile>_CXXFLAGS := -fno-PIC
+ # This will get implicitly picked up by SetupNativeCompilation below.
+ $(foreach s, $(NONPIC_SRC), $(eval BUILD_LIBJVM_$(notdir $s)_CXXFLAGS := -fno-PIC))
+ endif
+
+else ifeq ($(OPENJDK_TARGET_OS), solaris)
+ ifneq ($(DEBUG_LEVEL), slowdebug)
+ # Workaround for a bug in dtrace. If ciEnv::post_compiled_method_load_event()
+ # is inlined, the resulting dtrace object file needs a reference to this
+ # function, whose symbol name is too long for dtrace. So disable inlining
+ # for this method for now. (fix this when dtrace bug 6258412 is fixed)
+ BUILD_LIBJVM_ciEnv.cpp_CXXFLAGS := \
+ -xinline=no%__1cFciEnvbFpost_compiled_method_load_event6MpnHnmethod__v_
+ # dtrace cannot handle tail call optimization (6672627, 6693876)
+ BUILD_LIBJVM_jni.cpp_CXXFLAGS := -Qoption ube -O~yz
+ BUILD_LIBJVM_stubGenerator_$(HOTSPOT_TARGET_CPU).cpp_CXXFLAGS := -xspace
+
+ ifeq ($(OPENJDK_TARGET_CPU), x86_64)
+ # Temporary until SS10 C++ compiler is fixed
+ BUILD_LIBJVM_generateOptoStub.cpp_CXXFLAGS := -xO2
+ # Temporary util SS12u1 C++ compiler is fixed
+ BUILD_LIBJVM_c1_LinearScan.cpp_CXXFLAGS := -xO2
+ endif
+ endif
+
+ # Need extra inlining to get oop_ps_push_contents functions to perform well enough.
+ ifeq ($(DEBUG_LEVEL),release)
+ BUILD_LIBJVM_psPromotionManager.cpp_CXXFLAGS := -W2,-Ainline:inc=1000
+ endif
+
+ ifeq ($(DEBUG_LEVEL), fastdebug)
+ # this hangs in iropt now (7113504)
+ BUILD_LIBJVM_compileBroker.cpp_CXXFLAGS := -xO2
+
+ # Frame size > 100k if we allow inlining via -g0!
+ BUILD_LIBJVM_bytecodeInterpreter.cpp_CXXFLAGS := +d
+ BUILD_LIBJVM_bytecodeInterpreterWithChecks.cpp_CXXFLAGS := +d
+
+ ifeq ($(OPENJDK_TARGET_CPU_ARCH), x86)
+ # ube explodes on x86
+ BUILD_LIBJVM_bytecodeInterpreter.cpp_CXXFLAGS += -xO1
+ BUILD_LIBJVM_bytecodeInterpreterWithChecks.cpp_CXXFLAGS += -xO1
+ endif
+
+ endif
+
+else ifeq ($(OPENJDK_TARGET_OS), macosx)
+ # The copied fdlibm routines in these files must not be optimized
+ BUILD_LIBJVM_sharedRuntimeTrans.cpp_CXXFLAGS := $(CXX_O_FLAG_NONE)
+ BUILD_LIBJVM_sharedRuntimeTrig.cpp_CXXFLAGS := $(CXX_O_FLAG_NONE)
+ ifeq ($(TOOLCHAIN_TYPE), clang)
+ # NOTE: The old build tested clang version to make sure this workaround
+ # for the clang bug was still needed.
+ BUILD_LIBJVM_loopTransform.cpp_CXXFLAGS := $(CXX_O_FLAG_NONE)
+ ifneq ($(DEBUG_LEVEL), slowdebug)
+ BUILD_LIBJVM_unsafe.cpp_CXXFLAGS := -O1
+ endif
+
+ # The following files are compiled at various optimization
+ # levels due to optimization issues encountered at the
+ # default level. The Clang compiler issues a compile
+ # time error if there is an optimization level specification
+ # skew between the PCH file and the C++ file. Especially if the
+ # PCH file is compiled at a higher optimization level than
+ # the C++ file. One solution might be to prepare extra optimization
+ # level specific PCH files for the opt build and use them here, but
+ # it's probably not worth the effort as long as only a few files
+ # need this special handling.
+ JVM_PRECOMPILED_HEADER_EXCLUDE := \
+ sharedRuntimeTrig.cpp \
+ sharedRuntimeTrans.cpp \
+ loopTransform.cpp \
+ unsafe.cpp \
+ jvmciCompilerToVM.cpp \
+ #
+ endif
+
+else ifeq ($(OPENJDK_TARGET_OS), aix)
+ BUILD_LIBJVM_synchronizer.cpp_CXXFLAGS := -qnoinline
+ BUILD_LIBJVM_sharedRuntimeTrans.cpp_CXXFLAGS := $(CXX_O_FLAG_NONE)
+ # Disable aggressive optimizations for functions in sharedRuntimeTrig.cpp
+ # and sharedRuntimeTrans.cpp on ppc64.
+ # -qstrict turns off the following optimizations:
+ # * Performing code motion and scheduling on computations such as loads
+ # and floating-point computations that may trigger an exception.
+ # * Relaxing conformance to IEEE rules.
+ # * Reassociating floating-point expressions.
+ # When using '-qstrict' there still remains one problem
+ # in javasoft.sqe.tests.api.java.lang.Math.sin5Tests when run in compile-all
+ # mode, so don't optimize sharedRuntimeTrig.cpp at all.
+ BUILD_LIBJVM_sharedRuntimeTrig.cpp_CXXFLAGS := $(CXX_O_FLAG_NONE)
+
+ # Disable ELF decoder on AIX (AIX uses XCOFF).
+ JVM_EXCLUDE_PATTERNS += elf
+
+else ifeq ($(OPENJDK_TARGET_OS), windows)
+ JVM_PRECOMPILED_HEADER_EXCLUDE := \
+ bytecodeInterpreter.cpp \
+ bytecodeInterpreterWithChecks.cpp \
+ opcodes.cpp \
+ os_windows.cpp \
+ os_windows_x86.cpp \
+ osThread_windows.cpp \
+ #
+endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/mapfiles/libjsig/mapfile-vers-solaris Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+#
+
+# Define library interface.
+
+SUNWprivate_1.1 {
+ global:
+ JVM_begin_signal_setting;
+ JVM_end_signal_setting;
+ JVM_get_libjsig_version;
+ JVM_get_signal_action;
+ sigaction;
+ signal;
+ sigset;
+ local:
+ *;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/mapfiles/libjvm_db/mapfile-vers Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,38 @@
+#
+
+#
+# Copyright (c) 2005, 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.
+#
+# 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.
+#
+#
+
+# Define library interface.
+
+SUNWprivate_1.1 {
+ global:
+ Jagent_create;
+ Jagent_destroy;
+ Jframe_iter;
+ #Jget_vframe;
+ #Jlookup_by_regs;
+ local:
+ *;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/mapfiles/libjvm_dtrace/mapfile-vers Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,37 @@
+#
+
+#
+# Copyright (c) 2006, 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.
+#
+# 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.
+#
+#
+
+# Define library interface for JVM-DTrace interface
+
+SUNWprivate_1.1 {
+ global:
+ jvm_attach;
+ jvm_get_last_error;
+ jvm_enable_dtprobes;
+ jvm_detach;
+ local:
+ *;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/symbols/symbols-aix Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+JVM_handle_linux_signal
+numa_error
+numa_warn
+sysThreadAvailableStackWithSlack
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/symbols/symbols-aix-debug Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,26 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+JVM_AccessVMBooleanFlag
+JVM_AccessVMIntFlag
+JVM_VMBreakPoint
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/symbols/symbols-linux Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+JVM_handle_linux_signal
+numa_error
+numa_warn
+sysThreadAvailableStackWithSlack
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/symbols/symbols-macosx Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+JVM_handle_bsd_signal
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/symbols/symbols-shared Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+AsyncGetCallTrace
+jio_fprintf
+jio_printf
+jio_snprintf
+jio_vfprintf
+jio_vsnprintf
+JNI_CreateJavaVM
+JNI_GetCreatedJavaVMs
+JNI_GetDefaultJavaVMInitArgs
+JVM_FindClassFromBootLoader
+JVM_GetVersionInfo
+JVM_InitAgentProperties
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/symbols/symbols-solaris Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+JVM_handle_solaris_signal
+sysThreadAvailableStackWithSlack
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/symbols/symbols-solaris-dtrace-compiler1 Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+__1cGMethodG__vtbl_
+__1cHnmethodG__vtbl_
+__1cICodeBlobG__vtbl_
+__1cIUniverseO_collectedHeap_
+__1cJCodeCacheG_heaps_
+__1cKBufferBlobG__vtbl_
+__1cLRuntimeStubG__vtbl_
+__1cNSafepointBlobG__vtbl_
+__1cSDeoptimizationBlobG__vtbl_
+
+__JvmOffsets
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/symbols/symbols-solaris-dtrace-compiler2 Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+__1cGMethodG__vtbl_
+__1cHnmethodG__vtbl_
+__1cICodeBlobG__vtbl_
+__1cIUniverseO_collectedHeap_
+__1cJCodeCacheG_heaps_
+__1cKBufferBlobG__vtbl_
+__1cLRuntimeStubG__vtbl_
+__1cNSafepointBlobG__vtbl_
+__1cSDeoptimizationBlobG__vtbl_
+__1cNExceptionBlobG__vtbl_
+__1cQUncommonTrapBlobG__vtbl_
+
+__JvmOffsets
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/symbols/symbols-unix Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,194 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+JVM_ActiveProcessorCount
+JVM_ArrayCopy
+JVM_AssertionStatusDirectives
+JVM_CallStackWalk
+JVM_ClassDepth
+JVM_ClassLoaderDepth
+JVM_Clone
+JVM_ConstantPoolGetClassAt
+JVM_ConstantPoolGetClassAtIfLoaded
+JVM_ConstantPoolGetClassRefIndexAt
+JVM_ConstantPoolGetDoubleAt
+JVM_ConstantPoolGetFieldAt
+JVM_ConstantPoolGetFieldAtIfLoaded
+JVM_ConstantPoolGetFloatAt
+JVM_ConstantPoolGetIntAt
+JVM_ConstantPoolGetLongAt
+JVM_ConstantPoolGetMemberRefInfoAt
+JVM_ConstantPoolGetMethodAt
+JVM_ConstantPoolGetMethodAtIfLoaded
+JVM_ConstantPoolGetNameAndTypeRefIndexAt
+JVM_ConstantPoolGetNameAndTypeRefInfoAt
+JVM_ConstantPoolGetSize
+JVM_ConstantPoolGetStringAt
+JVM_ConstantPoolGetTagAt
+JVM_ConstantPoolGetUTF8At
+JVM_CountStackFrames
+JVM_CurrentClassLoader
+JVM_CurrentLoadedClass
+JVM_CurrentThread
+JVM_CurrentTimeMillis
+JVM_DefineClass
+JVM_DefineClassWithSource
+JVM_DesiredAssertionStatus
+JVM_DoPrivileged
+JVM_DumpAllStacks
+JVM_DumpThreads
+JVM_FillInStackTrace
+JVM_FindClassFromCaller
+JVM_FindClassFromClass
+JVM_FindLibraryEntry
+JVM_FindLoadedClass
+JVM_FindPrimitiveClass
+JVM_FindSignal
+JVM_FreeMemory
+JVM_GC
+JVM_GetAllThreads
+JVM_GetArrayElement
+JVM_GetArrayLength
+JVM_GetCallerClass
+JVM_GetClassAccessFlags
+JVM_GetClassAnnotations
+JVM_GetClassConstantPool
+JVM_GetClassContext
+JVM_GetClassCPEntriesCount
+JVM_GetClassCPTypes
+JVM_GetClassDeclaredConstructors
+JVM_GetClassDeclaredFields
+JVM_GetClassDeclaredMethods
+JVM_GetClassFieldsCount
+JVM_GetClassInterfaces
+JVM_GetClassMethodsCount
+JVM_GetClassModifiers
+JVM_GetClassName
+JVM_GetClassNameUTF
+JVM_GetClassSignature
+JVM_GetClassSigners
+JVM_GetClassTypeAnnotations
+JVM_GetCPClassNameUTF
+JVM_GetCPFieldClassNameUTF
+JVM_GetCPFieldModifiers
+JVM_GetCPFieldNameUTF
+JVM_GetCPFieldSignatureUTF
+JVM_GetCPMethodClassNameUTF
+JVM_GetCPMethodModifiers
+JVM_GetCPMethodNameUTF
+JVM_GetCPMethodSignatureUTF
+JVM_GetDeclaredClasses
+JVM_GetDeclaringClass
+JVM_GetEnclosingMethodInfo
+JVM_GetFieldIxModifiers
+JVM_GetFieldTypeAnnotations
+JVM_GetInheritedAccessControlContext
+JVM_GetInterfaceVersion
+JVM_GetManagement
+JVM_GetMethodIxArgsSize
+JVM_GetMethodIxByteCode
+JVM_GetMethodIxByteCodeLength
+JVM_GetMethodIxExceptionIndexes
+JVM_GetMethodIxExceptionsCount
+JVM_GetMethodIxExceptionTableEntry
+JVM_GetMethodIxExceptionTableLength
+JVM_GetMethodIxLocalsCount
+JVM_GetMethodIxMaxStack
+JVM_GetMethodIxModifiers
+JVM_GetMethodIxNameUTF
+JVM_GetMethodIxSignatureUTF
+JVM_GetMethodParameters
+JVM_GetMethodTypeAnnotations
+JVM_GetNanoTimeAdjustment
+JVM_GetPrimitiveArrayElement
+JVM_GetProtectionDomain
+JVM_GetSimpleBinaryName
+JVM_GetStackAccessControlContext
+JVM_GetStackTraceElements
+JVM_GetSystemPackage
+JVM_GetSystemPackages
+JVM_GetTemporaryDirectory
+JVM_GetVmArguments
+JVM_Halt
+JVM_HoldsLock
+JVM_IHashCode
+JVM_InitProperties
+JVM_InternString
+JVM_Interrupt
+JVM_InvokeMethod
+JVM_IsArrayClass
+JVM_IsConstructorIx
+JVM_IsInterface
+JVM_IsInterrupted
+JVM_IsPrimitiveClass
+JVM_IsSameClassPackage
+JVM_IsSupportedJNIVersion
+JVM_IsThreadAlive
+JVM_IsVMGeneratedMethodIx
+JVM_LatestUserDefinedLoader
+JVM_LoadLibrary
+JVM_MaxMemory
+JVM_MaxObjectInspectionAge
+JVM_MonitorNotify
+JVM_MonitorNotifyAll
+JVM_MonitorWait
+JVM_MoreStackWalk
+JVM_NanoTime
+JVM_NativePath
+JVM_NewArray
+JVM_NewInstanceFromConstructor
+JVM_NewMultiArray
+JVM_RaiseSignal
+JVM_RawMonitorCreate
+JVM_RawMonitorDestroy
+JVM_RawMonitorEnter
+JVM_RawMonitorExit
+JVM_RegisterSignal
+JVM_ReleaseUTF
+JVM_ResumeThread
+JVM_SetArrayElement
+JVM_SetClassSigners
+JVM_SetNativeThreadName
+JVM_SetPrimitiveArrayElement
+JVM_SetThreadPriority
+JVM_Sleep
+JVM_StartThread
+JVM_StopThread
+JVM_SupportsCX8
+JVM_SuspendThread
+JVM_ToStackTraceElement
+JVM_TotalMemory
+JVM_UnloadLibrary
+JVM_Yield
+
+# Module related API's
+JVM_AddModuleExports
+JVM_AddModuleExportsToAll
+JVM_AddModuleExportsToAllUnnamed
+JVM_AddModulePackage
+JVM_AddReadsModule
+JVM_CanReadModule
+JVM_DefineModule
+JVM_IsExportedToModule
+JVM_SetBootLoaderUnnamedModule
+JVM_GetModuleByPackageName
--- a/hotspot/src/cpu/aarch64/vm/debug_aarch64.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/aarch64/vm/debug_aarch64.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -30,6 +30,5 @@
#include "runtime/init.hpp"
#include "runtime/os.hpp"
#include "utilities/debug.hpp"
-#include "utilities/top.hpp"
void pd_ps(frame f) {}
--- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -27,7 +27,6 @@
#define CPU_AARCH64_VM_FRAME_AARCH64_HPP
#include "runtime/synchronizer.hpp"
-#include "utilities/top.hpp"
// A frame represents a physical stack frame (an activation). Frames can be
// C or Java frames, and the Java frames can be interpreted or compiled.
--- a/hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -30,7 +30,6 @@
#include "memory/allocation.hpp"
#include "runtime/icache.hpp"
#include "runtime/os.hpp"
-#include "utilities/top.hpp"
// We have interfaces for the following instructions:
// - NativeInstruction
--- a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -198,6 +198,16 @@
bool SharedRuntime::is_wide_vector(int size) {
return size > 8;
}
+
+size_t SharedRuntime::trampoline_size() {
+ return 16;
+}
+
+void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) {
+ __ mov(rscratch1, destination);
+ __ br(rscratch1);
+}
+
// The java_calling_convention describes stack locations as ideal slots on
// a frame with no abi restrictions. Since we must observe abi restrictions
// (like the placement of the register window) the slots must be biased by
--- a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -39,7 +39,6 @@
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.inline.hpp"
-#include "utilities/top.hpp"
#ifdef COMPILER2
#include "opto/runtime.hpp"
#endif
--- a/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -360,7 +360,7 @@
length.set_instruction(x->length());
length.load_item();
}
- if (needs_store_check) {
+ if (needs_store_check || x->check_boolean()) {
value.load_item();
} else {
value.load_for_store(x->elt_type());
@@ -407,7 +407,8 @@
pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */,
true /* do_load */, false /* patch */, NULL);
}
- __ move(value.result(), array_addr, null_check_info);
+ LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info);
+ __ move(result, array_addr, null_check_info);
if (obj_store) {
// Precise card mark.
post_barrier(LIR_OprFact::address(array_addr), value.result());
--- a/hotspot/src/cpu/ppc/vm/debug_ppc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/debug_ppc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -30,6 +30,5 @@
#include "runtime/init.hpp"
#include "runtime/os.hpp"
#include "utilities/debug.hpp"
-#include "utilities/top.hpp"
void pd_ps(frame f) {}
--- a/hotspot/src/cpu/ppc/vm/frame_ppc.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/frame_ppc.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -27,7 +27,6 @@
#define CPU_PPC_VM_FRAME_PPC_HPP
#include "runtime/synchronizer.hpp"
-#include "utilities/top.hpp"
// C frame layout on PPC-64.
//
--- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -169,6 +169,7 @@
case ltos: ld(R17_tos, in_bytes(JvmtiThreadState::earlyret_value_offset()), RjvmtiState);
break;
case btos: // fall through
+ case ztos: // fall through
case ctos: // fall through
case stos: // fall through
case itos: lwz(R17_tos, in_bytes(JvmtiThreadState::earlyret_value_offset()), RjvmtiState);
@@ -294,6 +295,7 @@
switch (state) {
case atos: push_ptr(); break;
case btos:
+ case ztos:
case ctos:
case stos:
case itos: push_i(); break;
@@ -309,6 +311,7 @@
switch (state) {
case atos: pop_ptr(); break;
case btos:
+ case ztos:
case ctos:
case stos:
case itos: pop_i(); break;
@@ -749,6 +752,43 @@
stdux(Rscratch2, R1_SP, Rscratch1); // atomically set *(SP = top_frame_sp) = **SP
}
+void InterpreterMacroAssembler::narrow(Register result) {
+ Register ret_type = R11_scratch1;
+ ld(R11_scratch1, in_bytes(Method::const_offset()), R19_method);
+ lbz(ret_type, in_bytes(ConstMethod::result_type_offset()), R11_scratch1);
+
+ Label notBool, notByte, notChar, done;
+
+ // common case first
+ cmpwi(CCR0, ret_type, T_INT);
+ beq(CCR0, done);
+
+ cmpwi(CCR0, ret_type, T_BOOLEAN);
+ bne(CCR0, notBool);
+ andi(result, result, 0x1);
+ b(done);
+
+ bind(notBool);
+ cmpwi(CCR0, ret_type, T_BYTE);
+ bne(CCR0, notByte);
+ extsb(result, result);
+ b(done);
+
+ bind(notByte);
+ cmpwi(CCR0, ret_type, T_CHAR);
+ bne(CCR0, notChar);
+ andi(result, result, 0xffff);
+ b(done);
+
+ bind(notChar);
+ // cmpwi(CCR0, ret_type, T_SHORT); // all that's left
+ // bne(CCR0, done);
+ extsh(result, result);
+
+ // Nothing to do for T_INT
+ bind(done);
+}
+
// Remove activation.
//
// Unlock the receiver if this is a synchronized method.
--- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -140,6 +140,8 @@
void get_cpool_and_tags(Register Rcpool, Register Rtags);
void is_a(Label& L);
+ void narrow(Register result);
+
// Java Call Helpers
void call_from_interpreter(Register Rtarget_method, Register Rret_addr, Register Rscratch1, Register Rscratch2);
--- a/hotspot/src/cpu/ppc/vm/nativeInst_ppc.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/nativeInst_ppc.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -31,7 +31,6 @@
#include "memory/allocation.hpp"
#include "runtime/icache.hpp"
#include "runtime/os.hpp"
-#include "utilities/top.hpp"
// We have interfaces for the following instructions:
//
--- a/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -483,6 +483,18 @@
assert(size <= 8, "%d bytes vectors are not supported", size);
return size > 8;
}
+
+size_t SharedRuntime::trampoline_size() {
+ return Assembler::load_const_size + 8;
+}
+
+void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) {
+ Register Rtemp = R12;
+ __ load_const(Rtemp, destination);
+ __ mtctr(Rtemp);
+ __ bctr();
+}
+
#ifdef COMPILER2
static int reg2slot(VMReg r) {
return r->reg2stack() + SharedRuntime::out_preserve_stack_slots();
--- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -37,7 +37,6 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
-#include "utilities/top.hpp"
#include "runtime/thread.inline.hpp"
#define __ _masm->
--- a/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -655,6 +655,7 @@
switch (state) {
case ltos:
case btos:
+ case ztos:
case ctos:
case stos:
case atos:
@@ -701,6 +702,7 @@
switch (state) {
case ltos:
case btos:
+ case ztos:
case ctos:
case stos:
case atos:
@@ -2092,12 +2094,14 @@
// Copied from TemplateTable::_return.
// Restoration of lr done by remove_activation.
switch (state) {
+ // Narrow result if state is itos but result type is smaller.
+ case itos: __ narrow(R17_tos); /* fall through */
case ltos:
case btos:
+ case ztos:
case ctos:
case stos:
- case atos:
- case itos: __ mr(R3_RET, R17_tos); break;
+ case atos: __ mr(R3_RET, R17_tos); break;
case ftos:
case dtos: __ fmr(F1_RET, F15_ftos); break;
case vtos: // This might be a constructor. Final fields (and volatile fields on PPC64) need
@@ -2157,6 +2161,10 @@
bname = "trace_code_btos {";
tsize = 2;
break;
+ case ztos:
+ bname = "trace_code_ztos {";
+ tsize = 2;
+ break;
case ctos:
bname = "trace_code_ctos {";
tsize = 2;
--- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -170,6 +170,7 @@
switch (new_bc) {
case Bytecodes::_fast_aputfield:
case Bytecodes::_fast_bputfield:
+ case Bytecodes::_fast_zputfield:
case Bytecodes::_fast_cputfield:
case Bytecodes::_fast_dputfield:
case Bytecodes::_fast_fputfield:
@@ -981,9 +982,21 @@
Rarray = R12_scratch2,
Rscratch = R3_ARG1;
__ pop_i(Rindex);
+ __ pop_ptr(Rarray);
// tos: val
- // Rarray: array ptr (popped by index_check)
- __ index_check(Rarray, Rindex, 0, Rscratch, Rarray);
+
+ // Need to check whether array is boolean or byte
+ // since both types share the bastore bytecode.
+ __ load_klass(Rscratch, Rarray);
+ __ lwz(Rscratch, in_bytes(Klass::layout_helper_offset()), Rscratch);
+ int diffbit = exact_log2(Klass::layout_helper_boolean_diffbit());
+ __ testbitdi(CCR0, R0, Rscratch, diffbit);
+ Label L_skip;
+ __ bfalse(CCR0, L_skip);
+ __ andi(R17_tos, R17_tos, 1); // if it is a T_BOOLEAN array, mask the stored value to 0/1
+ __ bind(L_skip);
+
+ __ index_check_without_pop(Rarray, Rindex, 0, Rscratch, Rarray);
__ stb(R17_tos, arrayOopDesc::base_offset_in_bytes(T_BYTE), Rarray);
}
@@ -2108,12 +2121,16 @@
__ remove_activation(state, /* throw_monitor_exception */ true);
// Restoration of lr done by remove_activation.
switch (state) {
+ // Narrow result if state is itos but result type is smaller.
+ // Need to narrow in the return bytecode rather than in generate_return_entry
+ // since compiled code callers expect the result to already be narrowed.
+ case itos: __ narrow(R17_tos); /* fall through */
case ltos:
case btos:
+ case ztos:
case ctos:
case stos:
- case atos:
- case itos: __ mr(R3_RET, R17_tos); break;
+ case atos: __ mr(R3_RET, R17_tos); break;
case ftos:
case dtos: __ fmr(F1_RET, F15_ftos); break;
case vtos: // This might be a constructor. Final fields (and volatile fields on PPC64) need
@@ -2519,6 +2536,21 @@
__ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
__ align(32, 28, 28); // Align load.
+ // __ bind(Lztos); (same code as btos)
+ __ fence(); // Volatile entry point (one instruction before non-volatile_entry point).
+ assert(branch_table[ztos] == 0, "can't compute twice");
+ branch_table[ztos] = __ pc(); // non-volatile_entry point
+ __ lbzx(R17_tos, Rclass_or_obj, Roffset);
+ __ extsb(R17_tos, R17_tos);
+ __ push(ztos);
+ if (!is_static) {
+ // use btos rewriting, no truncating to t/f bit is needed for getfield.
+ patch_bytecode(Bytecodes::_fast_bgetfield, Rbc, Rscratch);
+ }
+ __ beq(CCR6, Lacquire); // Volatile?
+ __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+ __ align(32, 28, 28); // Align load.
// __ bind(Lctos);
__ fence(); // Volatile entry point (one instruction before non-volatile_entry point).
assert(branch_table[ctos] == 0, "can't compute twice");
@@ -2618,6 +2650,7 @@
case Bytecodes::_fast_aputfield: __ push_ptr(); offs+= Interpreter::stackElementSize; break;
case Bytecodes::_fast_iputfield: // Fall through
case Bytecodes::_fast_bputfield: // Fall through
+ case Bytecodes::_fast_zputfield: // Fall through
case Bytecodes::_fast_cputfield: // Fall through
case Bytecodes::_fast_sputfield: __ push_i(); offs+= Interpreter::stackElementSize; break;
case Bytecodes::_fast_lputfield: __ push_l(); offs+=2*Interpreter::stackElementSize; break;
@@ -2658,6 +2691,7 @@
case Bytecodes::_fast_aputfield: __ pop_ptr(); break;
case Bytecodes::_fast_iputfield: // Fall through
case Bytecodes::_fast_bputfield: // Fall through
+ case Bytecodes::_fast_zputfield: // Fall through
case Bytecodes::_fast_cputfield: // Fall through
case Bytecodes::_fast_sputfield: __ pop_i(); break;
case Bytecodes::_fast_lputfield: __ pop_l(); break;
@@ -2825,6 +2859,21 @@
__ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
__ align(32, 28, 28); // Align pop.
+ // __ bind(Lztos);
+ __ release(); // Volatile entry point (one instruction before non-volatile_entry point).
+ assert(branch_table[ztos] == 0, "can't compute twice");
+ branch_table[ztos] = __ pc(); // non-volatile_entry point
+ __ pop(ztos);
+ if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1.
+ __ andi(R17_tos, R17_tos, 0x1);
+ __ stbx(R17_tos, Rclass_or_obj, Roffset);
+ if (!is_static) { patch_bytecode(Bytecodes::_fast_zputfield, Rbc, Rscratch, true, byte_no); }
+ if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
+ __ beq(CR_is_vol, Lvolatile); // Volatile?
+ }
+ __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+ __ align(32, 28, 28); // Align pop.
// __ bind(Lctos);
__ release(); // Volatile entry point (one instruction before non-volatile_entry point).
assert(branch_table[ctos] == 0, "can't compute twice");
@@ -2949,6 +2998,9 @@
__ stdx(R17_tos, Rclass_or_obj, Roffset);
break;
+ case Bytecodes::_fast_zputfield:
+ __ andi(R17_tos, R17_tos, 0x1); // boolean is true if LSB is 1
+ // fall through to bputfield
case Bytecodes::_fast_bputfield:
__ stbx(R17_tos, Rclass_or_obj, Roffset);
break;
--- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -344,7 +344,7 @@
length.set_instruction(x->length());
length.load_item();
}
- if (needs_store_check) {
+ if (needs_store_check || x->check_boolean()) {
value.load_item();
} else {
value.load_for_store(x->elt_type());
@@ -389,7 +389,8 @@
pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */,
true /* do_load */, false /* patch */, NULL);
}
- __ move(value.result(), array_addr, null_check_info);
+ LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info);
+ __ move(result, array_addr, null_check_info);
if (obj_store) {
// Precise card mark
post_barrier(LIR_OprFact::address(array_addr), value.result());
--- a/hotspot/src/cpu/sparc/vm/debug_sparc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/debug_sparc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -29,7 +29,6 @@
#include "runtime/init.hpp"
#include "runtime/os.hpp"
#include "utilities/debug.hpp"
-#include "utilities/top.hpp"
#ifndef PRODUCT
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -26,7 +26,6 @@
#define CPU_SPARC_VM_FRAME_SPARC_HPP
#include "runtime/synchronizer.hpp"
-#include "utilities/top.hpp"
// A frame represents a physical stack frame (an activation). Frames can be
// C or Java frames, and the Java frames can be interpreted or compiled.
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -208,6 +208,7 @@
case atos: ld_ptr(oop_addr, Otos_l);
st_ptr(G0, oop_addr); break;
case btos: // fall through
+ case ztos: // fall through
case ctos: // fall through
case stos: // fall through
case itos: ld(val_addr, Otos_l1); break;
@@ -452,9 +453,10 @@
interp_verify_oop(Otos_i, state, __FILE__, __LINE__);
switch (state) {
case atos: push_ptr(); break;
- case btos: push_i(); break;
- case ctos:
- case stos: push_i(); break;
+ case btos: // fall through
+ case ztos: // fall through
+ case ctos: // fall through
+ case stos: // fall through
case itos: push_i(); break;
case ltos: push_l(); break;
case ftos: push_f(); break;
@@ -468,9 +470,10 @@
void InterpreterMacroAssembler::pop(TosState state) {
switch (state) {
case atos: pop_ptr(); break;
- case btos: pop_i(); break;
- case ctos:
- case stos: pop_i(); break;
+ case btos: // fall through
+ case ztos: // fall through
+ case ctos: // fall through
+ case stos: // fall through
case itos: pop_i(); break;
case ltos: pop_l(); break;
case ftos: pop_f(); break;
@@ -1103,6 +1106,49 @@
interp_verify_oop(Otos_i, state, __FILE__, __LINE__);
}
+void InterpreterMacroAssembler::narrow(Register result) {
+
+ ld_ptr(Address(Lmethod, Method::const_offset()), G3_scratch);
+ ldub(G3_scratch, in_bytes(ConstMethod::result_type_offset()), G3_scratch);
+
+ Label notBool, notByte, notChar, done;
+
+ // common case first
+ cmp(G3_scratch, T_INT);
+ br(Assembler::equal, true, pn, done);
+ delayed()->nop();
+
+ cmp(G3_scratch, T_BOOLEAN);
+ br(Assembler::notEqual, true, pn, notBool);
+ delayed()->cmp(G3_scratch, T_BYTE);
+ and3(result, 1, result);
+ ba(done);
+ delayed()->nop();
+
+ bind(notBool);
+ // cmp(G3_scratch, T_BYTE);
+ br(Assembler::notEqual, true, pn, notByte);
+ delayed()->cmp(G3_scratch, T_CHAR);
+ sll(result, 24, result);
+ sra(result, 24, result);
+ ba(done);
+ delayed()->nop();
+
+ bind(notByte);
+ // cmp(G3_scratch, T_CHAR);
+ sll(result, 16, result);
+ br(Assembler::notEqual, true, pn, done);
+ delayed()->sra(result, 16, result);
+ // sll(result, 16, result);
+ srl(result, 16, result);
+
+ // bind(notChar);
+ // must be short, instructions already executed in delay slot
+ // sll(result, 16, result);
+ // sra(result, 16, result);
+
+ bind(done);
+}
// remove activation
//
@@ -1151,6 +1197,7 @@
case ltos: mov(Otos_l2, Otos_l2->after_save()); // fall through // O1 -> I1
#endif
case btos: // fall through
+ case ztos: // fall through
case ctos:
case stos: // fall through
case atos: // fall through
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -103,6 +103,8 @@
void dispatch_via (TosState state, address* table);
+ void narrow(Register result);
+
// Removes the current activation (incl. unlocking of monitors).
// Additionally this code is used for earlyReturn in which case we
// want to skip throwing an exception and installing an exception.
--- a/hotspot/src/cpu/sparc/vm/metaspaceShared_sparc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/metaspaceShared_sparc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -65,8 +65,6 @@
*vtable = dummy_vtable;
*md_top += vtable_bytes;
- guarantee(*md_top <= md_end, "Insufficient space for vtables.");
-
// Get ready to generate dummy methods.
CodeBuffer cb((unsigned char*)*mc_top, mc_end - *mc_top);
--- a/hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -29,7 +29,6 @@
#include "memory/allocation.hpp"
#include "runtime/icache.hpp"
#include "runtime/os.hpp"
-#include "utilities/top.hpp"
// We have interface for the following instructions:
// - NativeInstruction
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -324,6 +324,16 @@
return size > 8;
}
+size_t SharedRuntime::trampoline_size() {
+ return 40;
+}
+
+void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) {
+ __ set((intptr_t)destination, G3_scratch);
+ __ JMP(G3_scratch, 0);
+ __ delayed()->nop();
+}
+
// The java_calling_convention describes stack locations as ideal slots on
// a frame with no abi restrictions. Since we must observe abi restrictions
// (like the placement of the register window) the slots must be biased by
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -37,7 +37,6 @@
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.inline.hpp"
-#include "utilities/top.hpp"
#ifdef COMPILER2
#include "opto/runtime.hpp"
#endif
--- a/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -616,7 +616,7 @@
// compute the beginning of the protected zone minus the requested frame size
__ sub( Rscratch, Rscratch2, Rscratch );
- __ set( JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_zone_size(), Rscratch2 );
+ __ set(MAX2(JavaThread::stack_shadow_zone_size(), JavaThread::stack_guard_zone_size()), Rscratch2 );
__ add( Rscratch, Rscratch2, Rscratch );
// Add in the size of the frame (which is the same as subtracting it from the
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -165,6 +165,7 @@
switch (bc) {
case Bytecodes::_fast_aputfield:
case Bytecodes::_fast_bputfield:
+ case Bytecodes::_fast_zputfield:
case Bytecodes::_fast_cputfield:
case Bytecodes::_fast_dputfield:
case Bytecodes::_fast_fputfield:
@@ -922,8 +923,20 @@
transition(itos, vtos);
__ pop_i(O2); // index
// Otos_i: val
+ // O2: index
// O3: array
__ index_check(O3, O2, 0, G3_scratch, O2);
+ // Need to check whether array is boolean or byte
+ // since both types share the bastore bytecode.
+ __ load_klass(O3, G4_scratch);
+ __ ld(G4_scratch, in_bytes(Klass::layout_helper_offset()), G4_scratch);
+ __ set(Klass::layout_helper_boolean_diffbit(), G3_scratch);
+ __ andcc(G3_scratch, G4_scratch, G0);
+ Label L_skip;
+ __ br(Assembler::zero, false, Assembler::pn, L_skip);
+ __ delayed()->nop();
+ __ and3(Otos_i, 1, Otos_i); // if it is a T_BOOLEAN array, mask the stored value to 0/1
+ __ bind(L_skip);
__ stb(Otos_i, O2, arrayOopDesc::base_offset_in_bytes(T_BYTE));
}
@@ -2008,6 +2021,12 @@
__ bind(skip_register_finalizer);
}
+ // Narrow result if state is itos but result type is smaller.
+ // Need to narrow in the return bytecode rather than in generate_return_entry
+ // since compiled code callers expect the result to already be narrowed.
+ if (state == itos) {
+ __ narrow(Otos_i);
+ }
__ remove_activation(state, /* throw_monitor_exception */ true);
// The caller's SP was adjusted upon method entry to accomodate
@@ -2218,7 +2237,7 @@
Label checkVolatile;
// compute field type
- Label notByte, notInt, notShort, notChar, notLong, notFloat, notObj;
+ Label notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj;
__ srl(Rflags, ConstantPoolCacheEntry::tos_state_shift, Rflags);
// Make sure we don't need to mask Rflags after the above shift
ConstantPoolCacheEntry::verify_tos_state_shift();
@@ -2273,7 +2292,7 @@
// cmp(Rflags, btos);
__ br(Assembler::notEqual, false, Assembler::pt, notByte);
- __ delayed() ->cmp(Rflags, ctos);
+ __ delayed() ->cmp(Rflags, ztos);
// btos
__ ldsb(Rclass, Roffset, Otos_i);
@@ -2286,6 +2305,22 @@
__ bind(notByte);
+ // cmp(Rflags, ztos);
+ __ br(Assembler::notEqual, false, Assembler::pt, notBool);
+ __ delayed() ->cmp(Rflags, ctos);
+
+ // ztos
+ __ ldsb(Rclass, Roffset, Otos_i);
+ __ push(itos);
+ if (!is_static && rc == may_rewrite) {
+ // use btos rewriting, no truncating to t/f bit is needed for getfield.
+ patch_bytecode(Bytecodes::_fast_bgetfield, G3_scratch, G4_scratch);
+ }
+ __ ba(checkVolatile);
+ __ delayed()->tst(Lscratch);
+
+ __ bind(notBool);
+
// cmp(Rflags, ctos);
__ br(Assembler::notEqual, false, Assembler::pt, notChar);
__ delayed() ->cmp(Rflags, stos);
@@ -2449,6 +2484,7 @@
switch (bytecode()) { // save tos values before call_VM() clobbers them
case Bytecodes::_fast_aputfield: __ push_ptr(Otos_i); break;
case Bytecodes::_fast_bputfield: // fall through
+ case Bytecodes::_fast_zputfield: // fall through
case Bytecodes::_fast_sputfield: // fall through
case Bytecodes::_fast_cputfield: // fall through
case Bytecodes::_fast_iputfield: __ push_i(Otos_i); break;
@@ -2466,6 +2502,7 @@
switch (bytecode()) { // restore tos values
case Bytecodes::_fast_aputfield: __ pop_ptr(Otos_i); break;
case Bytecodes::_fast_bputfield: // fall through
+ case Bytecodes::_fast_zputfield: // fall through
case Bytecodes::_fast_sputfield: // fall through
case Bytecodes::_fast_cputfield: // fall through
case Bytecodes::_fast_iputfield: __ pop_i(Otos_i); break;
@@ -2581,7 +2618,7 @@
ConstantPoolCacheEntry::verify_tos_state_shift();
// compute field type
- Label notInt, notShort, notChar, notObj, notByte, notLong, notFloat;
+ Label notInt, notShort, notChar, notObj, notByte, notBool, notLong, notFloat;
if (is_static) {
// putstatic with object type most likely, check that first
@@ -2649,7 +2686,7 @@
// cmp(Rflags, btos);
__ br(Assembler::notEqual, false, Assembler::pt, notByte);
- __ delayed()->cmp(Rflags, ltos);
+ __ delayed()->cmp(Rflags, ztos);
// btos
{
@@ -2664,6 +2701,25 @@
}
__ bind(notByte);
+
+ // cmp(Rflags, btos);
+ __ br(Assembler::notEqual, false, Assembler::pt, notBool);
+ __ delayed()->cmp(Rflags, ltos);
+
+ // ztos
+ {
+ __ pop_i();
+ if (!is_static) pop_and_check_object(Rclass);
+ __ and3(Otos_i, 1, Otos_i);
+ __ stb(Otos_i, Rclass, Roffset);
+ if (!is_static && rc == may_rewrite) {
+ patch_bytecode(Bytecodes::_fast_zputfield, G3_scratch, G4_scratch, true, byte_no);
+ }
+ __ ba(checkVolatile);
+ __ delayed()->tst(Lscratch);
+ }
+
+ __ bind(notBool);
// cmp(Rflags, ltos);
__ br(Assembler::notEqual, false, Assembler::pt, notLong);
__ delayed()->cmp(Rflags, ctos);
@@ -2787,6 +2843,7 @@
pop_and_check_object(Rclass);
switch (bytecode()) {
+ case Bytecodes::_fast_zputfield: __ and3(Otos_i, 1, Otos_i); // fall through to bputfield
case Bytecodes::_fast_bputfield: __ stb(Otos_i, Rclass, Roffset); break;
case Bytecodes::_fast_cputfield: /* fall through */
case Bytecodes::_fast_sputfield: __ sth(Otos_i, Rclass, Roffset); break;
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
+#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/java.hpp"
#include "runtime/os.hpp"
@@ -368,36 +369,38 @@
FLAG_SET_DEFAULT(UseUnalignedAccesses, false);
}
- if (PrintMiscellaneous && Verbose) {
- tty->print_cr("L1 data cache line size: %u", L1_data_cache_line_size());
- tty->print_cr("L2 data cache line size: %u", L2_data_cache_line_size());
- tty->print("Allocation");
+ if (log_is_enabled(Info, os, cpu)) {
+ ResourceMark rm;
+ outputStream* log = Log(os, cpu)::info_stream();
+ log->print_cr("L1 data cache line size: %u", L1_data_cache_line_size());
+ log->print_cr("L2 data cache line size: %u", L2_data_cache_line_size());
+ log->print("Allocation");
if (AllocatePrefetchStyle <= 0) {
- tty->print_cr(": no prefetching");
+ log->print(": no prefetching");
} else {
- tty->print(" prefetching: ");
+ log->print(" prefetching: ");
if (AllocatePrefetchInstr == 0) {
- tty->print("PREFETCH");
+ log->print("PREFETCH");
} else if (AllocatePrefetchInstr == 1) {
- tty->print("BIS");
+ log->print("BIS");
}
if (AllocatePrefetchLines > 1) {
- tty->print_cr(" at distance %d, %d lines of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchLines, (int) AllocatePrefetchStepSize);
+ log->print_cr(" at distance %d, %d lines of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchLines, (int) AllocatePrefetchStepSize);
} else {
- tty->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize);
+ log->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize);
}
}
if (PrefetchCopyIntervalInBytes > 0) {
- tty->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes);
+ log->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes);
}
if (PrefetchScanIntervalInBytes > 0) {
- tty->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes);
+ log->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes);
}
if (PrefetchFieldsAhead > 0) {
- tty->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead);
+ log->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead);
}
if (ContendedPaddingWidth > 0) {
- tty->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth);
+ log->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth);
}
}
}
@@ -408,7 +411,7 @@
int VM_Version::determine_features() {
if (UseV8InstrsOnly) {
- if (PrintMiscellaneous && Verbose) { tty->print_cr("Version is Forced-V8"); }
+ log_info(os, cpu)("Version is Forced-V8");
return generic_v8_m;
}
@@ -416,7 +419,7 @@
if (features == unknown_m) {
features = generic_v9_m;
- warning("Cannot recognize SPARC version. Default to V9");
+ log_info(os)("Cannot recognize SPARC version. Default to V9");
}
assert(is_T_family(features) == is_niagara(features), "Niagara should be T series");
@@ -424,12 +427,12 @@
if (is_T_family(features)) {
// Happy to accomodate...
} else {
- if (PrintMiscellaneous && Verbose) { tty->print_cr("Version is Forced-Niagara"); }
+ log_info(os, cpu)("Version is Forced-Niagara");
features |= T_family_m;
}
} else {
if (is_T_family(features) && !FLAG_IS_DEFAULT(UseNiagaraInstrs)) {
- if (PrintMiscellaneous && Verbose) { tty->print_cr("Version is Forced-Not-Niagara"); }
+ log_info(os, cpu)("Version is Forced-Not-Niagara");
features &= ~(T_family_m | T1_model_m);
} else {
// Happy to accomodate...
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -284,7 +284,7 @@
length.load_item();
}
- if (needs_store_check) {
+ if (needs_store_check || x->check_boolean()) {
value.load_item();
} else {
value.load_for_store(x->elt_type());
@@ -332,7 +332,8 @@
// Seems to be a precise
post_barrier(LIR_OprFact::address(array_addr), value.result());
} else {
- __ move(value.result(), array_addr, null_check_info);
+ LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info);
+ __ move(result, array_addr, null_check_info);
}
}
--- a/hotspot/src/cpu/x86/vm/debug_x86.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/debug_x86.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -29,6 +29,5 @@
#include "runtime/init.hpp"
#include "runtime/os.hpp"
#include "utilities/debug.hpp"
-#include "utilities/top.hpp"
void pd_ps(frame f) {}
--- a/hotspot/src/cpu/x86/vm/frame_x86.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/frame_x86.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -26,7 +26,6 @@
#define CPU_X86_VM_FRAME_X86_HPP
#include "runtime/synchronizer.hpp"
-#include "utilities/top.hpp"
// A frame represents a physical stack frame (an activation). Frames can be
// C or Java frames, and the Java frames can be interpreted or compiled.
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -349,6 +349,7 @@
verify_oop(rax, state); break;
case ltos: movptr(rax, val_addr); break;
case btos: // fall through
+ case ztos: // fall through
case ctos: // fall through
case stos: // fall through
case itos: movl(rax, val_addr); break;
@@ -370,6 +371,7 @@
case ltos:
movl(rdx, val_addr1); // fall through
case btos: // fall through
+ case ztos: // fall through
case ctos: // fall through
case stos: // fall through
case itos: movl(rax, val_addr); break;
@@ -616,6 +618,7 @@
switch (state) {
case atos: pop_ptr(); break;
case btos:
+ case ztos:
case ctos:
case stos:
case itos: pop_i(); break;
@@ -633,6 +636,7 @@
switch (state) {
case atos: push_ptr(); break;
case btos:
+ case ztos:
case ctos:
case stos:
case itos: push_i(); break;
@@ -668,6 +672,7 @@
switch (state) {
case atos: pop_ptr(rax); break;
case btos: // fall through
+ case ztos: // fall through
case ctos: // fall through
case stos: // fall through
case itos: pop_i(rax); break;
@@ -716,6 +721,7 @@
switch (state) {
case atos: push_ptr(rax); break;
case btos: // fall through
+ case ztos: // fall through
case ctos: // fall through
case stos: // fall through
case itos: push_i(rax); break;
@@ -849,6 +855,51 @@
dispatch_base(state, table);
}
+void InterpreterMacroAssembler::narrow(Register result) {
+
+ // Get method->_constMethod->_result_type
+ movptr(rcx, Address(rbp, frame::interpreter_frame_method_offset * wordSize));
+ movptr(rcx, Address(rcx, Method::const_offset()));
+ load_unsigned_byte(rcx, Address(rcx, ConstMethod::result_type_offset()));
+
+ Label done, notBool, notByte, notChar;
+
+ // common case first
+ cmpl(rcx, T_INT);
+ jcc(Assembler::equal, done);
+
+ // mask integer result to narrower return type.
+ cmpl(rcx, T_BOOLEAN);
+ jcc(Assembler::notEqual, notBool);
+ andl(result, 0x1);
+ jmp(done);
+
+ bind(notBool);
+ cmpl(rcx, T_BYTE);
+ jcc(Assembler::notEqual, notByte);
+ LP64_ONLY(movsbl(result, result);)
+ NOT_LP64(shll(result, 24);) // truncate upper 24 bits
+ NOT_LP64(sarl(result, 24);) // and sign-extend byte
+ jmp(done);
+
+ bind(notByte);
+ cmpl(rcx, T_CHAR);
+ jcc(Assembler::notEqual, notChar);
+ LP64_ONLY(movzwl(result, result);)
+ NOT_LP64(andl(result, 0xFFFF);) // truncate upper 16 bits
+ jmp(done);
+
+ bind(notChar);
+ // cmpl(rcx, T_SHORT); // all that's left
+ // jcc(Assembler::notEqual, done);
+ LP64_ONLY(movswl(result, result);)
+ NOT_LP64(shll(result, 16);) // truncate upper 16 bits
+ NOT_LP64(sarl(result, 16);) // and sign-extend short
+
+ // Nothing to do for T_INT
+ bind(done);
+}
+
// remove activation
//
// Unlock the receiver if this is a synchronized method.
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -192,6 +192,9 @@
void prepare_to_jump_from_interpreted();
void jump_from_interpreted(Register method, Register temp);
+ // narrow int return value
+ void narrow(Register result);
+
// Returning from interpreted functions
//
// Removes the current activation (incl. unlocking of monitors)
--- a/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -29,7 +29,6 @@
#include "memory/allocation.hpp"
#include "runtime/icache.hpp"
#include "runtime/os.hpp"
-#include "utilities/top.hpp"
// We have interfaces for the following instructions:
// - NativeInstruction
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -355,6 +355,14 @@
return size > 16;
}
+size_t SharedRuntime::trampoline_size() {
+ return 16;
+}
+
+void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) {
+ __ jump(RuntimeAddress(destination));
+}
+
// The java_calling_convention describes stack locations as ideal slots on
// a frame with no abi restrictions. Since we must observe abi restrictions
// (like the placement of the register window) the slots must be biased by
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -391,6 +391,14 @@
return size > 16;
}
+size_t SharedRuntime::trampoline_size() {
+ return 16;
+}
+
+void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) {
+ __ jump(RuntimeAddress(destination));
+}
+
// The java_calling_convention describes stack locations as ideal slots on
// a frame with no abi restrictions. Since we must observe abi restrictions
// (like the placement of the register window) the slots must be biased by
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -38,7 +38,6 @@
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.inline.hpp"
-#include "utilities/top.hpp"
#ifdef COMPILER2
#include "opto/runtime.hpp"
#endif
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -38,7 +38,6 @@
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.inline.hpp"
-#include "utilities/top.hpp"
#ifdef COMPILER2
#include "opto/runtime.hpp"
#endif
--- a/hotspot/src/cpu/x86/vm/templateTable_x86.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -243,6 +243,7 @@
switch (bc) {
case Bytecodes::_fast_aputfield:
case Bytecodes::_fast_bputfield:
+ case Bytecodes::_fast_zputfield:
case Bytecodes::_fast_cputfield:
case Bytecodes::_fast_dputfield:
case Bytecodes::_fast_fputfield:
@@ -1082,6 +1083,16 @@
// rbx: index
// rdx: array
index_check(rdx, rbx); // prefer index in rbx
+ // Need to check whether array is boolean or byte
+ // since both types share the bastore bytecode.
+ __ load_klass(rcx, rdx);
+ __ movl(rcx, Address(rcx, Klass::layout_helper_offset()));
+ int diffbit = Klass::layout_helper_boolean_diffbit();
+ __ testl(rcx, diffbit);
+ Label L_skip;
+ __ jccb(Assembler::zero, L_skip);
+ __ andl(rax, 1); // if it is a T_BOOLEAN array, mask the stored value to 0/1
+ __ bind(L_skip);
__ movb(Address(rdx, rbx,
Address::times_1,
arrayOopDesc::base_offset_in_bytes(T_BYTE)),
@@ -2540,13 +2551,12 @@
void TemplateTable::_return(TosState state) {
transition(state, state);
- Register robj = LP64_ONLY(c_rarg1) NOT_LP64(rax);
-
assert(_desc->calls_vm(),
"inconsistent calls_vm information"); // call in remove_activation
if (_desc->bytecode() == Bytecodes::_return_register_finalizer) {
assert(state == vtos, "only valid state");
+ Register robj = LP64_ONLY(c_rarg1) NOT_LP64(rax);
__ movptr(robj, aaddress(0));
__ load_klass(rdi, robj);
__ movl(rdi, Address(rdi, Klass::access_flags_offset()));
@@ -2559,7 +2569,14 @@
__ bind(skip_register_finalizer);
}
+ // Narrow result if state is itos but result type is smaller.
+ // Need to narrow in the return bytecode rather than in generate_return_entry
+ // since compiled code callers expect the result to already be narrowed.
+ if (state == itos) {
+ __ narrow(rax);
+ }
__ remove_activation(state, rbcp);
+
__ jmp(rbcp);
}
@@ -2754,7 +2771,7 @@
const Address field(obj, off, Address::times_1, 0*wordSize);
NOT_LP64(const Address hi(obj, off, Address::times_1, 1*wordSize));
- Label Done, notByte, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
+ Label Done, notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
__ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
// Make sure we don't need to mask edx after the above shift
@@ -2773,6 +2790,20 @@
__ jmp(Done);
__ bind(notByte);
+ __ cmpl(flags, ztos);
+ __ jcc(Assembler::notEqual, notBool);
+
+ // ztos (same code as btos)
+ __ load_signed_byte(rax, field);
+ __ push(ztos);
+ // Rewrite bytecode to be faster
+ if (!is_static && rc == may_rewrite) {
+ // use btos rewriting, no truncating to t/f bit is needed for getfield.
+ patch_bytecode(Bytecodes::_fast_bgetfield, bc, rbx);
+ }
+ __ jmp(Done);
+
+ __ bind(notBool);
__ cmpl(flags, atos);
__ jcc(Assembler::notEqual, notObj);
// atos
@@ -3006,7 +3037,7 @@
const Address field(obj, off, Address::times_1, 0*wordSize);
NOT_LP64( const Address hi(obj, off, Address::times_1, 1*wordSize);)
- Label notByte, notInt, notShort, notChar,
+ Label notByte, notBool, notInt, notShort, notChar,
notLong, notFloat, notObj, notDouble;
__ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
@@ -3027,6 +3058,22 @@
}
__ bind(notByte);
+ __ cmpl(flags, ztos);
+ __ jcc(Assembler::notEqual, notBool);
+
+ // ztos
+ {
+ __ pop(ztos);
+ if (!is_static) pop_and_check_object(obj);
+ __ andl(rax, 0x1);
+ __ movb(field, rax);
+ if (!is_static && rc == may_rewrite) {
+ patch_bytecode(Bytecodes::_fast_zputfield, bc, rbx, true, byte_no);
+ }
+ __ jmp(Done);
+ }
+
+ __ bind(notBool);
__ cmpl(flags, atos);
__ jcc(Assembler::notEqual, notObj);
@@ -3214,6 +3261,7 @@
switch (bytecode()) { // load values into the jvalue object
case Bytecodes::_fast_aputfield: __ push_ptr(rax); break;
case Bytecodes::_fast_bputfield: // fall through
+ case Bytecodes::_fast_zputfield: // fall through
case Bytecodes::_fast_sputfield: // fall through
case Bytecodes::_fast_cputfield: // fall through
case Bytecodes::_fast_iputfield: __ push_i(rax); break;
@@ -3238,6 +3286,7 @@
switch (bytecode()) { // restore tos values
case Bytecodes::_fast_aputfield: __ pop_ptr(rax); break;
case Bytecodes::_fast_bputfield: // fall through
+ case Bytecodes::_fast_zputfield: // fall through
case Bytecodes::_fast_sputfield: // fall through
case Bytecodes::_fast_cputfield: // fall through
case Bytecodes::_fast_iputfield: __ pop_i(rax); break;
@@ -3297,6 +3346,9 @@
case Bytecodes::_fast_iputfield:
__ movl(field, rax);
break;
+ case Bytecodes::_fast_zputfield:
+ __ andl(rax, 0x1); // boolean is true if LSB is 1
+ // fall through to bputfield
case Bytecodes::_fast_bputfield:
__ movb(field, rax);
break;
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "asm/macroAssembler.inline.hpp"
+#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/java.hpp"
#include "runtime/os.hpp"
@@ -1223,59 +1224,60 @@
}
#ifndef PRODUCT
- if (PrintMiscellaneous && Verbose) {
- tty->print_cr("Logical CPUs per core: %u",
+ if (log_is_enabled(Info, os, cpu)) {
+ outputStream* log = Log(os, cpu)::info_stream();
+ log->print_cr("Logical CPUs per core: %u",
logical_processors_per_package());
- tty->print_cr("L1 data cache line size: %u", L1_data_cache_line_size());
- tty->print("UseSSE=%d", (int) UseSSE);
+ log->print_cr("L1 data cache line size: %u", L1_data_cache_line_size());
+ log->print("UseSSE=%d", (int) UseSSE);
if (UseAVX > 0) {
- tty->print(" UseAVX=%d", (int) UseAVX);
+ log->print(" UseAVX=%d", (int) UseAVX);
}
if (UseAES) {
- tty->print(" UseAES=1");
+ log->print(" UseAES=1");
}
#ifdef COMPILER2
if (MaxVectorSize > 0) {
- tty->print(" MaxVectorSize=%d", (int) MaxVectorSize);
+ log->print(" MaxVectorSize=%d", (int) MaxVectorSize);
}
#endif
- tty->cr();
- tty->print("Allocation");
+ log->cr();
+ log->print("Allocation");
if (AllocatePrefetchStyle <= 0 || UseSSE == 0 && !supports_3dnow_prefetch()) {
- tty->print_cr(": no prefetching");
+ log->print_cr(": no prefetching");
} else {
- tty->print(" prefetching: ");
+ log->print(" prefetching: ");
if (UseSSE == 0 && supports_3dnow_prefetch()) {
- tty->print("PREFETCHW");
+ log->print("PREFETCHW");
} else if (UseSSE >= 1) {
if (AllocatePrefetchInstr == 0) {
- tty->print("PREFETCHNTA");
+ log->print("PREFETCHNTA");
} else if (AllocatePrefetchInstr == 1) {
- tty->print("PREFETCHT0");
+ log->print("PREFETCHT0");
} else if (AllocatePrefetchInstr == 2) {
- tty->print("PREFETCHT2");
+ log->print("PREFETCHT2");
} else if (AllocatePrefetchInstr == 3) {
- tty->print("PREFETCHW");
+ log->print("PREFETCHW");
}
}
if (AllocatePrefetchLines > 1) {
- tty->print_cr(" at distance %d, %d lines of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchLines, (int) AllocatePrefetchStepSize);
+ log->print_cr(" at distance %d, %d lines of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchLines, (int) AllocatePrefetchStepSize);
} else {
- tty->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize);
+ log->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize);
}
}
if (PrefetchCopyIntervalInBytes > 0) {
- tty->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes);
+ log->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes);
}
if (PrefetchScanIntervalInBytes > 0) {
- tty->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes);
+ log->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes);
}
if (PrefetchFieldsAhead > 0) {
- tty->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead);
+ log->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead);
}
if (ContendedPaddingWidth > 0) {
- tty->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth);
+ log->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth);
}
}
#endif // !PRODUCT
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -82,6 +82,30 @@
return 0;
}
+intptr_t narrow(BasicType type, intptr_t result) {
+ // mask integer result to narrower return type.
+ switch (type) {
+ case T_BOOLEAN:
+ return result&1;
+ case T_BYTE:
+ return (intptr_t)(jbyte)result;
+ case T_CHAR:
+ return (intptr_t)(uintptr_t)(jchar)result;
+ case T_SHORT:
+ return (intptr_t)(jshort)result;
+ case T_OBJECT: // nothing to do fall through
+ case T_ARRAY:
+ case T_LONG:
+ case T_INT:
+ case T_FLOAT:
+ case T_DOUBLE:
+ case T_VOID:
+ return result;
+ default : ShouldNotReachHere();
+ }
+}
+
+
void CppInterpreter::main_loop(int recurse, TRAPS) {
JavaThread *thread = (JavaThread *) THREAD;
ZeroStack *stack = thread->zero_stack();
@@ -161,7 +185,7 @@
}
else if (istate->msg() == BytecodeInterpreter::return_from_method) {
// Copy the result into the caller's frame
- result_slots = type2size[result_type_of(method)];
+ result_slots = type2size[method->result_type()];
assert(result_slots >= 0 && result_slots <= 2, "what?");
result = istate->stack() + result_slots;
break;
@@ -195,8 +219,14 @@
stack->set_sp(stack->sp() + method->max_locals());
// Push our result
- for (int i = 0; i < result_slots; i++)
- stack->push(result[-i]);
+ for (int i = 0; i < result_slots; i++) {
+ // Adjust result to smaller
+ intptr_t res = result[-i];
+ if (result_slots == 1) {
+ res = narrow(method->result_type(), res);
+ }
+ stack->push(res);
+ }
}
int CppInterpreter::native_entry(Method* method, intptr_t UNUSED, TRAPS) {
@@ -407,7 +437,7 @@
// Push our result
if (!HAS_PENDING_EXCEPTION) {
- BasicType type = result_type_of(method);
+ BasicType type = method->result_type();
stack->set_sp(stack->sp() - type2size[type]);
switch (type) {
@@ -532,6 +562,7 @@
break;
case btos:
+ case ztos:
SET_LOCALS_INT(object->byte_field_acquire(entry->f2_as_index()), 0);
break;
@@ -570,6 +601,7 @@
break;
case btos:
+ case ztos:
SET_LOCALS_INT(object->byte_field(entry->f2_as_index()), 0);
break;
@@ -772,26 +804,6 @@
return (InterpreterFrame *) fp;
}
-BasicType CppInterpreter::result_type_of(Method* method) {
- BasicType t = T_ILLEGAL; // silence compiler warnings
- switch (method->result_index()) {
- case 0 : t = T_BOOLEAN; break;
- case 1 : t = T_CHAR; break;
- case 2 : t = T_BYTE; break;
- case 3 : t = T_SHORT; break;
- case 4 : t = T_INT; break;
- case 5 : t = T_LONG; break;
- case 6 : t = T_VOID; break;
- case 7 : t = T_FLOAT; break;
- case 8 : t = T_DOUBLE; break;
- case 9 : t = T_OBJECT; break;
- default: ShouldNotReachHere();
- }
- assert(AbstractInterpreter::BasicType_as_index(t) == method->result_index(),
- "out of step with AbstractInterpreter::BasicType_as_index");
- return t;
-}
-
address CppInterpreter::return_entry(TosState state, int length, Bytecodes::Code code) {
ShouldNotCallThis();
return NULL;
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2010, 2011 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -49,8 +49,4 @@
static intptr_t* calculate_unwind_sp(ZeroStack* stack, oop method_handle);
static void throw_exception(JavaThread* thread, Symbol* name,char *msg=NULL);
- private:
- // Fast result type determination
- static BasicType result_type_of(Method* method);
-
#endif // CPU_ZERO_VM_CPPINTERPRETER_ZERO_HPP
--- a/hotspot/src/cpu/zero/vm/debug_zero.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/zero/vm/debug_zero.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -30,7 +30,6 @@
#include "runtime/init.hpp"
#include "runtime/os.hpp"
#include "utilities/debug.hpp"
-#include "utilities/top.hpp"
void pd_ps(frame f) {
ShouldNotCallThis();
--- a/hotspot/src/cpu/zero/vm/frame_zero.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/zero/vm/frame_zero.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -27,7 +27,6 @@
#define CPU_ZERO_VM_FRAME_ZERO_HPP
#include "runtime/synchronizer.hpp"
-#include "utilities/top.hpp"
// A frame represents a physical stack frame on the Zero stack.
--- a/hotspot/src/cpu/zero/vm/nativeInst_zero.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/zero/vm/nativeInst_zero.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -30,7 +30,6 @@
#include "memory/allocation.hpp"
#include "runtime/icache.hpp"
#include "runtime/os.hpp"
-#include "utilities/top.hpp"
// We have interfaces for the following instructions:
// - NativeInstruction
--- a/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -132,6 +132,15 @@
return generate_empty_runtime_stub("resolve_blob");
}
+size_t SharedRuntime::trampoline_size() {
+ ShouldNotCallThis();
+ return 0;
+}
+
+void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) {
+ ShouldNotCallThis();
+ return;
+}
int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
VMRegPair *regs,
--- a/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -40,7 +40,6 @@
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.inline.hpp"
#include "stack_zero.inline.hpp"
-#include "utilities/top.hpp"
#ifdef COMPILER2
#include "opto/runtime.hpp"
#endif
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SAGetopt.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SAGetopt.java Thu Apr 28 23:08:17 2016 -0700
@@ -55,11 +55,11 @@
private void extractOptarg(String opt) {
// Argument expected
if (_optind > _argv.length) {
- throw new RuntimeException("Not enough arguments for '" + opt + "'");
+ throw new SAGetoptException("Not enough arguments for '" + opt + "'");
}
if (! _argv[_optind].isEmpty() && _argv[_optind].charAt(0) == '-') {
- throw new RuntimeException("Argument is expected for '" + opt + "'");
+ throw new SAGetoptException("Argument is expected for '" + opt + "'");
}
_optarg = _argv[_optind];
@@ -72,7 +72,7 @@
if (los.contains(ca[0])) {
if (ca.length > 1) {
- throw new RuntimeException("Argument is not expected for '" + ca[0] + "'");
+ throw new SAGetoptException("Argument is not expected for '" + ca[0] + "'");
}
return carg;
}
@@ -87,14 +87,14 @@
try {
extractOptarg(ca[0]);
} catch (ArrayIndexOutOfBoundsException e) {
- throw new RuntimeException("Argument is expected for '" + ca[0] + "'");
+ throw new SAGetoptException("Argument is expected for '" + ca[0] + "'");
}
}
return ca[0];
}
- throw new RuntimeException("Invalid option '" + ca[0] + "'");
+ throw new SAGetoptException("Invalid option '" + ca[0] + "'");
}
public String next(String optStr, String[] longOptStr) {
@@ -148,7 +148,7 @@
int chIndex = optStr.indexOf(ch);
if (chIndex == -1) {
- throw new RuntimeException("Invalid option '" + ch + "'");
+ throw new SAGetoptException("Invalid option '" + ch + "'");
}
if (_optopt >= carg.length()) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SAGetoptException.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.jvm.hotspot;
+
+public class SAGetoptException extends IllegalArgumentException {
+
+ public SAGetoptException(String message) {
+ super(message);
+ }
+
+}
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java Thu Apr 28 23:08:17 2016 -0700
@@ -111,34 +111,31 @@
return launcherHelp();
}
- private static void buildAttachArgs(ArrayList<String> newArgs,
- String pid, String exe, String core) {
- if ((pid == null) && (exe == null)) {
- throw new IllegalArgumentException(
- "You have to set --pid or --exe.");
+ private static void buildAttachArgs(ArrayList<String> newArgs, String pid,
+ String exe, String core, boolean allowEmpty) {
+ if (!allowEmpty && (pid == null) && (exe == null)) {
+ throw new SAGetoptException("You have to set --pid or --exe.");
}
if (pid != null) { // Attach to live process
if (exe != null) {
- throw new IllegalArgumentException(
- "Unnecessary argument: --exe");
+ throw new SAGetoptException("Unnecessary argument: --exe");
} else if (core != null) {
- throw new IllegalArgumentException(
- "Unnecessary argument: --core");
+ throw new SAGetoptException("Unnecessary argument: --core");
} else if (!pid.matches("^\\d+$")) {
- throw new IllegalArgumentException("Invalid pid: " + pid);
+ throw new SAGetoptException("Invalid pid: " + pid);
}
newArgs.add(pid);
- } else {
+ } else if (exe != null) {
if (exe.length() == 0) {
- throw new IllegalArgumentException("You have to set --exe.");
+ throw new SAGetoptException("You have to set --exe.");
}
newArgs.add(exe);
if ((core == null) || (core.length() == 0)) {
- throw new IllegalArgumentException("You have to set --core.");
+ throw new SAGetoptException("You have to set --core.");
}
newArgs.add(core);
@@ -170,7 +167,7 @@
}
}
- buildAttachArgs(newArgs, pid, exe, core);
+ buildAttachArgs(newArgs, pid, exe, core, true);
CLHSDB.main(newArgs.toArray(new String[newArgs.size()]));
}
@@ -199,7 +196,7 @@
}
}
- buildAttachArgs(newArgs, pid, exe, core);
+ buildAttachArgs(newArgs, pid, exe, core, true);
HSDB.main(newArgs.toArray(new String[newArgs.size()]));
}
@@ -237,7 +234,7 @@
}
}
- buildAttachArgs(newArgs, pid, exe, core);
+ buildAttachArgs(newArgs, pid, exe, core, false);
JStack.main(newArgs.toArray(new String[newArgs.size()]));
}
@@ -287,7 +284,7 @@
}
}
- buildAttachArgs(newArgs, pid, exe, core);
+ buildAttachArgs(newArgs, pid, exe, core, false);
JMap.main(newArgs.toArray(new String[newArgs.size()]));
}
@@ -325,7 +322,7 @@
}
}
- buildAttachArgs(newArgs, pid, exe, core);
+ buildAttachArgs(newArgs, pid, exe, core, false);
JInfo.main(newArgs.toArray(new String[newArgs.size()]));
}
@@ -358,7 +355,7 @@
}
}
- buildAttachArgs(newArgs, pid, exe, core);
+ buildAttachArgs(newArgs, pid, exe, core, false);
JSnap.main(newArgs.toArray(new String[newArgs.size()]));
}
@@ -416,8 +413,8 @@
return;
}
- throw new IllegalArgumentException("Unknown tool: " + args[0]);
- } catch (Exception e) {
+ throw new SAGetoptException("Unknown tool: " + args[0]);
+ } catch (SAGetoptException e) {
System.err.println(e.getMessage());
toolHelp(args[0]);
}
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/interpreter/Bytecodes.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/interpreter/Bytecodes.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -253,29 +253,30 @@
public static final int _fast_sgetfield = 210;
public static final int _fast_aputfield = 211;
public static final int _fast_bputfield = 212;
- public static final int _fast_cputfield = 213;
- public static final int _fast_dputfield = 214;
- public static final int _fast_fputfield = 215;
- public static final int _fast_iputfield = 216;
- public static final int _fast_lputfield = 217;
- public static final int _fast_sputfield = 218;
- public static final int _fast_aload_0 = 219;
- public static final int _fast_iaccess_0 = 220;
- public static final int _fast_aaccess_0 = 221;
- public static final int _fast_faccess_0 = 222;
- public static final int _fast_iload = 223;
- public static final int _fast_iload2 = 224;
- public static final int _fast_icaload = 225;
- public static final int _fast_invokevfinal = 226;
- public static final int _fast_linearswitch = 227;
- public static final int _fast_binaryswitch = 228;
- public static final int _fast_aldc = 229;
- public static final int _fast_aldc_w = 230;
- public static final int _return_register_finalizer = 231;
- public static final int _invokehandle = 232;
- public static final int _shouldnotreachhere = 233; // For debugging
+ public static final int _fast_zputfield = 213;
+ public static final int _fast_cputfield = 214;
+ public static final int _fast_dputfield = 215;
+ public static final int _fast_fputfield = 216;
+ public static final int _fast_iputfield = 217;
+ public static final int _fast_lputfield = 218;
+ public static final int _fast_sputfield = 219;
+ public static final int _fast_aload_0 = 220;
+ public static final int _fast_iaccess_0 = 221;
+ public static final int _fast_aaccess_0 = 222;
+ public static final int _fast_faccess_0 = 223;
+ public static final int _fast_iload = 224;
+ public static final int _fast_iload2 = 225;
+ public static final int _fast_icaload = 226;
+ public static final int _fast_invokevfinal = 227;
+ public static final int _fast_linearswitch = 228;
+ public static final int _fast_binaryswitch = 229;
+ public static final int _fast_aldc = 230;
+ public static final int _fast_aldc_w = 231;
+ public static final int _return_register_finalizer = 232;
+ public static final int _invokehandle = 233;
+ public static final int _shouldnotreachhere = 234; // For debugging
- public static final int number_of_codes = 234;
+ public static final int number_of_codes = 235;
// Flag bits derived from format strings, can_trap, can_rewrite, etc.:
// semantic flags:
@@ -776,6 +777,7 @@
def(_fast_aputfield , "fast_aputfield" , "bJJ" , null , BasicType.getTObject() , 0, true , _putfield );
def(_fast_bputfield , "fast_bputfield" , "bJJ" , null , BasicType.getTInt() , 0, true , _putfield );
+ def(_fast_zputfield , "fast_zputfield" , "bJJ" , null , BasicType.getTInt() , 0, true , _putfield );
def(_fast_cputfield , "fast_cputfield" , "bJJ" , null , BasicType.getTChar() , 0, true , _putfield );
def(_fast_dputfield , "fast_dputfield" , "bJJ" , null , BasicType.getTDouble() , 0, true , _putfield );
def(_fast_fputfield , "fast_fputfield" , "bJJ" , null , BasicType.getTFloat() , 0, true , _putfield );
--- a/hotspot/src/os/aix/vm/os_aix.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os/aix/vm/os_aix.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -3612,14 +3612,12 @@
struct rlimit nbr_files;
int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
if (status != 0) {
- if (PrintMiscellaneous && (Verbose || WizardMode))
- perror("os::init_2 getrlimit failed");
+ log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno));
} else {
nbr_files.rlim_cur = nbr_files.rlim_max;
status = setrlimit(RLIMIT_NOFILE, &nbr_files);
if (status != 0) {
- if (PrintMiscellaneous && (Verbose || WizardMode))
- perror("os::init_2 setrlimit failed");
+ log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno));
}
}
}
--- a/hotspot/src/os/aix/vm/perfMemory_aix.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os/aix/vm/perfMemory_aix.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -956,7 +956,7 @@
#ifdef O_NOFOLLOW
RESTARTABLE(::open(filename, oflags), result);
#else
- open_o_nofollow(filename, oflags);
+ result = open_o_nofollow(filename, oflags);
#endif
if (result == OS_ERR) {
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -3459,25 +3459,13 @@
guarantee(polling_page != MAP_FAILED, "os::init_2: failed to allocate polling page");
os::set_polling_page(polling_page);
-
-#ifndef PRODUCT
- if (Verbose && PrintMiscellaneous) {
- tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n",
- (intptr_t)polling_page);
- }
-#endif
+ log_info(os)("SafePoint Polling address: " INTPTR_FORMAT, p2i(polling_page));
if (!UseMembar) {
address mem_serialize_page = (address) ::mmap(NULL, Bsd::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
guarantee(mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page");
os::set_memory_serialize_page(mem_serialize_page);
-
-#ifndef PRODUCT
- if (Verbose && PrintMiscellaneous) {
- tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n",
- (intptr_t)mem_serialize_page);
- }
-#endif
+ log_info(os)("Memory Serialize Page address: " INTPTR_FORMAT, p2i(mem_serialize_page));
}
// initialize suspend/resume support - must do this before signal_sets_init()
@@ -3519,9 +3507,7 @@
struct rlimit nbr_files;
int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
if (status != 0) {
- if (PrintMiscellaneous && (Verbose || WizardMode)) {
- perror("os::init_2 getrlimit failed");
- }
+ log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno));
} else {
nbr_files.rlim_cur = nbr_files.rlim_max;
@@ -3534,9 +3520,7 @@
status = setrlimit(RLIMIT_NOFILE, &nbr_files);
if (status != 0) {
- if (PrintMiscellaneous && (Verbose || WizardMode)) {
- perror("os::init_2 setrlimit failed");
- }
+ log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno));
}
}
}
@@ -3748,6 +3732,28 @@
return ::stat(pathbuf, sbuf);
}
+static inline struct timespec get_mtime(const char* filename) {
+ struct stat st;
+ int ret = os::stat(filename, &st);
+ assert(ret == 0, "failed to stat() file '%s': %s", filename, strerror(errno));
+#ifdef __APPLE__
+ return st.st_mtimespec;
+#else
+ return st.st_mtim;
+#endif
+}
+
+int os::compare_file_modified_times(const char* file1, const char* file2) {
+ struct timespec filetime1 = get_mtime(file1);
+ struct timespec filetime2 = get_mtime(file2);
+ int diff = filetime1.tv_sec - filetime2.tv_sec;
+ if (diff == 0) {
+ return filetime1.tv_nsec - filetime2.tv_nsec;
+ }
+ return diff;
+}
+
+
bool os::check_heap(bool force) {
return true;
}
--- a/hotspot/src/os/linux/vm/os_linux.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -2163,7 +2163,7 @@
bool model_name_printed = false;
if (strstr(buf, "model name") != NULL) {
if (!model_name_printed) {
- st->print_raw("\nCPU Model and flags from /proc/cpuinfo:\n");
+ st->print_raw("CPU Model and flags from /proc/cpuinfo:\n");
st->print_raw(buf);
model_name_printed = true;
} else {
@@ -4671,25 +4671,13 @@
guarantee(polling_page != MAP_FAILED, "os::init_2: failed to allocate polling page");
os::set_polling_page(polling_page);
-
-#ifndef PRODUCT
- if (Verbose && PrintMiscellaneous) {
- tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n",
- (intptr_t)polling_page);
- }
-#endif
+ log_info(os)("SafePoint Polling address: " INTPTR_FORMAT, p2i(polling_page));
if (!UseMembar) {
address mem_serialize_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
guarantee(mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page");
os::set_memory_serialize_page(mem_serialize_page);
-
-#ifndef PRODUCT
- if (Verbose && PrintMiscellaneous) {
- tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n",
- (intptr_t)mem_serialize_page);
- }
-#endif
+ log_info(os)("Memory Serialize Page address: " INTPTR_FORMAT, p2i(mem_serialize_page));
}
// initialize suspend/resume support - must do this before signal_sets_init()
@@ -4732,10 +4720,8 @@
#endif
Linux::libpthread_init();
- if (PrintMiscellaneous && (Verbose || WizardMode)) {
- tty->print_cr("[HotSpot is running with %s, %s]\n",
- Linux::glibc_version(), Linux::libpthread_version());
- }
+ log_info(os)("HotSpot is running with %s, %s",
+ Linux::glibc_version(), Linux::libpthread_version());
if (UseNUMA) {
if (!Linux::libnuma_init()) {
@@ -4776,16 +4762,12 @@
struct rlimit nbr_files;
int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
if (status != 0) {
- if (PrintMiscellaneous && (Verbose || WizardMode)) {
- perror("os::init_2 getrlimit failed");
- }
+ log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno));
} else {
nbr_files.rlim_cur = nbr_files.rlim_max;
status = setrlimit(RLIMIT_NOFILE, &nbr_files);
if (status != 0) {
- if (PrintMiscellaneous && (Verbose || WizardMode)) {
- perror("os::init_2 setrlimit failed");
- }
+ log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno));
}
}
}
@@ -6026,7 +6008,22 @@
return yes;
}
-
+static inline struct timespec get_mtime(const char* filename) {
+ struct stat st;
+ int ret = os::stat(filename, &st);
+ assert(ret == 0, "failed to stat() file '%s': %s", filename, strerror(errno));
+ return st.st_mtim;
+}
+
+int os::compare_file_modified_times(const char* file1, const char* file2) {
+ struct timespec filetime1 = get_mtime(file1);
+ struct timespec filetime2 = get_mtime(file2);
+ int diff = filetime1.tv_sec - filetime2.tv_sec;
+ if (diff == 0) {
+ return filetime1.tv_nsec - filetime2.tv_nsec;
+ }
+ return diff;
+}
/////////////// Unit tests ///////////////
--- a/hotspot/src/os/posix/vm/os_posix.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os/posix/vm/os_posix.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -181,6 +181,10 @@
return vsnprintf(buf, len, fmt, args);
}
+int os::fileno(FILE* fp) {
+ return ::fileno(fp);
+}
+
void os::Posix::print_load_average(outputStream* st) {
st->print("load average:");
double loadavg[3];
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -161,6 +161,7 @@
address os::Solaris::_main_stack_base = NULL; // 4352906 workaround
+os::Solaris::pthread_setname_np_func_t os::Solaris::_pthread_setname_np = NULL;
// "default" initializers for missing libc APIs
extern "C" {
@@ -441,8 +442,15 @@
}
void os::set_native_thread_name(const char *name) {
- // Not yet implemented.
- return;
+ if (Solaris::_pthread_setname_np != NULL) {
+ // Only the first 31 bytes of 'name' are processed by pthread_setname_np
+ // but we explicitly copy into a size-limited buffer to avoid any
+ // possible overflow.
+ char buf[32];
+ snprintf(buf, sizeof(buf), "%s", name);
+ buf[sizeof(buf) - 1] = '\0';
+ Solaris::_pthread_setname_np(pthread_self(), buf);
+ }
}
bool os::distribute_processes(uint length, uint* distribution) {
@@ -1819,6 +1827,19 @@
return ::stat(pathbuf, sbuf);
}
+static inline time_t get_mtime(const char* filename) {
+ struct stat st;
+ int ret = os::stat(filename, &st);
+ assert(ret == 0, "failed to stat() file '%s': %s", filename, strerror(errno));
+ return st.st_mtime;
+}
+
+int os::compare_file_modified_times(const char* file1, const char* file2) {
+ time_t t1 = get_mtime(file1);
+ time_t t2 = get_mtime(file2);
+ return t1 - t2;
+}
+
static bool _print_ascii_file(const char* filename, outputStream* st) {
int fd = ::open(filename, O_RDONLY);
if (fd == -1) {
@@ -2754,13 +2775,13 @@
pd_unmap_memory(addr, bytes);
}
- if (PrintMiscellaneous && Verbose) {
+ if (log_is_enabled(Warning, os)) {
char buf[256];
buf[0] = '\0';
if (addr == NULL) {
jio_snprintf(buf, sizeof(buf), ": %s", os::strerror(err));
}
- warning("attempt_reserve_memory_at: couldn't reserve " SIZE_FORMAT " bytes at "
+ log_info(os)("attempt_reserve_memory_at: couldn't reserve " SIZE_FORMAT " bytes at "
PTR_FORMAT ": reserve_memory_helper returned " PTR_FORMAT
"%s", bytes, requested_addr, addr, buf);
}
@@ -2790,9 +2811,7 @@
assert(i > 0, "gap adjustment code problem");
have_adjusted_gap = true; // adjust the gap only once, just in case
gap = actual_gap;
- if (PrintMiscellaneous && Verbose) {
- warning("attempt_reserve_memory_at: adjusted gap to 0x%lx", gap);
- }
+ log_info(os)("attempt_reserve_memory_at: adjusted gap to 0x%lx", gap);
unmap_memory(base[i], bytes);
unmap_memory(base[i-1], size[i-1]);
i-=2;
@@ -2824,8 +2843,8 @@
} else {
size_t bottom_overlap = base[i] + bytes - requested_addr;
if (bottom_overlap >= 0 && bottom_overlap < bytes) {
- if (PrintMiscellaneous && Verbose && bottom_overlap == 0) {
- warning("attempt_reserve_memory_at: possible alignment bug");
+ if (bottom_overlap == 0) {
+ log_info(os)("attempt_reserve_memory_at: possible alignment bug");
}
unmap_memory(requested_addr, bottom_overlap);
size[i] = bytes - bottom_overlap;
@@ -4355,8 +4374,8 @@
void init_pset_getloadavg_ptr(void) {
pset_getloadavg_ptr =
(pset_getloadavg_type)dlsym(RTLD_DEFAULT, "pset_getloadavg");
- if (PrintMiscellaneous && Verbose && pset_getloadavg_ptr == NULL) {
- warning("pset_getloadavg function not found");
+ if (pset_getloadavg_ptr == NULL) {
+ log_warning(os)("pset_getloadavg function not found");
}
}
@@ -4412,6 +4431,13 @@
// the minimum of what the OS supports (thr_min_stack()), and
// enough to allow the thread to get to user bytecode execution.
Solaris::min_stack_allowed = MAX2(thr_min_stack(), Solaris::min_stack_allowed);
+
+ // retrieve entry point for pthread_setname_np
+ void * handle = dlopen("libc.so.1", RTLD_LAZY);
+ if (handle != NULL) {
+ Solaris::_pthread_setname_np =
+ (Solaris::pthread_setname_np_func_t)dlsym(handle, "pthread_setname_np");
+ }
}
// To install functions for atexit system call
@@ -4439,25 +4465,13 @@
}
os::set_polling_page(polling_page);
-
-#ifndef PRODUCT
- if (Verbose && PrintMiscellaneous) {
- tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n",
- (intptr_t)polling_page);
- }
-#endif
+ log_info(os)("SafePoint Polling address: " INTPTR_FORMAT, p2i(polling_page));
if (!UseMembar) {
address mem_serialize_page = (address)Solaris::mmap_chunk(NULL, page_size, MAP_PRIVATE, PROT_READ | PROT_WRITE);
guarantee(mem_serialize_page != NULL, "mmap Failed for memory serialize page");
os::set_memory_serialize_page(mem_serialize_page);
-
-#ifndef PRODUCT
- if (Verbose && PrintMiscellaneous) {
- tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n",
- (intptr_t)mem_serialize_page);
- }
-#endif
+ log_info(os)("Memory Serialize Page address: " INTPTR_FORMAT, p2i(mem_serialize_page));
}
// Check minimum allowable stack size for thread creation and to initialize
@@ -4537,16 +4551,12 @@
struct rlimit nbr_files;
int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
if (status != 0) {
- if (PrintMiscellaneous && (Verbose || WizardMode)) {
- perror("os::init_2 getrlimit failed");
- }
+ log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno));
} else {
nbr_files.rlim_cur = nbr_files.rlim_max;
status = setrlimit(RLIMIT_NOFILE, &nbr_files);
if (status != 0) {
- if (PrintMiscellaneous && (Verbose || WizardMode)) {
- perror("os::init_2 setrlimit failed");
- }
+ log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno));
}
}
}
--- a/hotspot/src/os/solaris/vm/os_solaris.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os/solaris/vm/os_solaris.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -122,6 +122,9 @@
static int _SIGasync; // user-overridable ASYNC_SIGNAL
static void set_SIGasync(int newsig) { _SIGasync = newsig; }
+ typedef int (*pthread_setname_np_func_t)(pthread_t, const char*);
+ static pthread_setname_np_func_t _pthread_setname_np;
+
public:
// Large Page Support--ISM.
static bool largepage_range(char* addr, size_t size);
--- a/hotspot/src/os/windows/vm/os_windows.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1594,6 +1594,19 @@
return ret;
}
+static inline time_t get_mtime(const char* filename) {
+ struct stat st;
+ int ret = os::stat(filename, &st);
+ assert(ret == 0, "failed to stat() file '%s': %s", filename, strerror(errno));
+ return st.st_mtime;
+}
+
+int os::compare_file_modified_times(const char* file1, const char* file2) {
+ time_t t1 = get_mtime(file1);
+ time_t t2 = get_mtime(file2);
+ return t1 - t2;
+}
+
void os::print_os_info_brief(outputStream* st) {
os::print_os_info(st);
}
@@ -2436,14 +2449,10 @@
bool res = os::protect_memory((char*) page_start, page_size,
os::MEM_PROT_RWX);
- if (PrintMiscellaneous && Verbose) {
- char buf[256];
- jio_snprintf(buf, sizeof(buf), "Execution protection violation "
- "at " INTPTR_FORMAT
- ", unguarding " INTPTR_FORMAT ": %s", addr,
- page_start, (res ? "success" : os::strerror(errno)));
- tty->print_raw_cr(buf);
- }
+ log_debug(os)("Execution protection violation "
+ "at " INTPTR_FORMAT
+ ", unguarding " INTPTR_FORMAT ": %s", p2i(addr),
+ p2i(page_start), (res ? "success" : os::strerror(errno)));
// Set last_addr so if we fault again at the same address, we don't
// end up in an endless loop.
@@ -2896,12 +2905,12 @@
NUMAInterleaveGranularity = align_size_up(NUMAInterleaveGranularity, min_interleave_granularity);
if (numa_node_list_holder.build()) {
- if (PrintMiscellaneous && Verbose) {
- tty->print("NUMA UsedNodeCount=%d, namely ", numa_node_list_holder.get_count());
+ if (log_is_enabled(Debug, os, cpu)) {
+ Log(os, cpu) log;
+ log.debug("NUMA UsedNodeCount=%d, namely ", numa_node_list_holder.get_count());
for (int i = 0; i < numa_node_list_holder.get_count(); i++) {
- tty->print("%d ", numa_node_list_holder.get_node_list_entry(i));
+ log.debug(" %d ", numa_node_list_holder.get_node_list_entry(i));
}
- tty->print("\n");
}
success = true;
} else {
@@ -3010,9 +3019,7 @@
}
#ifdef ASSERT
if (should_inject_error) {
- if (TracePageSizes && Verbose) {
- tty->print_cr("Reserving pages individually failed.");
- }
+ log_develop_debug(pagesize)("Reserving pages individually failed.");
}
#endif
return NULL;
@@ -3196,9 +3203,8 @@
// 1) the UseLargePagesIndividualAllocation flag is set (set by default on WS2003)
// 2) NUMA Interleaving is enabled, in which case we use a different node for each page
if (UseLargePagesIndividualAllocation || UseNUMAInterleaving) {
- if (TracePageSizes && Verbose) {
- tty->print_cr("Reserving large pages individually.");
- }
+ log_debug(pagesize)("Reserving large pages individually.");
+
char * p_buf = allocate_pages_individually(bytes, addr, flags, prot, LargePagesIndividualAllocationInjectError);
if (p_buf == NULL) {
// give an appropriate warning message
@@ -3215,9 +3221,8 @@
return p_buf;
} else {
- if (TracePageSizes && Verbose) {
- tty->print_cr("Reserving large pages in a single large chunk.");
- }
+ log_debug(pagesize)("Reserving large pages in a single large chunk.");
+
// normal policy just allocate it all at once
DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
char * res = (char *)VirtualAlloc(addr, bytes, flag, prot);
@@ -4119,13 +4124,7 @@
guarantee(return_page != NULL, "Commit Failed for polling page");
os::set_polling_page(polling_page);
-
-#ifndef PRODUCT
- if (Verbose && PrintMiscellaneous) {
- tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n",
- (intptr_t)polling_page);
- }
-#endif
+ log_info(os)("SafePoint Polling address: " INTPTR_FORMAT, p2i(polling_page));
if (!UseMembar) {
address mem_serialize_page = (address)VirtualAlloc(NULL, os::vm_page_size(), MEM_RESERVE, PAGE_READWRITE);
@@ -4135,13 +4134,7 @@
guarantee(return_page != NULL, "Commit Failed for memory serialize page");
os::set_memory_serialize_page(mem_serialize_page);
-
-#ifndef PRODUCT
- if (Verbose && PrintMiscellaneous) {
- tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n",
- (intptr_t)mem_serialize_page);
- }
-#endif
+ log_info(os)("Memory Serialize Page address: " INTPTR_FORMAT, p2i(mem_serialize_page));
}
// Setup Windows Exceptions
@@ -4609,6 +4602,9 @@
return 0;
}
+int os::fileno(FILE* fp) {
+ return _fileno(fp);
+}
// This code is a copy of JDK's sysSync
// from src/windows/hpi/src/sys_api_md.c
@@ -4769,10 +4765,7 @@
hFile = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == NULL) {
- if (PrintMiscellaneous && Verbose) {
- DWORD err = GetLastError();
- tty->print_cr("CreateFile() failed: GetLastError->%ld.", err);
- }
+ log_info(os)("CreateFile() failed: GetLastError->%ld.", GetLastError());
return NULL;
}
@@ -4790,10 +4783,7 @@
base = (char*) VirtualAlloc(addr, bytes, MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE);
if (base == NULL) {
- if (PrintMiscellaneous && Verbose) {
- DWORD err = GetLastError();
- tty->print_cr("VirtualAlloc() failed: GetLastError->%ld.", err);
- }
+ log_info(os)("VirtualAlloc() failed: GetLastError->%ld.", GetLastError());
CloseHandle(hFile);
return NULL;
}
@@ -4807,10 +4797,7 @@
// number of bytes were read before returning.
bool res = ReadFile(hFile, base, (DWORD)bytes, &bytes_read, &overlapped) != 0;
if (!res) {
- if (PrintMiscellaneous && Verbose) {
- DWORD err = GetLastError();
- tty->print_cr("ReadFile() failed: GetLastError->%ld.", err);
- }
+ log_info(os)("ReadFile() failed: GetLastError->%ld.", GetLastError());
release_memory(base, bytes);
CloseHandle(hFile);
return NULL;
@@ -4819,10 +4806,7 @@
HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_WRITECOPY, 0, 0,
NULL /* file_name */);
if (hMap == NULL) {
- if (PrintMiscellaneous && Verbose) {
- DWORD err = GetLastError();
- tty->print_cr("CreateFileMapping() failed: GetLastError->%ld.", err);
- }
+ log_info(os)("CreateFileMapping() failed: GetLastError->%ld.", GetLastError());
CloseHandle(hFile);
return NULL;
}
@@ -4831,20 +4815,14 @@
base = (char*)MapViewOfFileEx(hMap, access, 0, (DWORD)file_offset,
(DWORD)bytes, addr);
if (base == NULL) {
- if (PrintMiscellaneous && Verbose) {
- DWORD err = GetLastError();
- tty->print_cr("MapViewOfFileEx() failed: GetLastError->%ld.", err);
- }
+ log_info(os)("MapViewOfFileEx() failed: GetLastError->%ld.", GetLastError());
CloseHandle(hMap);
CloseHandle(hFile);
return NULL;
}
if (CloseHandle(hMap) == 0) {
- if (PrintMiscellaneous && Verbose) {
- DWORD err = GetLastError();
- tty->print_cr("CloseHandle(hMap) failed: GetLastError->%ld.", err);
- }
+ log_info(os)("CloseHandle(hMap) failed: GetLastError->%ld.", GetLastError());
CloseHandle(hFile);
return base;
}
@@ -4856,10 +4834,7 @@
bool res = VirtualProtect(base, bytes, exec_access, &old_protect) != 0;
if (!res) {
- if (PrintMiscellaneous && Verbose) {
- DWORD err = GetLastError();
- tty->print_cr("VirtualProtect() failed: GetLastError->%ld.", err);
- }
+ log_info(os)("VirtualProtect() failed: GetLastError->%ld.", GetLastError());
// Don't consider this a hard error, on IA32 even if the
// VirtualProtect fails, we should still be able to execute
CloseHandle(hFile);
@@ -4868,10 +4843,7 @@
}
if (CloseHandle(hFile) == 0) {
- if (PrintMiscellaneous && Verbose) {
- DWORD err = GetLastError();
- tty->print_cr("CloseHandle(hFile) failed: GetLastError->%ld.", err);
- }
+ log_info(os)("CloseHandle(hFile) failed: GetLastError->%ld.", GetLastError());
return base;
}
@@ -4904,10 +4876,7 @@
bool os::pd_unmap_memory(char* addr, size_t bytes) {
MEMORY_BASIC_INFORMATION mem_info;
if (VirtualQuery(addr, &mem_info, sizeof(mem_info)) == 0) {
- if (PrintMiscellaneous && Verbose) {
- DWORD err = GetLastError();
- tty->print_cr("VirtualQuery() failed: GetLastError->%ld.", err);
- }
+ log_info(os)("VirtualQuery() failed: GetLastError->%ld.", GetLastError());
return false;
}
@@ -4924,10 +4893,7 @@
BOOL result = UnmapViewOfFile(addr);
if (result == 0) {
- if (PrintMiscellaneous && Verbose) {
- DWORD err = GetLastError();
- tty->print_cr("UnmapViewOfFile() failed: GetLastError->%ld.", err);
- }
+ log_info(os)("UnmapViewOfFile() failed: GetLastError->%ld.", GetLastError());
return false;
}
return true;
--- a/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2014 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -184,9 +184,7 @@
if (os::Aix::chained_handler(sig, info, ucVoid)) {
return 1;
} else {
- if (PrintMiscellaneous && (WizardMode || Verbose)) {
- warning("Ignoring SIGPIPE - see bug 4229104");
- }
+ // Ignoring SIGPIPE - see bugs 4229104
return 1;
}
}
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -469,11 +469,7 @@
if (os::Bsd::chained_handler(sig, info, ucVoid)) {
return true;
} else {
- if (PrintMiscellaneous && (WizardMode || Verbose)) {
- char buf[64];
- warning("Ignoring %s - see bugs 4229104 or 646499219",
- os::exception_name(sig, buf, sizeof(buf)));
- }
+ // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
return true;
}
}
@@ -728,14 +724,10 @@
bool res = os::protect_memory((char*) page_start, page_size,
os::MEM_PROT_RWX);
- if (PrintMiscellaneous && Verbose) {
- char buf[256];
- jio_snprintf(buf, sizeof(buf), "Execution protection violation "
- "at " INTPTR_FORMAT
- ", unguarding " INTPTR_FORMAT ": %s, errno=%d", addr,
- page_start, (res ? "success" : "failed"), errno);
- tty->print_raw_cr(buf);
- }
+ log_debug(os)("Execution protection violation "
+ "at " INTPTR_FORMAT
+ ", unguarding " INTPTR_FORMAT ": %s, errno=%d", p2i(addr),
+ p2i(page_start), (res ? "success" : "failed"), errno);
stub = pc;
// Set last_addr so if we fault again at the same address, we don't end
--- a/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "memory/metaspaceShared.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/thread.inline.hpp"
@@ -64,6 +65,14 @@
return false;
}
+#if INCLUDE_CDS
+ if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) {
+ // In the middle of a trampoline call. Bail out for safety.
+ // This happens rarely so shouldn't affect profiling.
+ return false;
+ }
+#endif
+
frame ret_frame(ret_sp, ret_fp, addr.pc());
if (!ret_frame.safe_for_sender(jt)) {
#if defined(COMPILER2) || INCLUDE_JVMCI
--- a/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -159,11 +159,7 @@
if (os::Bsd::chained_handler(sig, info, ucVoid)) {
return true;
} else {
- if (PrintMiscellaneous && (WizardMode || Verbose)) {
- char buf[64];
- warning("Ignoring %s - see bugs 4229104 or 646499219",
- os::exception_name(sig, buf, sizeof(buf)));
- }
+ // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
return true;
}
}
--- a/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -270,11 +270,7 @@
if (os::Linux::chained_handler(sig, info, ucVoid)) {
return true;
} else {
- if (PrintMiscellaneous && (WizardMode || Verbose)) {
- char buf[64];
- warning("Ignoring %s - see bugs 4229104 or 646499219",
- os::exception_name(sig, buf, sizeof(buf)));
- }
+ // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
return true;
}
}
--- a/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -24,6 +24,7 @@
*/
#include "precompiled.hpp"
+#include "memory/metaspaceShared.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/thread.inline.hpp"
@@ -66,6 +67,14 @@
return false;
}
+#if INCLUDE_CDS
+ if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) {
+ // In the middle of a trampoline call. Bail out for safety.
+ // This happens rarely so shouldn't affect profiling.
+ return false;
+ }
+#endif
+
frame ret_frame(ret_sp, ret_fp, addr.pc());
if (!ret_frame.safe_for_sender(jt)) {
#ifdef COMPILER2
--- a/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -198,9 +198,7 @@
if (os::Linux::chained_handler(sig, info, ucVoid)) {
return true;
} else {
- if (PrintMiscellaneous && (WizardMode || Verbose)) {
- warning("Ignoring SIGPIPE - see bug 4229104");
- }
+ // Ignoring SIGPIPE - see bugs 4229104
return true;
}
}
--- a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -561,11 +561,7 @@
if (os::Linux::chained_handler(sig, info, ucVoid)) {
return true;
} else {
- if (PrintMiscellaneous && (WizardMode || Verbose)) {
- char buf[64];
- warning("Ignoring %s - see bugs 4229104 or 646499219",
- os::exception_name(sig, buf, sizeof(buf)));
- }
+ // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
return true;
}
}
--- a/hotspot/src/os_cpu/linux_sparc/vm/thread_linux_sparc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/linux_sparc/vm/thread_linux_sparc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "memory/metaspaceShared.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/thread.inline.hpp"
@@ -64,6 +65,14 @@
return false;
}
+#if INCLUDE_CDS
+ if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) {
+ // In the middle of a trampoline call. Bail out for safety.
+ // This happens rarely so shouldn't affect profiling.
+ return false;
+ }
+#endif
+
// we were running Java code when SIGPROF came in
if (isInJava) {
// If we have a last_Java_sp, then the SIGPROF signal caught us
--- a/hotspot/src/os_cpu/linux_sparc/vm/vm_version_linux_sparc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/linux_sparc/vm/vm_version_linux_sparc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -66,12 +66,12 @@
features = generic_v9_m;
if (detect_niagara()) {
- if (PrintMiscellaneous && Verbose) { tty->print_cr("Detected Linux on Niagara"); }
+ log_info(os, cpu)("Detected Linux on Niagara");
features = niagara1_m | T_family_m;
}
if (detect_M_family()) {
- if (PrintMiscellaneous && Verbose) { tty->print_cr("Detected Linux on M family"); }
+ log_info(os, cpu)("Detected Linux on M family");
features = sun4v_m | generic_v9_m | M_family_m | T_family_m;
}
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -287,11 +287,7 @@
if (os::Linux::chained_handler(sig, info, ucVoid)) {
return true;
} else {
- if (PrintMiscellaneous && (WizardMode || Verbose)) {
- char buf[64];
- warning("Ignoring %s - see bugs 4229104 or 646499219",
- os::exception_name(sig, buf, sizeof(buf)));
- }
+ // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
return true;
}
}
@@ -542,14 +538,10 @@
bool res = os::protect_memory((char*) page_start, page_size,
os::MEM_PROT_RWX);
- if (PrintMiscellaneous && Verbose) {
- char buf[256];
- jio_snprintf(buf, sizeof(buf), "Execution protection violation "
- "at " INTPTR_FORMAT
- ", unguarding " INTPTR_FORMAT ": %s, errno=%d", addr,
- page_start, (res ? "success" : "failed"), errno);
- tty->print_raw_cr(buf);
- }
+ log_debug(os)("Execution protection violation "
+ "at " INTPTR_FORMAT
+ ", unguarding " INTPTR_FORMAT ": %s, errno=%d", p2i(addr),
+ p2i(page_start), (res ? "success" : "failed"), errno);
stub = pc;
// Set last_addr so if we fault again at the same address, we don't end
@@ -645,12 +637,8 @@
int major = strtol(uts.release,&minor_string,10);
int minor = strtol(minor_string+1,NULL,10);
bool result = (major > 2 || (major==2 && minor >= 4));
-#ifndef PRODUCT
- if (PrintMiscellaneous && Verbose) {
- tty->print("OS version is %d.%d, which %s support SSE/SSE2\n",
+ log_info(os)("OS version is %d.%d, which %s support SSE/SSE2",
major,minor, result ? "DOES" : "does NOT");
- }
-#endif
return result;
#endif // AMD64
}
@@ -939,9 +927,7 @@
MemTracker::record_virtual_memory_type((address)codebuf, mtInternal);
- if (PrintMiscellaneous && (Verbose || WizardMode)) {
- tty->print_cr("[CS limit NX emulation work-around, exec code at: %p]", codebuf);
- }
+ log_info(os)("[CS limit NX emulation work-around, exec code at: %p]", codebuf);
// Some code to exec: the 'ret' instruction
codebuf[0] = 0xC3;
--- a/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "memory/metaspaceShared.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/thread.inline.hpp"
@@ -65,6 +66,14 @@
return false;
}
+#if INCLUDE_CDS
+ if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) {
+ // In the middle of a trampoline call. Bail out for safety.
+ // This happens rarely so shouldn't affect profiling.
+ return false;
+ }
+#endif
+
frame ret_frame(ret_sp, ret_fp, addr.pc());
if (!ret_frame.safe_for_sender(jt)) {
#if defined(COMPILER2) || INCLUDE_JVMCI
--- a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -154,11 +154,7 @@
if (os::Linux::chained_handler(sig, info, ucVoid)) {
return true;
} else {
- if (PrintMiscellaneous && (WizardMode || Verbose)) {
- char buf[64];
- warning("Ignoring %s - see bugs 4229104 or 646499219",
- os::exception_name(sig, buf, sizeof(buf)));
- }
+ // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
return true;
}
}
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -338,12 +338,7 @@
if (os::Solaris::chained_handler(sig, info, ucVoid)) {
return true;
} else {
- if (PrintMiscellaneous && (WizardMode || Verbose)) {
- char buf[64];
- warning("Ignoring %s - see 4229104 or 6499219",
- os::exception_name(sig, buf, sizeof(buf)));
-
- }
+ // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
return true;
}
}
--- a/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "memory/metaspaceShared.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/thread.inline.hpp"
@@ -77,6 +78,14 @@
return false;
}
+#if INCLUDE_CDS
+ if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) {
+ // In the middle of a trampoline call. Bail out for safety.
+ // This happens rarely so shouldn't affect profiling.
+ return false;
+ }
+#endif
+
frame ret_frame(ret_sp, frame::unpatchable, addr.pc());
// we were running Java code when SIGPROF came in
--- a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "logging/log.hpp"
#include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp"
#include "runtime/os.hpp"
@@ -361,15 +362,10 @@
assert(avn <= 2, "should return two or less av's");
uint_t av = avs[0];
-#ifndef PRODUCT
- if (PrintMiscellaneous && Verbose) {
- tty->print("getisax(2) returned: " PTR32_FORMAT, av);
- if (avn > 1) {
- tty->print(", " PTR32_FORMAT, avs[1]);
- }
- tty->cr();
+ log_info(os, cpu)("getisax(2) returned: " PTR32_FORMAT, av);
+ if (avn > 1) {
+ log_info(os, cpu)(" " PTR32_FORMAT, avs[1]);
}
-#endif
if (av & AV_SPARC_MUL32) features |= hardware_mul32_m;
if (av & AV_SPARC_DIV32) features |= hardware_div32_m;
@@ -464,11 +460,7 @@
if (strcmp((const char*)&(knm[i].name),"implementation") == 0) {
implementation = KSTAT_NAMED_STR_PTR(&knm[i]);
has_implementation = true;
-#ifndef PRODUCT
- if (PrintMiscellaneous && Verbose) {
- tty->print_cr("cpu_info.implementation: %s", implementation);
- }
-#endif
+ log_info(os, cpu)("cpu_info.implementation: %s", implementation);
features |= parse_features(implementation);
break;
}
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -403,12 +403,7 @@
if (os::Solaris::chained_handler(sig, info, ucVoid)) {
return true;
} else {
- if (PrintMiscellaneous && (WizardMode || Verbose)) {
- char buf[64];
- warning("Ignoring %s - see 4229104 or 6499219",
- os::exception_name(sig, buf, sizeof(buf)));
-
- }
+ // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
return true;
}
}
@@ -640,14 +635,10 @@
bool res = os::protect_memory((char*) page_start, page_size,
os::MEM_PROT_RWX);
- if (PrintMiscellaneous && Verbose) {
- char buf[256];
- jio_snprintf(buf, sizeof(buf), "Execution protection violation "
- "at " INTPTR_FORMAT
- ", unguarding " INTPTR_FORMAT ": %s, errno=%d", addr,
- page_start, (res ? "success" : "failed"), errno);
- tty->print_raw_cr(buf);
- }
+ log_debug(os)("Execution protection violation "
+ "at " INTPTR_FORMAT
+ ", unguarding " INTPTR_FORMAT ": %s, errno=%d", p2i(addr),
+ p2i(page_start), (res ? "success" : "failed"), errno);
stub = pc;
// Set last_addr so if we fault again at the same address, we don't end
--- a/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "memory/metaspaceShared.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/thread.inline.hpp"
@@ -70,6 +71,14 @@
return false;
}
+#if INCLUDE_CDS
+ if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) {
+ // In the middle of a trampoline call. Bail out for safety.
+ // This happens rarely so shouldn't affect profiling.
+ return false;
+ }
+#endif
+
// If sp and fp are nonsense just leave them out
if (!jt->on_local_stack((address)ret_sp)) {
--- a/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "memory/metaspaceShared.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/thread.inline.hpp"
@@ -72,6 +73,14 @@
return false;
}
+#if INCLUDE_CDS
+ if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) {
+ // In the middle of a trampoline call. Bail out for safety.
+ // This happens rarely so shouldn't affect profiling.
+ return false;
+ }
+#endif
+
frame ret_frame(ret_sp, ret_fp, addr.pc());
if (!ret_frame.safe_for_sender(jt)) {
#if defined(COMPILER2) || INCLUDE_JVMCI
--- a/hotspot/src/share/vm/asm/assembler.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/asm/assembler.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -33,7 +33,6 @@
#include "runtime/vm_version.hpp"
#include "utilities/debug.hpp"
#include "utilities/growableArray.hpp"
-#include "utilities/top.hpp"
// This file contains platform-independent assembler declarations.
--- a/hotspot/src/share/vm/asm/register.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/asm/register.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -25,7 +25,8 @@
#ifndef SHARE_VM_ASM_REGISTER_HPP
#define SHARE_VM_ASM_REGISTER_HPP
-#include "utilities/top.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
// Use AbstractRegister as shortcut
class AbstractRegisterImpl;
--- a/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -305,7 +305,8 @@
// limit this optimization to current block
if (value != NULL && in_current_block(conv)) {
set_canonical(new StoreIndexed(x->array(), x->index(), x->length(),
- x->elt_type(), value, x->state_before()));
+ x->elt_type(), value, x->state_before(),
+ x->check_boolean()));
return;
}
}
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -976,7 +976,19 @@
(array->as_NewArray() && array->as_NewArray()->length() && array->as_NewArray()->length()->type()->is_constant())) {
length = append(new ArrayLength(array, state_before));
}
- StoreIndexed* result = new StoreIndexed(array, index, length, type, value, state_before);
+ ciType* array_type = array->declared_type();
+ bool check_boolean = false;
+ if (array_type != NULL) {
+ if (array_type->is_loaded() &&
+ array_type->as_array_klass()->element_type()->basic_type() == T_BOOLEAN) {
+ assert(type == T_BYTE, "boolean store uses bastore");
+ Value mask = append(new Constant(new IntConstant(1)));
+ value = append(new LogicOp(Bytecodes::_iand, value, mask));
+ }
+ } else if (type == T_BYTE) {
+ check_boolean = true;
+ }
+ StoreIndexed* result = new StoreIndexed(array, index, length, type, value, state_before, check_boolean);
append(result);
_memory->store_value(value);
@@ -1443,6 +1455,36 @@
need_mem_bar = true;
}
+ BasicType bt = method()->return_type()->basic_type();
+ switch (bt) {
+ case T_BYTE:
+ {
+ Value shift = append(new Constant(new IntConstant(24)));
+ x = append(new ShiftOp(Bytecodes::_ishl, x, shift));
+ x = append(new ShiftOp(Bytecodes::_ishr, x, shift));
+ break;
+ }
+ case T_SHORT:
+ {
+ Value shift = append(new Constant(new IntConstant(16)));
+ x = append(new ShiftOp(Bytecodes::_ishl, x, shift));
+ x = append(new ShiftOp(Bytecodes::_ishr, x, shift));
+ break;
+ }
+ case T_CHAR:
+ {
+ Value mask = append(new Constant(new IntConstant(0xFFFF)));
+ x = append(new LogicOp(Bytecodes::_iand, x, mask));
+ break;
+ }
+ case T_BOOLEAN:
+ {
+ Value mask = append(new Constant(new IntConstant(1)));
+ x = append(new LogicOp(Bytecodes::_iand, x, mask));
+ break;
+ }
+ }
+
// Check to see whether we are inlining. If so, Return
// instructions become Gotos to the continuation point.
if (continuation() != NULL) {
@@ -1611,6 +1653,10 @@
if (state_before == NULL) {
state_before = copy_state_for_exception();
}
+ if (field->type()->basic_type() == T_BOOLEAN) {
+ Value mask = append(new Constant(new IntConstant(1)));
+ val = append(new LogicOp(Bytecodes::_iand, val, mask));
+ }
append(new StoreField(append(obj), offset, field, val, true, state_before, needs_patching));
break;
}
@@ -1672,6 +1718,10 @@
if (state_before == NULL) {
state_before = copy_state_for_exception();
}
+ if (field->type()->basic_type() == T_BOOLEAN) {
+ Value mask = append(new Constant(new IntConstant(1)));
+ val = append(new LogicOp(Bytecodes::_iand, val, mask));
+ }
StoreField* store = new StoreField(obj, offset, field, val, false, state_before, needs_patching);
if (!needs_patching) store = _memory->store(store);
if (store != NULL) {
@@ -4134,7 +4184,12 @@
#ifndef _LP64
offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
#endif
- Instruction* op = append(new UnsafePutObject(t, args->at(1), offset, args->at(3), is_volatile));
+ Value val = args->at(3);
+ if (t == T_BOOLEAN) {
+ Value mask = append(new Constant(new IntConstant(1)));
+ val = append(new LogicOp(Bytecodes::_iand, val, mask));
+ }
+ Instruction* op = append(new UnsafePutObject(t, args->at(1), offset, val, is_volatile));
compilation()->set_has_unsafe_access(true);
kill_all();
}
@@ -4208,7 +4263,7 @@
Value index = args->at(1);
if (is_store) {
Value value = args->at(2);
- Instruction* store = append(new StoreIndexed(array, index, NULL, T_CHAR, value, state_before));
+ Instruction* store = append(new StoreIndexed(array, index, NULL, T_CHAR, value, state_before, false));
store->set_flag(Instruction::NeedsRangeCheckFlag, false);
_memory->store_value(value);
} else {
--- a/hotspot/src/share/vm/c1/c1_Instruction.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -974,11 +974,13 @@
ciMethod* _profiled_method;
int _profiled_bci;
+ bool _check_boolean;
+
public:
// creation
- StoreIndexed(Value array, Value index, Value length, BasicType elt_type, Value value, ValueStack* state_before)
+ StoreIndexed(Value array, Value index, Value length, BasicType elt_type, Value value, ValueStack* state_before, bool check_boolean)
: AccessIndexed(array, index, length, elt_type, state_before)
- , _value(value), _profiled_method(NULL), _profiled_bci(0)
+ , _value(value), _profiled_method(NULL), _profiled_bci(0), _check_boolean(check_boolean)
{
set_flag(NeedsWriteBarrierFlag, (as_ValueType(elt_type)->is_object()));
set_flag(NeedsStoreCheckFlag, (as_ValueType(elt_type)->is_object()));
@@ -990,6 +992,7 @@
Value value() const { return _value; }
bool needs_write_barrier() const { return check_flag(NeedsWriteBarrierFlag); }
bool needs_store_check() const { return check_flag(NeedsStoreCheckFlag); }
+ bool check_boolean() const { return _check_boolean; }
// Helpers for MethodData* profiling
void set_should_profile(bool value) { set_flag(ProfileMDOFlag, value); }
void set_profiled_method(ciMethod* method) { _profiled_method = method; }
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -28,7 +28,6 @@
#include "c1/c1_CodeStubs.hpp"
#include "ci/ciMethodData.hpp"
#include "oops/methodData.hpp"
-#include "utilities/top.hpp"
class Compilation;
class ScopeValue;
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -3680,3 +3680,26 @@
}
}
}
+
+LIR_Opr LIRGenerator::maybe_mask_boolean(StoreIndexed* x, LIR_Opr array, LIR_Opr value, CodeEmitInfo*& null_check_info) {
+ if (x->check_boolean()) {
+ LIR_Opr value_fixed = rlock_byte(T_BYTE);
+ if (TwoOperandLIRForm) {
+ __ move(value, value_fixed);
+ __ logical_and(value_fixed, LIR_OprFact::intConst(1), value_fixed);
+ } else {
+ __ logical_and(value, LIR_OprFact::intConst(1), value_fixed);
+ }
+ LIR_Opr klass = new_register(T_METADATA);
+ __ move(new LIR_Address(array, oopDesc::klass_offset_in_bytes(), T_ADDRESS), klass, null_check_info);
+ null_check_info = NULL;
+ LIR_Opr layout = new_register(T_INT);
+ __ move(new LIR_Address(klass, in_bytes(Klass::layout_helper_offset()), T_INT), layout);
+ int diffbit = Klass::layout_helper_boolean_diffbit();
+ __ logical_and(layout, LIR_OprFact::intConst(diffbit), layout);
+ __ cmp(lir_cond_notEqual, layout, LIR_OprFact::intConst(0));
+ __ cmove(lir_cond_notEqual, value_fixed, value, value_fixed, T_BYTE);
+ value = value_fixed;
+ }
+ return value;
+}
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -448,6 +448,7 @@
void profile_arguments(ProfileCall* x);
void profile_parameters(Base* x);
void profile_parameters_at_call(ProfileCall* x);
+ LIR_Opr maybe_mask_boolean(StoreIndexed* x, LIR_Opr array, LIR_Opr value, CodeEmitInfo*& null_check_info);
public:
Compilation* compilation() const { return _compilation; }
--- a/hotspot/src/share/vm/ci/ciFlags.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/ci/ciFlags.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -29,6 +29,7 @@
#include "memory/allocation.hpp"
#include "prims/jvm.h"
#include "utilities/accessFlags.hpp"
+#include "utilities/ostream.hpp"
// ciFlags
//
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -2713,11 +2713,9 @@
m->set_constants(_cp);
m->set_name_index(name_index);
m->set_signature_index(signature_index);
-#ifdef CC_INTERP
- // hmm is there a gc issue here??
+
ResultTypeFinder rtf(cp->symbol_at(signature_index));
- m->set_result_index(rtf.type());
-#endif
+ m->constMethod()->set_result_type(rtf.type());
if (args_size >= 0) {
m->set_size_of_parameters(args_size);
--- a/hotspot/src/share/vm/classfile/classFileStream.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classFileStream.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -25,8 +25,9 @@
#ifndef SHARE_VM_CLASSFILE_CLASSFILESTREAM_HPP
#define SHARE_VM_CLASSFILE_CLASSFILESTREAM_HPP
+#include "memory/allocation.hpp"
#include "utilities/bytes.hpp"
-#include "utilities/top.hpp"
+#include "utilities/exceptions.hpp"
// Input stream for reading .class file
//
--- a/hotspot/src/share/vm/classfile/classLoader.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -98,12 +98,13 @@
// Entry points for jimage.dll for loading jimage file entries
-static JImageOpen_t JImageOpen = NULL;
-static JImageClose_t JImageClose = NULL;
-static JImagePackageToModule_t JImagePackageToModule = NULL;
-static JImageFindResource_t JImageFindResource = NULL;
-static JImageGetResource_t JImageGetResource = NULL;
-static JImageResourceIterator_t JImageResourceIterator = NULL;
+static JImageOpen_t JImageOpen = NULL;
+static JImageClose_t JImageClose = NULL;
+static JImagePackageToModule_t JImagePackageToModule = NULL;
+static JImageFindResource_t JImageFindResource = NULL;
+static JImageGetResource_t JImageGetResource = NULL;
+static JImageResourceIterator_t JImageResourceIterator = NULL;
+static JImage_ResourcePath_t JImageResourcePath = NULL;
// Globals
@@ -233,6 +234,7 @@
strcpy(copy, zip_name);
_zip_name = copy;
_is_boot_append = is_boot_append;
+ _multi_versioned = _unknown;
}
ClassPathZipEntry::~ClassPathZipEntry() {
@@ -330,13 +332,20 @@
bool ClassPathZipEntry::is_multiple_versioned(TRAPS) {
assert(DumpSharedSpaces, "called only at dump time");
+ if (_multi_versioned != _unknown) {
+ return (_multi_versioned == _yes) ? true : false;
+ }
jint size;
- char* buffer = (char*)open_entry("META-INF/MANIFEST.MF", &size, false, CHECK_false);
+ char* buffer = (char*)open_entry("META-INF/MANIFEST.MF", &size, true, CHECK_false);
if (buffer != NULL) {
- if (strstr(buffer, "Multi-Release: true") != NULL) {
+ char* p = buffer;
+ for ( ; *p; ++p) *p = tolower(*p);
+ if (strstr(buffer, "multi-release: true") != NULL) {
+ _multi_versioned = _yes;
return true;
}
}
+ _multi_versioned = _no;
return false;
}
#endif // INCLUDE_CDS
@@ -917,6 +926,8 @@
guarantee(JImageGetResource != NULL, "function JIMAGE_GetResource not found");
JImageResourceIterator = CAST_TO_FN_PTR(JImageResourceIterator_t, os::dll_lookup(handle, "JIMAGE_ResourceIterator"));
guarantee(JImageResourceIterator != NULL, "function JIMAGE_ResourceIterator not found");
+ JImageResourcePath = CAST_TO_FN_PTR(JImage_ResourcePath_t, os::dll_lookup(handle, "JIMAGE_ResourcePath"));
+ guarantee(JImageResourcePath != NULL, "function JIMAGE_ResourcePath not found");
}
jboolean ClassLoader::decompress(void *in, u8 inSize, void *out, u8 outSize, char **pmsg) {
--- a/hotspot/src/share/vm/classfile/classLoader.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -101,10 +101,17 @@
class ClassPathZipEntry: public ClassPathEntry {
+ enum {
+ _unknown = 0,
+ _yes = 1,
+ _no = 2
+ };
private:
jzfile* _zip; // The zip archive
const char* _zip_name; // Name of zip archive
bool _is_boot_append; // entry coming from -Xbootclasspath/a
+ u1 _multi_versioned; // indicates if the jar file has multi-versioned entries.
+ // It can have value of "_unknown", "_yes", or "_no"
public:
bool is_jrt() { return false; }
bool is_jar_file() const { return true; }
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -373,13 +373,10 @@
// Lazily create the package entry table at first request.
if (_packages == NULL) {
MutexLockerEx m1(metaspace_lock(), Mutex::_no_safepoint_check_flag);
- // Check again if _packages has been allocated while we were getting this lock.
- if (_packages != NULL) {
- return _packages;
+ // Check if _packages got allocated while we were waiting for this lock.
+ if (_packages == NULL) {
+ _packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size);
}
- // Ensure _packages is stable, since it is examined without a lock
- OrderAccess::storestore();
- _packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size);
}
return _packages;
}
--- a/hotspot/src/share/vm/classfile/defaultMethods.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -860,10 +860,8 @@
m->set_constants(NULL); // This will get filled in later
m->set_name_index(cp->utf8(name));
m->set_signature_index(cp->utf8(sig));
-#ifdef CC_INTERP
ResultTypeFinder rtf(sig);
- m->set_result_index(rtf.type());
-#endif
+ m->constMethod()->set_result_type(rtf.type());
m->set_size_of_parameters(params);
m->set_max_stack(max_stack);
m->set_max_locals(params);
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -2187,43 +2187,19 @@
}
Method* java_lang_StackFrameInfo::get_method(Handle stackFrame, InstanceKlass* holder, TRAPS) {
- if (MemberNameInStackFrame) {
- Handle mname(THREAD, stackFrame->obj_field(_memberName_offset));
- Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mname());
- // we should expand MemberName::name when Throwable uses StackTrace
- // MethodHandles::expand_MemberName(mname, MethodHandles::_suppress_defc|MethodHandles::_suppress_type, CHECK_NULL);
- return method;
- } else {
- short mid = stackFrame->short_field(_mid_offset);
- short version = stackFrame->short_field(_version_offset);
- return holder->method_with_orig_idnum(mid, version);
- }
-}
-
-Symbol* java_lang_StackFrameInfo::get_file_name(Handle stackFrame, InstanceKlass* holder) {
- if (MemberNameInStackFrame) {
- return holder->source_file_name();
- } else {
- short version = stackFrame->short_field(_version_offset);
- return Backtrace::get_source_file_name(holder, version);
- }
+ Handle mname(THREAD, stackFrame->obj_field(_memberName_offset));
+ Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mname());
+ // we should expand MemberName::name when Throwable uses StackTrace
+ // MethodHandles::expand_MemberName(mname, MethodHandles::_suppress_defc|MethodHandles::_suppress_type, CHECK_NULL);
+ return method;
}
void java_lang_StackFrameInfo::set_method_and_bci(Handle stackFrame, const methodHandle& method, int bci) {
// set Method* or mid/cpref
- if (MemberNameInStackFrame) {
- oop mname = stackFrame->obj_field(_memberName_offset);
- InstanceKlass* ik = method->method_holder();
- CallInfo info(method(), ik);
- MethodHandles::init_method_MemberName(mname, info);
- } else {
- int mid = method->orig_method_idnum();
- int cpref = method->name_index();
- assert((jushort)mid == mid, "mid should be short");
- assert((jushort)cpref == cpref, "cpref should be short");
- java_lang_StackFrameInfo::set_mid(stackFrame(), (short)mid);
- java_lang_StackFrameInfo::set_cpref(stackFrame(), (short)cpref);
- }
+ oop mname = stackFrame->obj_field(_memberName_offset);
+ InstanceKlass* ik = method->method_holder();
+ CallInfo info(method(), ik);
+ MethodHandles::init_method_MemberName(mname, info);
// set bci
java_lang_StackFrameInfo::set_bci(stackFrame(), bci);
// method may be redefined; store the version
@@ -2232,52 +2208,23 @@
java_lang_StackFrameInfo::set_version(stackFrame(), (short)version);
}
-void java_lang_StackFrameInfo::fill_methodInfo(Handle stackFrame, TRAPS) {
+void java_lang_StackFrameInfo::to_stack_trace_element(Handle stackFrame, Handle stack_trace_element, TRAPS) {
ResourceMark rm(THREAD);
- oop k = stackFrame->obj_field(_declaringClass_offset);
- InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(k));
+ Handle k (THREAD, stackFrame->obj_field(_declaringClass_offset));
+ InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(k()));
Method* method = java_lang_StackFrameInfo::get_method(stackFrame, holder, CHECK);
- int bci = stackFrame->int_field(_bci_offset);
-
- // The method can be NULL if the requested class version is gone
- Symbol* sym = (method != NULL) ? method->name() : NULL;
- if (MemberNameInStackFrame) {
- assert(sym != NULL, "MemberName must have method name");
- } else {
- // The method can be NULL if the requested class version is gone
- if (sym == NULL) {
- short cpref = stackFrame->short_field(_cpref_offset);
- sym = holder->constants()->symbol_at(cpref);
- }
- }
-
- // set method name
- oop methodname = StringTable::intern(sym, CHECK);
- java_lang_StackFrameInfo::set_methodName(stackFrame(), methodname);
-
- // set file name and line number
- Symbol* source = get_file_name(stackFrame, holder);
- if (source != NULL) {
- oop filename = StringTable::intern(source, CHECK);
- java_lang_StackFrameInfo::set_fileName(stackFrame(), filename);
- }
-
- // if the method has been redefined, the bci is no longer applicable
+
short version = stackFrame->short_field(_version_offset);
- if (version_matches(method, version)) {
- int line_number = Backtrace::get_line_number(method, bci);
- java_lang_StackFrameInfo::set_lineNumber(stackFrame(), line_number);
- }
+ short bci = stackFrame->short_field(_bci_offset);
+ int cpref = method->name_index();
+ java_lang_StackTraceElement::fill_in(stack_trace_element, holder, method, version, bci, cpref, CHECK);
}
void java_lang_StackFrameInfo::compute_offsets() {
Klass* k = SystemDictionary::StackFrameInfo_klass();
compute_offset(_declaringClass_offset, k, vmSymbols::declaringClass_name(), vmSymbols::class_signature());
compute_offset(_memberName_offset, k, vmSymbols::memberName_name(), vmSymbols::object_signature());
- compute_offset(_bci_offset, k, vmSymbols::bci_name(), vmSymbols::int_signature());
- compute_offset(_methodName_offset, k, vmSymbols::methodName_name(), vmSymbols::string_signature());
- compute_offset(_fileName_offset, k, vmSymbols::fileName_name(), vmSymbols::string_signature());
- compute_offset(_lineNumber_offset, k, vmSymbols::lineNumber_name(), vmSymbols::int_signature());
+ compute_offset(_bci_offset, k, vmSymbols::bci_name(), vmSymbols::short_signature());
STACKFRAMEINFO_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
}
@@ -3690,12 +3637,7 @@
int java_lang_StackFrameInfo::_declaringClass_offset;
int java_lang_StackFrameInfo::_memberName_offset;
int java_lang_StackFrameInfo::_bci_offset;
-int java_lang_StackFrameInfo::_methodName_offset;
-int java_lang_StackFrameInfo::_fileName_offset;
-int java_lang_StackFrameInfo::_lineNumber_offset;
-int java_lang_StackFrameInfo::_mid_offset;
int java_lang_StackFrameInfo::_version_offset;
-int java_lang_StackFrameInfo::_cpref_offset;
int java_lang_LiveStackFrameInfo::_monitors_offset;
int java_lang_LiveStackFrameInfo::_locals_offset;
int java_lang_LiveStackFrameInfo::_operands_offset;
@@ -3741,34 +3683,14 @@
element->obj_field_put(_declaringClass_offset, value);
}
-void java_lang_StackFrameInfo::set_mid(oop element, short value) {
- element->short_field_put(_mid_offset, value);
-}
-
void java_lang_StackFrameInfo::set_version(oop element, short value) {
element->short_field_put(_version_offset, value);
}
-void java_lang_StackFrameInfo::set_cpref(oop element, short value) {
- element->short_field_put(_cpref_offset, value);
-}
-
void java_lang_StackFrameInfo::set_bci(oop element, int value) {
element->int_field_put(_bci_offset, value);
}
-void java_lang_StackFrameInfo::set_fileName(oop element, oop value) {
- element->obj_field_put(_fileName_offset, value);
-}
-
-void java_lang_StackFrameInfo::set_methodName(oop element, oop value) {
- element->obj_field_put(_methodName_offset, value);
-}
-
-void java_lang_StackFrameInfo::set_lineNumber(oop element, int value) {
- element->int_field_put(_lineNumber_offset, value);
-}
-
void java_lang_LiveStackFrameInfo::set_monitors(oop element, oop value) {
element->obj_field_put(_monitors_offset, value);
}
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -1364,25 +1364,16 @@
// Interface to java.lang.StackFrameInfo objects
#define STACKFRAMEINFO_INJECTED_FIELDS(macro) \
- macro(java_lang_StackFrameInfo, mid, short_signature, false) \
- macro(java_lang_StackFrameInfo, version, short_signature, false) \
- macro(java_lang_StackFrameInfo, cpref, short_signature, false)
+ macro(java_lang_StackFrameInfo, version, short_signature, false)
class java_lang_StackFrameInfo: AllStatic {
private:
static int _declaringClass_offset;
static int _memberName_offset;
static int _bci_offset;
- static int _methodName_offset;
- static int _fileName_offset;
- static int _lineNumber_offset;
-
- static int _mid_offset;
static int _version_offset;
- static int _cpref_offset;
static Method* get_method(Handle stackFrame, InstanceKlass* holder, TRAPS);
- static Symbol* get_file_name(Handle stackFrame, InstanceKlass* holder);
public:
// Setters
@@ -1390,19 +1381,12 @@
static void set_method_and_bci(Handle stackFrame, const methodHandle& method, int bci);
static void set_bci(oop info, int value);
- // set method info in an instance of StackFrameInfo
- static void fill_methodInfo(Handle info, TRAPS);
- static void set_methodName(oop info, oop value);
- static void set_fileName(oop info, oop value);
- static void set_lineNumber(oop info, int value);
-
- // these injected fields are only used if -XX:-MemberNameInStackFrame set
- static void set_mid(oop info, short value);
static void set_version(oop info, short value);
- static void set_cpref(oop info, short value);
static void compute_offsets();
+ static void to_stack_trace_element(Handle stackFrame, Handle stack_trace_element, TRAPS);
+
// Debugging
friend class JavaClasses;
};
--- a/hotspot/src/share/vm/classfile/javaClasses.inline.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.inline.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -222,20 +222,17 @@
return line_number;
}
-/*
- * Returns the source file name of a given InstanceKlass and version
- */
inline Symbol* Backtrace::get_source_file_name(InstanceKlass* holder, int version) {
- // Find the specific ik version that contains this source_file_name_index
- // via the previous versions list, but use the current version's
- // constant pool to look it up. The previous version's index has been
- // merged for the current constant pool.
- InstanceKlass* ik = holder->get_klass_version(version);
- // This version has been cleaned up.
- if (ik == NULL) return NULL;
- int source_file_name_index = ik->source_file_name_index();
- return (source_file_name_index == 0) ?
- (Symbol*)NULL : holder->constants()->symbol_at(source_file_name_index);
+ // RedefineClasses() currently permits redefine operations to
+ // happen in parallel using a "last one wins" philosophy. That
+ // spec laxness allows the constant pool entry associated with
+ // the source_file_name_index for any older constant pool version
+ // to be unstable so we shouldn't try to use it.
+ if (holder->constants()->version() != version) {
+ return NULL;
+ } else {
+ return holder->source_file_name();
+ }
}
#endif // SHARE_VM_CLASSFILE_JAVACLASSES_INLINE_HPP
--- a/hotspot/src/share/vm/classfile/jimage.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/jimage.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -30,7 +30,7 @@
typedef jlong JImageLocationRef;
// Max path length limit independent of platform. Windows max path is 1024,
-// other platforms use 4096. The JCK fails several tests when 1024 is used.
+// other platforms use 4096.
#define JIMAGE_MAX_PATH 4096
// JImage Error Codes
@@ -113,7 +113,8 @@
*
* Ex.
* jlong size;
- * JImageLocationRef location = (*JImageFindResource)(image, "java.base", "9.0", "java/lang/String.class", &size);
+ * JImageLocationRef location = (*JImageFindResource)(image,
+ * "java.base", "9.0", "java/lang/String.class", &size);
*/
extern "C" JImageLocationRef JIMAGE_FindResource(JImageFile* jimage,
const char* module_name, const char* version, const char* name,
@@ -134,7 +135,8 @@
*
* Ex.
* jlong size;
- * JImageLocationRef location = (*JImageFindResource)(image, "java.base", "9.0", "java/lang/String.class", &size);
+ * JImageLocationRef location = (*JImageFindResource)(image,
+ * "java.base", "9.0", "java/lang/String.class", &size);
* char* buffer = new char[size];
* (*JImageGetResource)(image, location, buffer, size);
*/
@@ -154,7 +156,8 @@
* required. All strings are utf-8, zero byte terminated.file.
*
* Ex.
- * bool ctw_visitor(JImageFile* jimage, const char* module_name, const char* version, const char* package, const char* name, const char* extension, void* arg) {
+ * bool ctw_visitor(JImageFile* jimage, const char* module_name, const char* version,
+ * const char* package, const char* name, const char* extension, void* arg) {
* if (strcmp(extension, “class”) == 0) {
* char path[JIMAGE_MAX_PATH];
* Thread* THREAD = Thread::current();
@@ -176,3 +179,20 @@
typedef void (*JImageResourceIterator_t)(JImageFile* jimage,
JImageResourceVisitor_t visitor, void* arg);
+
+/*
+ * JIMAGE_ResourcePath- Given an open image file, a location reference, a buffer
+ * and a maximum buffer size, copy the path of the resource into the buffer.
+ * Returns false if not a valid location reference.
+ *
+ * Ex.
+ * JImageLocationRef location = ...
+ * char path[JIMAGE_MAX_PATH];
+ * (*JImageResourcePath)(image, location, path, JIMAGE_MAX_PATH);
+ */
+extern "C" bool JIMAGE_ResourcePath(JImageFile* image, JImageLocationRef locationRef,
+ char* path, size_t max);
+
+typedef bool (*JImage_ResourcePath_t)(JImageFile* jimage, JImageLocationRef location,
+ char* buffer, jlong size);
+
--- a/hotspot/src/share/vm/classfile/moduleEntry.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/moduleEntry.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -36,6 +36,7 @@
#include "utilities/events.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/hashtable.inline.hpp"
+#include "utilities/ostream.hpp"
ModuleEntry* ModuleEntryTable::_javabase_module = NULL;
@@ -359,31 +360,29 @@
java_lang_Class::set_fixup_module_field_list(NULL);
}
-#ifndef PRODUCT
-void ModuleEntryTable::print() {
- tty->print_cr("Module Entry Table (table_size=%d, entries=%d)",
- table_size(), number_of_entries());
+void ModuleEntryTable::print(outputStream* st) {
+ st->print_cr("Module Entry Table (table_size=%d, entries=%d)",
+ table_size(), number_of_entries());
for (int i = 0; i < table_size(); i++) {
for (ModuleEntry* probe = bucket(i);
probe != NULL;
probe = probe->next()) {
- probe->print();
+ probe->print(st);
}
}
}
-void ModuleEntry::print() {
+void ModuleEntry::print(outputStream* st) {
ResourceMark rm;
- tty->print_cr("entry "PTR_FORMAT" name %s module "PTR_FORMAT" loader %s version %s location %s strict %s next "PTR_FORMAT,
- p2i(this),
- name() == NULL ? UNNAMED_MODULE : name()->as_C_string(),
- p2i(module()),
- loader()->loader_name(),
- version() != NULL ? version()->as_C_string() : "NULL",
- location() != NULL ? location()->as_C_string() : "NULL",
- BOOL_TO_STR(!can_read_all_unnamed()), p2i(next()));
+ st->print_cr("entry "PTR_FORMAT" name %s module "PTR_FORMAT" loader %s version %s location %s strict %s next "PTR_FORMAT,
+ p2i(this),
+ name() == NULL ? UNNAMED_MODULE : name()->as_C_string(),
+ p2i(module()),
+ loader()->loader_name(),
+ version() != NULL ? version()->as_C_string() : "NULL",
+ location() != NULL ? location()->as_C_string() : "NULL",
+ BOOL_TO_STR(!can_read_all_unnamed()), p2i(next()));
}
-#endif
void ModuleEntryTable::verify() {
int element_count = 0;
--- a/hotspot/src/share/vm/classfile/moduleEntry.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/moduleEntry.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -33,6 +33,7 @@
#include "trace/traceMacros.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/hashtable.hpp"
+#include "utilities/ostream.hpp"
#define UNNAMED_MODULE "Unnamed Module"
@@ -141,7 +142,7 @@
void purge_reads();
void delete_reads();
- void print() PRODUCT_RETURN;
+ void print(outputStream* st = tty);
void verify();
};
@@ -223,7 +224,7 @@
static void finalize_javabase(Handle module_handle, Symbol* version, Symbol* location);
static void patch_javabase_entries(Handle module_handle);
- void print() PRODUCT_RETURN;
+ void print(outputStream* st = tty);
void verify();
};
--- a/hotspot/src/share/vm/classfile/packageEntry.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/packageEntry.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -32,6 +32,7 @@
#include "utilities/events.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/hashtable.inline.hpp"
+#include "utilities/ostream.hpp"
// Return true if this package is exported to m.
bool PackageEntry::is_qexported_to(ModuleEntry* m) const {
@@ -265,28 +266,26 @@
}
}
-#ifndef PRODUCT
-void PackageEntryTable::print() {
- tty->print_cr("Package Entry Table (table_size=%d, entries=%d)",
- table_size(), number_of_entries());
+void PackageEntryTable::print(outputStream* st) {
+ st->print_cr("Package Entry Table (table_size=%d, entries=%d)",
+ table_size(), number_of_entries());
for (int i = 0; i < table_size(); i++) {
for (PackageEntry* probe = bucket(i);
probe != NULL;
probe = probe->next()) {
- probe->print();
+ probe->print(st);
}
}
}
-void PackageEntry::print() {
+void PackageEntry::print(outputStream* st) {
ResourceMark rm;
- tty->print_cr("package entry "PTR_FORMAT" name %s module %s classpath_index "
- INT32_FORMAT " is_exported %d is_exported_allUnnamed %d " "next "PTR_FORMAT,
- p2i(this), name()->as_C_string(),
- (module()->is_named() ? module()->name()->as_C_string() : UNNAMED_MODULE),
- _classpath_index, _is_exported, _is_exported_allUnnamed, p2i(next()));
+ st->print_cr("package entry "PTR_FORMAT" name %s module %s classpath_index "
+ INT32_FORMAT " is_exported %d is_exported_allUnnamed %d " "next "PTR_FORMAT,
+ p2i(this), name()->as_C_string(),
+ (module()->is_named() ? module()->name()->as_C_string() : UNNAMED_MODULE),
+ _classpath_index, _is_exported, _is_exported_allUnnamed, p2i(next()));
}
-#endif
void PackageEntryTable::verify() {
int element_count = 0;
--- a/hotspot/src/share/vm/classfile/packageEntry.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/packageEntry.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -29,6 +29,7 @@
#include "oops/symbol.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/hashtable.hpp"
+#include "utilities/ostream.hpp"
// A PackageEntry basically represents a Java package. It contains:
// - Symbol* containing the package's name.
@@ -144,7 +145,7 @@
void purge_qualified_exports();
void delete_qualified_exports();
- void print() PRODUCT_RETURN;
+ void print(outputStream* st = tty);
void verify();
};
@@ -195,7 +196,7 @@
// purge dead weak references out of exported list
void purge_all_package_exports();
- void print() PRODUCT_RETURN;
+ void print(outputStream* st = tty);
void verify();
};
--- a/hotspot/src/share/vm/code/relocInfo.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/code/relocInfo.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -26,8 +26,9 @@
#define SHARE_VM_CODE_RELOCINFO_HPP
#include "memory/allocation.hpp"
-#include "utilities/top.hpp"
+#include "runtime/os.hpp"
+class Metadata;
class NativeMovConstReg;
// Types in this file:
--- a/hotspot/src/share/vm/code/vmreg.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/code/vmreg.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -28,10 +28,9 @@
#include "asm/register.hpp"
#include "memory/allocation.hpp"
#include "utilities/globalDefinitions.hpp"
-
+#include "utilities/ostream.hpp"
#ifdef COMPILER2
#include "opto/adlcVMDeps.hpp"
-#include "utilities/ostream.hpp"
#endif
//------------------------------VMReg------------------------------------------
--- a/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -32,6 +32,7 @@
#include "gc/shared/genCollectedHeap.hpp"
#include "gc/shared/space.inline.hpp"
#include "gc/shared/spaceDecorator.hpp"
+#include "logging/logStream.inline.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.inline.hpp"
@@ -505,10 +506,13 @@
return;
}
log.debug("%s", title);
- _dictionary->report_statistics(log.debug_stream());
+
+ LogStream out(log.debug());
+ _dictionary->report_statistics(&out);
+
if (log.is_trace()) {
- ResourceMark rm;
- reportIndexedFreeListStatistics(log.trace_stream());
+ LogStream trace_out(log.trace());
+ reportIndexedFreeListStatistics(&trace_out);
size_t total_size = totalSizeInIndexedFreeLists() +
_dictionary->total_chunk_size(DEBUG_ONLY(freelistLock()));
log.trace(" free=" SIZE_FORMAT " frag=%1.4f", total_size, flsFrag());
@@ -2836,6 +2840,11 @@
par_get_chunk_of_blocks_dictionary(word_sz, n, fl);
}
+const size_t CompactibleFreeListSpace::max_flag_size_for_task_size() const {
+ const size_t ergo_max = _old_gen->reserved().word_size() / (CardTableModRefBS::card_size_in_words * BitsPerWord);
+ return ergo_max;
+}
+
// Set up the space's par_seq_tasks structure for work claiming
// for parallel rescan. See CMSParRemarkTask where this is currently used.
// XXX Need to suitably abstract and generalize this and the next
--- a/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -82,6 +82,8 @@
template <typename SpaceType>
friend void CompactibleSpace::scan_and_compact(SpaceType* space);
template <typename SpaceType>
+ friend void CompactibleSpace::verify_up_to_first_dead(SpaceType* space);
+ template <typename SpaceType>
friend void CompactibleSpace::scan_and_forward(SpaceType* space, CompactPoint* cp);
// "Size" of chunks of work (executed during parallel remark phases
@@ -345,6 +347,8 @@
// Support for parallelization of rescan and marking.
const size_t rescan_task_size() const { return _rescan_task_size; }
const size_t marking_task_size() const { return _marking_task_size; }
+ // Return ergonomic max size for CMSRescanMultiple and CMSConcMarkMultiple.
+ const size_t max_flag_size_for_task_size() const;
SequentialSubTasksDone* conc_par_seq_tasks() {return &_conc_par_seq_tasks; }
void initialize_sequential_subtasks_for_rescan(int n_threads);
void initialize_sequential_subtasks_for_marking(int n_threads,
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -425,7 +425,7 @@
st->print(",cms_consumption_rate=%g,time_until_full=%g",
cms_consumption_rate(), time_until_cms_gen_full());
}
- st->print(" ");
+ st->cr();
}
#endif // #ifndef PRODUCT
@@ -1108,8 +1108,10 @@
}
bool CMSCollector::shouldConcurrentCollect() {
+ LogTarget(Trace, gc) log;
+
if (_full_gc_requested) {
- log_trace(gc)("CMSCollector: collect because of explicit gc request (or GCLocker)");
+ log.print("CMSCollector: collect because of explicit gc request (or GCLocker)");
return true;
}
@@ -1117,21 +1119,22 @@
// ------------------------------------------------------------------
// Print out lots of information which affects the initiation of
// a collection.
- Log(gc) log;
- if (log.is_trace() && stats().valid()) {
- log.trace("CMSCollector shouldConcurrentCollect: ");
- ResourceMark rm;
- stats().print_on(log.debug_stream());
- log.trace("time_until_cms_gen_full %3.7f", stats().time_until_cms_gen_full());
- log.trace("free=" SIZE_FORMAT, _cmsGen->free());
- log.trace("contiguous_available=" SIZE_FORMAT, _cmsGen->contiguous_available());
- log.trace("promotion_rate=%g", stats().promotion_rate());
- log.trace("cms_allocation_rate=%g", stats().cms_allocation_rate());
- log.trace("occupancy=%3.7f", _cmsGen->occupancy());
- log.trace("initiatingOccupancy=%3.7f", _cmsGen->initiating_occupancy());
- log.trace("cms_time_since_begin=%3.7f", stats().cms_time_since_begin());
- log.trace("cms_time_since_end=%3.7f", stats().cms_time_since_end());
- log.trace("metadata initialized %d", MetaspaceGC::should_concurrent_collect());
+ if (log.is_enabled() && stats().valid()) {
+ log.print("CMSCollector shouldConcurrentCollect: ");
+
+ LogStream out(log);
+ stats().print_on(&out);
+
+ log.print("time_until_cms_gen_full %3.7f", stats().time_until_cms_gen_full());
+ log.print("free=" SIZE_FORMAT, _cmsGen->free());
+ log.print("contiguous_available=" SIZE_FORMAT, _cmsGen->contiguous_available());
+ log.print("promotion_rate=%g", stats().promotion_rate());
+ log.print("cms_allocation_rate=%g", stats().cms_allocation_rate());
+ log.print("occupancy=%3.7f", _cmsGen->occupancy());
+ log.print("initiatingOccupancy=%3.7f", _cmsGen->initiating_occupancy());
+ log.print("cms_time_since_begin=%3.7f", stats().cms_time_since_begin());
+ log.print("cms_time_since_end=%3.7f", stats().cms_time_since_end());
+ log.print("metadata initialized %d", MetaspaceGC::should_concurrent_collect());
}
// ------------------------------------------------------------------
@@ -1149,8 +1152,8 @@
// this branch will not fire after the first successful CMS
// collection because the stats should then be valid.
if (_cmsGen->occupancy() >= _bootstrap_occupancy) {
- log_trace(gc)(" CMSCollector: collect for bootstrapping statistics: occupancy = %f, boot occupancy = %f",
- _cmsGen->occupancy(), _bootstrap_occupancy);
+ log.print(" CMSCollector: collect for bootstrapping statistics: occupancy = %f, boot occupancy = %f",
+ _cmsGen->occupancy(), _bootstrap_occupancy);
return true;
}
}
@@ -1162,7 +1165,7 @@
// XXX We need to make sure that the gen expansion
// criterion dovetails well with this. XXX NEED TO FIX THIS
if (_cmsGen->should_concurrent_collect()) {
- log_trace(gc)("CMS old gen initiated");
+ log.print("CMS old gen initiated");
return true;
}
@@ -1173,12 +1176,12 @@
assert(gch->collector_policy()->is_generation_policy(),
"You may want to check the correctness of the following");
if (gch->incremental_collection_will_fail(true /* consult_young */)) {
- log_trace(gc)("CMSCollector: collect because incremental collection will fail ");
+ log.print("CMSCollector: collect because incremental collection will fail ");
return true;
}
if (MetaspaceGC::should_concurrent_collect()) {
- log_trace(gc)("CMSCollector: collect for metadata allocation ");
+ log.print("CMSCollector: collect for metadata allocation ");
return true;
}
@@ -1193,10 +1196,10 @@
// as we want to be able to trigger the first CMS cycle as well)
if (stats().cms_time_since_begin() >= (CMSTriggerInterval / ((double) MILLIUNITS))) {
if (stats().valid()) {
- log_trace(gc)("CMSCollector: collect because of trigger interval (time since last begin %3.7f secs)",
- stats().cms_time_since_begin());
+ log.print("CMSCollector: collect because of trigger interval (time since last begin %3.7f secs)",
+ stats().cms_time_since_begin());
} else {
- log_trace(gc)("CMSCollector: collect because of trigger interval (first collection)");
+ log.print("CMSCollector: collect because of trigger interval (first collection)");
}
return true;
}
@@ -3598,7 +3601,7 @@
size_t capacity = get_eden_capacity();
// Don't start sampling unless we will get sufficiently
// many samples.
- if (used < (capacity/(CMSScheduleRemarkSamplingRatio * 100)
+ if (used < (((capacity / CMSScheduleRemarkSamplingRatio) / 100)
* CMSScheduleRemarkEdenPenetration)) {
_start_sampling = true;
} else {
--- a/hotspot/src/share/vm/gc/g1/concurrentG1Refine.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1Refine.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -29,42 +29,174 @@
#include "gc/g1/g1HotCardCache.hpp"
#include "gc/g1/g1Predictions.hpp"
#include "runtime/java.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/pair.hpp"
+#include <math.h>
-ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h, const G1Predictions* predictor) :
+// Arbitrary but large limits, to simplify some of the zone calculations.
+// The general idea is to allow expressions like
+// MIN2(x OP y, max_XXX_zone)
+// without needing to check for overflow in "x OP y", because the
+// ranges for x and y have been restricted.
+STATIC_ASSERT(sizeof(LP64_ONLY(jint) NOT_LP64(jshort)) <= (sizeof(size_t)/2));
+const size_t max_yellow_zone = LP64_ONLY(max_jint) NOT_LP64(max_jshort);
+const size_t max_green_zone = max_yellow_zone / 2;
+const size_t max_red_zone = INT_MAX; // For dcqs.set_max_completed_queue.
+STATIC_ASSERT(max_yellow_zone <= max_red_zone);
+
+// Range check assertions for green zone values.
+#define assert_zone_constraints_g(green) \
+ do { \
+ size_t azc_g_green = (green); \
+ assert(azc_g_green <= max_green_zone, \
+ "green exceeds max: " SIZE_FORMAT, azc_g_green); \
+ } while (0)
+
+// Range check assertions for green and yellow zone values.
+#define assert_zone_constraints_gy(green, yellow) \
+ do { \
+ size_t azc_gy_green = (green); \
+ size_t azc_gy_yellow = (yellow); \
+ assert_zone_constraints_g(azc_gy_green); \
+ assert(azc_gy_yellow <= max_yellow_zone, \
+ "yellow exceeds max: " SIZE_FORMAT, azc_gy_yellow); \
+ assert(azc_gy_green <= azc_gy_yellow, \
+ "green (" SIZE_FORMAT ") exceeds yellow (" SIZE_FORMAT ")", \
+ azc_gy_green, azc_gy_yellow); \
+ } while (0)
+
+// Range check assertions for green, yellow, and red zone values.
+#define assert_zone_constraints_gyr(green, yellow, red) \
+ do { \
+ size_t azc_gyr_green = (green); \
+ size_t azc_gyr_yellow = (yellow); \
+ size_t azc_gyr_red = (red); \
+ assert_zone_constraints_gy(azc_gyr_green, azc_gyr_yellow); \
+ assert(azc_gyr_red <= max_red_zone, \
+ "red exceeds max: " SIZE_FORMAT, azc_gyr_red); \
+ assert(azc_gyr_yellow <= azc_gyr_red, \
+ "yellow (" SIZE_FORMAT ") exceeds red (" SIZE_FORMAT ")", \
+ azc_gyr_yellow, azc_gyr_red); \
+ } while (0)
+
+// Logging tag sequence for refinement control updates.
+#define CTRL_TAGS gc, ergo, refine
+
+// For logging zone values, ensuring consistency of level and tags.
+#define LOG_ZONES(...) log_debug( CTRL_TAGS )(__VA_ARGS__)
+
+// Package for pair of refinement thread activation and deactivation
+// thresholds. The activation and deactivation levels are resp. the first
+// and second values of the pair.
+typedef Pair<size_t, size_t> Thresholds;
+inline size_t activation_level(const Thresholds& t) { return t.first; }
+inline size_t deactivation_level(const Thresholds& t) { return t.second; }
+
+static Thresholds calc_thresholds(size_t green_zone,
+ size_t yellow_zone,
+ uint worker_i) {
+ double yellow_size = yellow_zone - green_zone;
+ double step = yellow_size / ConcurrentG1Refine::thread_num();
+ if (worker_i == 0) {
+ // Potentially activate worker 0 more aggressively, to keep
+ // available buffers near green_zone value. When yellow_size is
+ // large we don't want to allow a full step to accumulate before
+ // doing any processing, as that might lead to significantly more
+ // than green_zone buffers to be processed by update_rs.
+ step = MIN2(step, ParallelGCThreads / 2.0);
+ }
+ size_t activate_offset = static_cast<size_t>(ceil(step * (worker_i + 1)));
+ size_t deactivate_offset = static_cast<size_t>(floor(step * worker_i));
+ return Thresholds(green_zone + activate_offset,
+ green_zone + deactivate_offset);
+}
+
+ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h,
+ size_t green_zone,
+ size_t yellow_zone,
+ size_t red_zone,
+ size_t min_yellow_zone_size) :
_threads(NULL),
_sample_thread(NULL),
- _predictor_sigma(predictor->sigma()),
+ _n_worker_threads(thread_num()),
+ _green_zone(green_zone),
+ _yellow_zone(yellow_zone),
+ _red_zone(red_zone),
+ _min_yellow_zone_size(min_yellow_zone_size),
_hot_card_cache(g1h)
{
- // Ergonomically select initial concurrent refinement parameters
- if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) {
- FLAG_SET_DEFAULT(G1ConcRefinementGreenZone, ParallelGCThreads);
- }
- set_green_zone(G1ConcRefinementGreenZone);
+ assert_zone_constraints_gyr(green_zone, yellow_zone, red_zone);
+}
- if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) {
- FLAG_SET_DEFAULT(G1ConcRefinementYellowZone, green_zone() * 3);
+static size_t calc_min_yellow_zone_size() {
+ size_t step = G1ConcRefinementThresholdStep;
+ uint n_workers = ConcurrentG1Refine::thread_num();
+ if ((max_yellow_zone / step) < n_workers) {
+ return max_yellow_zone;
+ } else {
+ return step * n_workers;
}
- set_yellow_zone(MAX2(G1ConcRefinementYellowZone, green_zone()));
+}
- if (FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) {
- FLAG_SET_DEFAULT(G1ConcRefinementRedZone, yellow_zone() * 2);
+static size_t calc_init_green_zone() {
+ size_t green = G1ConcRefinementGreenZone;
+ if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) {
+ green = ParallelGCThreads;
}
- set_red_zone(MAX2(G1ConcRefinementRedZone, yellow_zone()));
-
+ return MIN2(green, max_green_zone);
}
-ConcurrentG1Refine* ConcurrentG1Refine::create(G1CollectedHeap* g1h, CardTableEntryClosure* refine_closure, jint* ecode) {
- G1CollectorPolicy* policy = g1h->g1_policy();
- ConcurrentG1Refine* cg1r = new ConcurrentG1Refine(g1h, &policy->predictor());
+static size_t calc_init_yellow_zone(size_t green, size_t min_size) {
+ size_t config = G1ConcRefinementYellowZone;
+ size_t size = 0;
+ if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) {
+ size = green * 2;
+ } else if (green < config) {
+ size = config - green;
+ }
+ size = MAX2(size, min_size);
+ size = MIN2(size, max_yellow_zone);
+ return MIN2(green + size, max_yellow_zone);
+}
+
+static size_t calc_init_red_zone(size_t green, size_t yellow) {
+ size_t size = yellow - green;
+ if (!FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) {
+ size_t config = G1ConcRefinementRedZone;
+ if (yellow < config) {
+ size = MAX2(size, config - yellow);
+ }
+ }
+ return MIN2(yellow + size, max_red_zone);
+}
+
+ConcurrentG1Refine* ConcurrentG1Refine::create(G1CollectedHeap* g1h,
+ CardTableEntryClosure* refine_closure,
+ jint* ecode) {
+ size_t min_yellow_zone_size = calc_min_yellow_zone_size();
+ size_t green_zone = calc_init_green_zone();
+ size_t yellow_zone = calc_init_yellow_zone(green_zone, min_yellow_zone_size);
+ size_t red_zone = calc_init_red_zone(green_zone, yellow_zone);
+
+ LOG_ZONES("Initial Refinement Zones: "
+ "green: " SIZE_FORMAT ", "
+ "yellow: " SIZE_FORMAT ", "
+ "red: " SIZE_FORMAT ", "
+ "min yellow size: " SIZE_FORMAT,
+ green_zone, yellow_zone, red_zone, min_yellow_zone_size);
+
+ ConcurrentG1Refine* cg1r = new ConcurrentG1Refine(g1h,
+ green_zone,
+ yellow_zone,
+ red_zone,
+ min_yellow_zone_size);
+
if (cg1r == NULL) {
*ecode = JNI_ENOMEM;
vm_shutdown_during_initialization("Could not create ConcurrentG1Refine");
return NULL;
}
- cg1r->_n_worker_threads = thread_num();
-
- cg1r->reset_threshold_step();
cg1r->_threads = NEW_C_HEAP_ARRAY_RETURN_NULL(ConcurrentG1RefineThread*, cg1r->_n_worker_threads, mtGC);
if (cg1r->_threads == NULL) {
@@ -77,7 +209,15 @@
ConcurrentG1RefineThread *next = NULL;
for (uint i = cg1r->_n_worker_threads - 1; i != UINT_MAX; i--) {
- ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(cg1r, next, refine_closure, worker_id_offset, i);
+ Thresholds thresholds = calc_thresholds(green_zone, yellow_zone, i);
+ ConcurrentG1RefineThread* t =
+ new ConcurrentG1RefineThread(cg1r,
+ next,
+ refine_closure,
+ worker_id_offset,
+ i,
+ activation_level(thresholds),
+ deactivation_level(thresholds));
assert(t != NULL, "Conc refine should have been created");
if (t->osthread() == NULL) {
*ecode = JNI_ENOMEM;
@@ -101,14 +241,6 @@
return cg1r;
}
-void ConcurrentG1Refine::reset_threshold_step() {
- if (FLAG_IS_DEFAULT(G1ConcRefinementThresholdStep)) {
- _thread_threshold_step = (yellow_zone() - green_zone()) / (worker_thread_num() + 1);
- } else {
- _thread_threshold_step = G1ConcRefinementThresholdStep;
- }
-}
-
void ConcurrentG1Refine::init(G1RegionToSpaceMapper* card_counts_storage) {
_hot_card_cache.initialize(card_counts_storage);
}
@@ -120,10 +252,11 @@
_sample_thread->stop();
}
-void ConcurrentG1Refine::reinitialize_threads() {
- reset_threshold_step();
+void ConcurrentG1Refine::update_thread_thresholds() {
for (uint i = 0; i < _n_worker_threads; i++) {
- _threads[i]->initialize();
+ Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, i);
+ _threads[i]->update_thresholds(activation_level(thresholds),
+ deactivation_level(thresholds));
}
}
@@ -142,7 +275,7 @@
}
void ConcurrentG1Refine::worker_threads_do(ThreadClosure * tc) {
- for (uint i = 0; i < worker_thread_num(); i++) {
+ for (uint i = 0; i < _n_worker_threads; i++) {
tc->do_thread(_threads[i]);
}
}
@@ -160,34 +293,80 @@
st->cr();
}
+static size_t calc_new_green_zone(size_t green,
+ double update_rs_time,
+ size_t update_rs_processed_buffers,
+ double goal_ms) {
+ // Adjust green zone based on whether we're meeting the time goal.
+ // Limit to max_green_zone.
+ const double inc_k = 1.1, dec_k = 0.9;
+ if (update_rs_time > goal_ms) {
+ if (green > 0) {
+ green = static_cast<size_t>(green * dec_k);
+ }
+ } else if (update_rs_time < goal_ms &&
+ update_rs_processed_buffers > green) {
+ green = static_cast<size_t>(MAX2(green * inc_k, green + 1.0));
+ green = MIN2(green, max_green_zone);
+ }
+ return green;
+}
+
+static size_t calc_new_yellow_zone(size_t green, size_t min_yellow_size) {
+ size_t size = green * 2;
+ size = MAX2(size, min_yellow_size);
+ return MIN2(green + size, max_yellow_zone);
+}
+
+static size_t calc_new_red_zone(size_t green, size_t yellow) {
+ return MIN2(yellow + (yellow - green), max_red_zone);
+}
+
+void ConcurrentG1Refine::update_zones(double update_rs_time,
+ size_t update_rs_processed_buffers,
+ double goal_ms) {
+ log_trace( CTRL_TAGS )("Updating Refinement Zones: "
+ "update_rs time: %.3fms, "
+ "update_rs buffers: " SIZE_FORMAT ", "
+ "update_rs goal time: %.3fms",
+ update_rs_time,
+ update_rs_processed_buffers,
+ goal_ms);
+
+ _green_zone = calc_new_green_zone(_green_zone,
+ update_rs_time,
+ update_rs_processed_buffers,
+ goal_ms);
+ _yellow_zone = calc_new_yellow_zone(_green_zone, _min_yellow_zone_size);
+ _red_zone = calc_new_red_zone(_green_zone, _yellow_zone);
+
+ assert_zone_constraints_gyr(_green_zone, _yellow_zone, _red_zone);
+ LOG_ZONES("Updated Refinement Zones: "
+ "green: " SIZE_FORMAT ", "
+ "yellow: " SIZE_FORMAT ", "
+ "red: " SIZE_FORMAT,
+ _green_zone, _yellow_zone, _red_zone);
+}
+
void ConcurrentG1Refine::adjust(double update_rs_time,
- double update_rs_processed_buffers,
+ size_t update_rs_processed_buffers,
double goal_ms) {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
if (G1UseAdaptiveConcRefinement) {
- const int k_gy = 3, k_gr = 6;
- const double inc_k = 1.1, dec_k = 0.9;
+ update_zones(update_rs_time, update_rs_processed_buffers, goal_ms);
+ update_thread_thresholds();
- size_t g = green_zone();
- if (update_rs_time > goal_ms) {
- g = (size_t)(g * dec_k); // Can become 0, that's OK. That would mean a mutator-only processing.
+ // Change the barrier params
+ if (_n_worker_threads == 0) {
+ // Disable dcqs notification when there are no threads to notify.
+ dcqs.set_process_completed_threshold(INT_MAX);
} else {
- if (update_rs_time < goal_ms && update_rs_processed_buffers > g) {
- g = (size_t)MAX2(g * inc_k, g + 1.0);
- }
+ // Worker 0 is the primary; wakeup is via dcqs notification.
+ STATIC_ASSERT(max_yellow_zone <= INT_MAX);
+ size_t activate = _threads[0]->activation_threshold();
+ dcqs.set_process_completed_threshold((int)activate);
}
- // Change the refinement threads params
- set_green_zone(g);
- set_yellow_zone(g * k_gy);
- set_red_zone(g * k_gr);
- reinitialize_threads();
-
- size_t processing_threshold_delta = MAX2<size_t>(green_zone() * _predictor_sigma, 1);
- size_t processing_threshold = MIN2(green_zone() + processing_threshold_delta,
- yellow_zone());
- // Change the barrier params
- dcqs.set_process_completed_threshold((int)processing_threshold);
dcqs.set_max_completed_queue((int)red_zone());
}
--- a/hotspot/src/share/vm/gc/g1/concurrentG1Refine.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1Refine.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -65,18 +65,24 @@
size_t _green_zone;
size_t _yellow_zone;
size_t _red_zone;
-
- size_t _thread_threshold_step;
-
- double _predictor_sigma;
+ size_t _min_yellow_zone_size;
// We delay the refinement of 'hot' cards using the hot card cache.
G1HotCardCache _hot_card_cache;
- // Reset the threshold step value based of the current zone boundaries.
- void reset_threshold_step();
+ ConcurrentG1Refine(G1CollectedHeap* g1h,
+ size_t green_zone,
+ size_t yellow_zone,
+ size_t red_zone,
+ size_t min_yellow_zone_size);
- ConcurrentG1Refine(G1CollectedHeap* g1h, const G1Predictions* predictions);
+ // Update green/yellow/red zone values based on how well goals are being met.
+ void update_zones(double update_rs_time,
+ size_t update_rs_processed_buffers,
+ double goal_ms);
+
+ // Update thread thresholds to account for updated zone values.
+ void update_thread_thresholds();
public:
~ConcurrentG1Refine();
@@ -88,9 +94,7 @@
void init(G1RegionToSpaceMapper* card_counts_storage);
void stop();
- void adjust(double update_rs_time, double update_rs_processed_buffers, double goal_ms);
-
- void reinitialize_threads();
+ void adjust(double update_rs_time, size_t update_rs_processed_buffers, double goal_ms);
// Iterate over all concurrent refinement threads
void threads_do(ThreadClosure *tc);
@@ -105,18 +109,10 @@
void print_worker_threads_on(outputStream* st) const;
- void set_green_zone(size_t x) { _green_zone = x; }
- void set_yellow_zone(size_t x) { _yellow_zone = x; }
- void set_red_zone(size_t x) { _red_zone = x; }
-
size_t green_zone() const { return _green_zone; }
size_t yellow_zone() const { return _yellow_zone; }
size_t red_zone() const { return _red_zone; }
- uint worker_thread_num() const { return _n_worker_threads; }
-
- size_t thread_threshold_step() const { return _thread_threshold_step; }
-
G1HotCardCache* hot_card_cache() { return &_hot_card_cache; }
static bool hot_card_cache_enabled() { return G1HotCardCache::default_use_cache(); }
--- a/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -36,7 +36,8 @@
ConcurrentG1RefineThread::
ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *next,
CardTableEntryClosure* refine_closure,
- uint worker_id_offset, uint worker_id) :
+ uint worker_id_offset, uint worker_id,
+ size_t activate, size_t deactivate) :
ConcurrentGCThread(),
_refine_closure(refine_closure),
_worker_id_offset(worker_id_offset),
@@ -45,7 +46,9 @@
_next(next),
_monitor(NULL),
_cg1r(cg1r),
- _vtime_accum(0.0)
+ _vtime_accum(0.0),
+ _activation_threshold(activate),
+ _deactivation_threshold(deactivate)
{
// Each thread has its own monitor. The i-th thread is responsible for signaling
@@ -58,21 +61,17 @@
} else {
_monitor = DirtyCardQ_CBL_mon;
}
- initialize();
// set name
set_name("G1 Refine#%d", worker_id);
create_and_start();
}
-void ConcurrentG1RefineThread::initialize() {
- // Current thread activation threshold
- _threshold = MIN2(cg1r()->thread_threshold_step() * (_worker_id + 1) + cg1r()->green_zone(),
- cg1r()->yellow_zone());
- // A thread deactivates once the number of buffer reached a deactivation threshold
- _deactivation_threshold =
- MAX2(_threshold - MIN2(_threshold, cg1r()->thread_threshold_step()),
- cg1r()->green_zone());
+void ConcurrentG1RefineThread::update_thresholds(size_t activate,
+ size_t deactivate) {
+ assert(deactivate < activate, "precondition");
+ _activation_threshold = activate;
+ _deactivation_threshold = deactivate;
}
void ConcurrentG1RefineThread::wait_for_completed_buffers() {
@@ -118,9 +117,10 @@
break;
}
+ size_t buffers_processed = 0;
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
log_debug(gc, refine)("Activated %d, on threshold: " SIZE_FORMAT ", current: " SIZE_FORMAT,
- _worker_id, _threshold, dcqs.completed_buffers_num());
+ _worker_id, _activation_threshold, dcqs.completed_buffers_num());
{
SuspendibleThreadSetJoiner sts_join;
@@ -139,7 +139,9 @@
}
// Check if we need to activate the next thread.
- if (_next != NULL && !_next->is_active() && curr_buffer_num > _next->_threshold) {
+ if ((_next != NULL) &&
+ !_next->is_active() &&
+ (curr_buffer_num > _next->_activation_threshold)) {
_next->activate();
}
@@ -150,14 +152,16 @@
false /* during_pause */)) {
break; // Deactivate, number of buffers fell below threshold.
}
+ ++buffers_processed;
}
}
deactivate();
log_debug(gc, refine)("Deactivated %d, off threshold: " SIZE_FORMAT
- ", current: " SIZE_FORMAT,
+ ", current: " SIZE_FORMAT ", processed: " SIZE_FORMAT,
_worker_id, _deactivation_threshold,
- dcqs.completed_buffers_num());
+ dcqs.completed_buffers_num(),
+ buffers_processed);
if (os::supports_vtime()) {
_vtime_accum = (os::elapsedVTime() - _vtime_start);
--- a/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -53,10 +53,8 @@
// The closure applied to completed log buffers.
CardTableEntryClosure* _refine_closure;
- size_t _thread_threshold_step;
- // This thread activation threshold
- size_t _threshold;
- // This thread deactivation threshold
+ // This thread's activation/deactivation thresholds
+ size_t _activation_threshold;
size_t _deactivation_threshold;
void wait_for_completed_buffers();
@@ -75,9 +73,11 @@
// Constructor
ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread* next,
CardTableEntryClosure* refine_closure,
- uint worker_id_offset, uint worker_id);
+ uint worker_id_offset, uint worker_id,
+ size_t activate, size_t deactivate);
- void initialize();
+ void update_thresholds(size_t activate, size_t deactivate);
+ size_t activation_threshold() const { return _activation_threshold; }
// Total virtual time so far.
double vtime_accum() { return _vtime_accum; }
--- a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -28,6 +28,7 @@
#include "gc/g1/g1Analytics.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1CollectorPolicy.hpp"
+#include "gc/g1/g1ConcurrentMark.inline.hpp"
#include "gc/g1/g1MMUTracker.hpp"
#include "gc/g1/suspendibleThreadSet.hpp"
#include "gc/g1/vm_operations_g1.hpp"
@@ -183,6 +184,11 @@
}
} while (cm()->restart_for_overflow());
+ if (!cm()->has_aborted()) {
+ G1ConcPhaseTimer t(_cm, "Concurrent Create Live Data");
+ cm()->create_live_data();
+ }
+
double end_time = os::elapsedVTime();
// Update the total virtual time before doing this, since it will try
// to measure it to get the vtime for this marking. We purposely
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1CardLiveData.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,558 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1ConcurrentMark.inline.hpp"
+#include "gc/g1/g1CardLiveData.inline.hpp"
+#include "gc/g1/suspendibleThreadSet.hpp"
+#include "gc/shared/workgroup.hpp"
+#include "memory/universe.hpp"
+#include "runtime/atomic.inline.hpp"
+#include "runtime/globals.hpp"
+#include "runtime/os.hpp"
+#include "utilities/bitMap.inline.hpp"
+#include "utilities/debug.hpp"
+
+G1CardLiveData::G1CardLiveData() :
+ _max_capacity(0),
+ _cards_per_region(0),
+ _live_regions(NULL),
+ _live_regions_size_in_bits(0),
+ _live_cards(NULL),
+ _live_cards_size_in_bits(0) {
+}
+
+G1CardLiveData::~G1CardLiveData() {
+ free_large_bitmap(_live_cards, _live_cards_size_in_bits);
+ free_large_bitmap(_live_regions, _live_regions_size_in_bits);
+}
+
+G1CardLiveData::bm_word_t* G1CardLiveData::allocate_large_bitmap(size_t size_in_bits) {
+ size_t size_in_words = BitMap::calc_size_in_words(size_in_bits);
+
+ bm_word_t* map = MmapArrayAllocator<bm_word_t, mtGC>::allocate(size_in_words);
+
+ return map;
+}
+
+void G1CardLiveData::free_large_bitmap(bm_word_t* bitmap, size_t size_in_bits) {
+ MmapArrayAllocator<bm_word_t, mtGC>::free(bitmap, size_in_bits / BitsPerWord);
+}
+
+void G1CardLiveData::initialize(size_t max_capacity, uint num_max_regions) {
+ assert(max_capacity % num_max_regions == 0,
+ "Given capacity must be evenly divisible by region size.");
+ size_t region_size = max_capacity / num_max_regions;
+ assert(region_size % (G1SATBCardTableModRefBS::card_size * BitsPerWord) == 0,
+ "Region size must be evenly divisible by area covered by a single word.");
+ _max_capacity = max_capacity;
+ _cards_per_region = region_size / G1SATBCardTableModRefBS::card_size;
+
+ _live_regions_size_in_bits = live_region_bitmap_size_in_bits();
+ _live_regions = allocate_large_bitmap(_live_regions_size_in_bits);
+ _live_cards_size_in_bits = live_card_bitmap_size_in_bits();
+ _live_cards = allocate_large_bitmap(_live_cards_size_in_bits);
+}
+
+void G1CardLiveData::pretouch() {
+ live_cards_bm().pretouch();
+ live_regions_bm().pretouch();
+}
+
+size_t G1CardLiveData::live_region_bitmap_size_in_bits() const {
+ return _max_capacity / (_cards_per_region << G1SATBCardTableModRefBS::card_shift);
+}
+
+size_t G1CardLiveData::live_card_bitmap_size_in_bits() const {
+ return _max_capacity >> G1SATBCardTableModRefBS::card_shift;
+}
+
+// Helper class that provides functionality to generate the Live Data Count
+// information.
+class G1CardLiveDataHelper VALUE_OBJ_CLASS_SPEC {
+private:
+ BitMap _region_bm;
+ BitMap _card_bm;
+
+ // The card number of the bottom of the G1 heap.
+ // Used in biasing indices into accounting card bitmaps.
+ BitMap::idx_t _heap_card_bias;
+
+ // Utility routine to set an exclusive range of bits on the given
+ // bitmap, optimized for very small ranges.
+ // There must be at least one bit to set.
+ void set_card_bitmap_range(BitMap::idx_t start_idx,
+ BitMap::idx_t end_idx) {
+
+ // Set the exclusive bit range [start_idx, end_idx).
+ assert((end_idx - start_idx) > 0, "at least one bit");
+
+ // For small ranges use a simple loop; otherwise use set_range.
+ // The range is made up of the cards that are spanned by an object/mem
+ // region so 8 cards will allow up to object sizes up to 4K to be handled
+ // using the loop.
+ if ((end_idx - start_idx) <= 8) {
+ for (BitMap::idx_t i = start_idx; i < end_idx; i += 1) {
+ _card_bm.set_bit(i);
+ }
+ } else {
+ _card_bm.set_range(start_idx, end_idx);
+ }
+ }
+
+ // We cache the last mark set. This avoids setting the same bit multiple times.
+ // This is particularly interesting for dense bitmaps, as this avoids doing
+ // lots of work most of the time.
+ BitMap::idx_t _last_marked_bit_idx;
+
+ // Mark the card liveness bitmap for the object spanning from start to end.
+ void mark_card_bitmap_range(HeapWord* start, HeapWord* end) {
+ BitMap::idx_t start_idx = card_live_bitmap_index_for(start);
+ BitMap::idx_t end_idx = card_live_bitmap_index_for((HeapWord*)align_ptr_up(end, CardTableModRefBS::card_size));
+
+ assert((end_idx - start_idx) > 0, "Trying to mark zero sized range.");
+
+ if (start_idx == _last_marked_bit_idx) {
+ start_idx++;
+ }
+ if (start_idx == end_idx) {
+ return;
+ }
+
+ // Set the bits in the card bitmap for the cards spanned by this object.
+ set_card_bitmap_range(start_idx, end_idx);
+ _last_marked_bit_idx = end_idx - 1;
+ }
+
+ void reset_mark_cache() {
+ _last_marked_bit_idx = (BitMap::idx_t)-1;
+ }
+
+public:
+ // Returns the index in the per-card liveness count bitmap
+ // for the given address
+ inline BitMap::idx_t card_live_bitmap_index_for(HeapWord* addr) {
+ // Below, the term "card num" means the result of shifting an address
+ // by the card shift -- address 0 corresponds to card number 0. One
+ // must subtract the card num of the bottom of the heap to obtain a
+ // card table index.
+ BitMap::idx_t card_num = uintptr_t(addr) >> CardTableModRefBS::card_shift;
+ return card_num - _heap_card_bias;
+ }
+
+ // Takes a region that's not empty (i.e., it has at least one
+ // live object in it and sets its corresponding bit on the region
+ // bitmap to 1.
+ void set_bit_for_region(HeapRegion* hr) {
+ _region_bm.par_set_bit(hr->hrm_index());
+ }
+
+ // Mark the range of bits covered by allocations done since the last marking
+ // in the given heap region, i.e. from NTAMS to top of the given region.
+ // Returns if there has been some allocation in this region since the last marking.
+ bool mark_allocated_since_marking(HeapRegion* hr) {
+ reset_mark_cache();
+
+ HeapWord* ntams = hr->next_top_at_mark_start();
+ HeapWord* top = hr->top();
+
+ assert(hr->bottom() <= ntams && ntams <= hr->end(), "Preconditions.");
+
+ // Mark the allocated-since-marking portion...
+ if (ntams < top) {
+ mark_card_bitmap_range(ntams, top);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ // Mark the range of bits covered by live objects on the mark bitmap between
+ // bottom and NTAMS of the given region.
+ // Returns the number of live bytes marked within that area for the given
+ // heap region.
+ size_t mark_marked_during_marking(G1CMBitMap* mark_bitmap, HeapRegion* hr) {
+ reset_mark_cache();
+
+ size_t marked_bytes = 0;
+
+ HeapWord* ntams = hr->next_top_at_mark_start();
+ HeapWord* start = hr->bottom();
+
+ if (ntams <= start) {
+ // Skip empty regions.
+ return 0;
+ }
+ if (hr->is_humongous()) {
+ HeapRegion* start_region = hr->humongous_start_region();
+ if (mark_bitmap->isMarked(start_region->bottom())) {
+ mark_card_bitmap_range(start, hr->top());
+ return pointer_delta(hr->top(), start, 1);
+ } else {
+ // Humongous start object was actually dead.
+ return 0;
+ }
+ }
+
+ assert(start <= hr->end() && start <= ntams && ntams <= hr->end(),
+ "Preconditions not met - "
+ "start: " PTR_FORMAT ", ntams: " PTR_FORMAT ", end: " PTR_FORMAT,
+ p2i(start), p2i(ntams), p2i(hr->end()));
+
+ // Find the first marked object at or after "start".
+ start = mark_bitmap->getNextMarkedWordAddress(start, ntams);
+ while (start < ntams) {
+ oop obj = oop(start);
+ size_t obj_size = obj->size();
+ HeapWord* obj_end = start + obj_size;
+
+ assert(obj_end <= hr->end(), "Humongous objects must have been handled elsewhere.");
+
+ mark_card_bitmap_range(start, obj_end);
+
+ // Add the size of this object to the number of marked bytes.
+ marked_bytes += obj_size * HeapWordSize;
+
+ // Find the next marked object after this one.
+ start = mark_bitmap->getNextMarkedWordAddress(obj_end, ntams);
+ }
+
+ return marked_bytes;
+ }
+
+ G1CardLiveDataHelper(G1CardLiveData* live_data, HeapWord* base_address) :
+ _region_bm(live_data->live_regions_bm()),
+ _card_bm(live_data->live_cards_bm()) {
+ // Calculate the card number for the bottom of the heap. Used
+ // in biasing indexes into the accounting card bitmaps.
+ _heap_card_bias =
+ uintptr_t(base_address) >> CardTableModRefBS::card_shift;
+ }
+};
+
+class G1CreateCardLiveDataTask: public AbstractGangTask {
+ // Aggregate the counting data that was constructed concurrently
+ // with marking.
+ class G1CreateLiveDataClosure : public HeapRegionClosure {
+ G1CardLiveDataHelper _helper;
+
+ G1CMBitMap* _mark_bitmap;
+
+ G1ConcurrentMark* _cm;
+ public:
+ G1CreateLiveDataClosure(G1CollectedHeap* g1h,
+ G1ConcurrentMark* cm,
+ G1CMBitMap* mark_bitmap,
+ G1CardLiveData* live_data) :
+ HeapRegionClosure(),
+ _helper(live_data, g1h->reserved_region().start()),
+ _mark_bitmap(mark_bitmap),
+ _cm(cm) { }
+
+ bool doHeapRegion(HeapRegion* hr) {
+ size_t marked_bytes = _helper.mark_marked_during_marking(_mark_bitmap, hr);
+ if (marked_bytes > 0) {
+ hr->add_to_marked_bytes(marked_bytes);
+ }
+
+ return (_cm->do_yield_check() && _cm->has_aborted());
+ }
+ };
+
+ G1ConcurrentMark* _cm;
+ G1CardLiveData* _live_data;
+ HeapRegionClaimer _hr_claimer;
+
+public:
+ G1CreateCardLiveDataTask(G1CMBitMap* bitmap,
+ G1CardLiveData* live_data,
+ uint n_workers) :
+ AbstractGangTask("G1 Create Live Data"),
+ _live_data(live_data),
+ _hr_claimer(n_workers) {
+ }
+
+ void work(uint worker_id) {
+ SuspendibleThreadSetJoiner sts_join;
+
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+ G1ConcurrentMark* cm = g1h->concurrent_mark();
+ G1CreateLiveDataClosure cl(g1h, cm, cm->nextMarkBitMap(), _live_data);
+ g1h->heap_region_par_iterate(&cl, worker_id, &_hr_claimer);
+ }
+};
+
+void G1CardLiveData::create(WorkGang* workers, G1CMBitMap* mark_bitmap) {
+ uint n_workers = workers->active_workers();
+
+ G1CreateCardLiveDataTask cl(mark_bitmap,
+ this,
+ n_workers);
+ workers->run_task(&cl);
+}
+
+class G1FinalizeCardLiveDataTask: public AbstractGangTask {
+ // Finalizes the liveness counting data.
+ // Sets the bits corresponding to the interval [NTAMS, top]
+ // (which contains the implicitly live objects) in the
+ // card liveness bitmap. Also sets the bit for each region
+ // containing live data, in the region liveness bitmap.
+ class G1FinalizeCardLiveDataClosure: public HeapRegionClosure {
+ private:
+ G1CardLiveDataHelper _helper;
+ public:
+ G1FinalizeCardLiveDataClosure(G1CollectedHeap* g1h,
+ G1CMBitMap* bitmap,
+ G1CardLiveData* live_data) :
+ HeapRegionClosure(),
+ _helper(live_data, g1h->reserved_region().start()) { }
+
+ bool doHeapRegion(HeapRegion* hr) {
+ bool allocated_since_marking = _helper.mark_allocated_since_marking(hr);
+ if (allocated_since_marking || hr->next_marked_bytes() > 0) {
+ _helper.set_bit_for_region(hr);
+ }
+ return false;
+ }
+ };
+
+ G1CMBitMap* _bitmap;
+
+ G1CardLiveData* _live_data;
+
+ HeapRegionClaimer _hr_claimer;
+
+public:
+ G1FinalizeCardLiveDataTask(G1CMBitMap* bitmap, G1CardLiveData* live_data, uint n_workers) :
+ AbstractGangTask("G1 Finalize Card Live Data"),
+ _bitmap(bitmap),
+ _live_data(live_data),
+ _hr_claimer(n_workers) {
+ }
+
+ void work(uint worker_id) {
+ G1FinalizeCardLiveDataClosure cl(G1CollectedHeap::heap(), _bitmap, _live_data);
+
+ G1CollectedHeap::heap()->heap_region_par_iterate(&cl, worker_id, &_hr_claimer);
+ }
+};
+
+void G1CardLiveData::finalize(WorkGang* workers, G1CMBitMap* mark_bitmap) {
+ // Finalize the live data.
+ G1FinalizeCardLiveDataTask cl(mark_bitmap,
+ this,
+ workers->active_workers());
+ workers->run_task(&cl);
+}
+
+class G1ClearCardLiveDataTask : public AbstractGangTask {
+ BitMap _bitmap;
+ size_t _num_chunks;
+ size_t _cur_chunk;
+public:
+ G1ClearCardLiveDataTask(BitMap bitmap, size_t num_tasks) :
+ AbstractGangTask("G1 Clear Card Live Data"),
+ _bitmap(bitmap),
+ _num_chunks(num_tasks),
+ _cur_chunk(0) {
+ }
+
+ static size_t chunk_size() { return M; }
+
+ virtual void work(uint worker_id) {
+ while (true) {
+ size_t to_process = Atomic::add(1, &_cur_chunk) - 1;
+ if (to_process >= _num_chunks) {
+ break;
+ }
+
+ BitMap::idx_t start = M * BitsPerByte * to_process;
+ BitMap::idx_t end = MIN2(start + M * BitsPerByte, _bitmap.size());
+ _bitmap.clear_range(start, end);
+ }
+ }
+};
+
+void G1CardLiveData::clear(WorkGang* workers) {
+ guarantee(Universe::is_fully_initialized(), "Should not call this during initialization.");
+
+ size_t const num_chunks = align_size_up(live_cards_bm().size_in_bytes(), G1ClearCardLiveDataTask::chunk_size()) / G1ClearCardLiveDataTask::chunk_size();
+
+ G1ClearCardLiveDataTask cl(live_cards_bm(), num_chunks);
+ workers->run_task(&cl);
+
+ // The region live bitmap is always very small, even for huge heaps. Clear
+ // directly.
+ live_regions_bm().clear();
+}
+
+class G1VerifyCardLiveDataTask: public AbstractGangTask {
+ // Heap region closure used for verifying the live count data
+ // that was created concurrently and finalized during
+ // the remark pause. This closure is applied to the heap
+ // regions during the STW cleanup pause.
+ class G1VerifyCardLiveDataClosure: public HeapRegionClosure {
+ private:
+ G1CollectedHeap* _g1h;
+ G1CMBitMap* _mark_bitmap;
+ G1CardLiveDataHelper _helper;
+
+ G1CardLiveData* _act_live_data;
+
+ G1CardLiveData* _exp_live_data;
+
+ int _failures;
+
+ // Completely recreates the live data count for the given heap region and
+ // returns the number of bytes marked.
+ size_t create_live_data_count(HeapRegion* hr) {
+ size_t bytes_marked = _helper.mark_marked_during_marking(_mark_bitmap, hr);
+ bool allocated_since_marking = _helper.mark_allocated_since_marking(hr);
+ if (allocated_since_marking || bytes_marked > 0) {
+ _helper.set_bit_for_region(hr);
+ }
+ return bytes_marked;
+ }
+ public:
+ G1VerifyCardLiveDataClosure(G1CollectedHeap* g1h,
+ G1CMBitMap* mark_bitmap,
+ G1CardLiveData* act_live_data,
+ G1CardLiveData* exp_live_data) :
+ _g1h(g1h),
+ _mark_bitmap(mark_bitmap),
+ _helper(exp_live_data, g1h->reserved_region().start()),
+ _act_live_data(act_live_data),
+ _exp_live_data(exp_live_data),
+ _failures(0) { }
+
+ int failures() const { return _failures; }
+
+ bool doHeapRegion(HeapRegion* hr) {
+ int failures = 0;
+
+ // Walk the marking bitmap for this region and set the corresponding bits
+ // in the expected region and card bitmaps.
+ size_t exp_marked_bytes = create_live_data_count(hr);
+ size_t act_marked_bytes = hr->next_marked_bytes();
+ // Verify the marked bytes for this region.
+
+ if (exp_marked_bytes != act_marked_bytes) {
+ failures += 1;
+ } else if (exp_marked_bytes > HeapRegion::GrainBytes) {
+ failures += 1;
+ }
+
+ // Verify the bit, for this region, in the actual and expected
+ // (which was just calculated) region bit maps.
+ // We're not OK if the bit in the calculated expected region
+ // bitmap is set and the bit in the actual region bitmap is not.
+ uint index = hr->hrm_index();
+
+ bool expected = _exp_live_data->is_region_live(index);
+ bool actual = _act_live_data->is_region_live(index);
+ if (expected && !actual) {
+ failures += 1;
+ }
+
+ // Verify that the card bit maps for the cards spanned by the current
+ // region match. We have an error if we have a set bit in the expected
+ // bit map and the corresponding bit in the actual bitmap is not set.
+
+ BitMap::idx_t start_idx = _helper.card_live_bitmap_index_for(hr->bottom());
+ BitMap::idx_t end_idx = _helper.card_live_bitmap_index_for(hr->top());
+
+ for (BitMap::idx_t i = start_idx; i < end_idx; i+=1) {
+ expected = _exp_live_data->is_card_live_at(i);
+ actual = _act_live_data->is_card_live_at(i);
+
+ if (expected && !actual) {
+ failures += 1;
+ }
+ }
+
+ _failures += failures;
+
+ // We could stop iteration over the heap when we
+ // find the first violating region by returning true.
+ return false;
+ }
+ };
+protected:
+ G1CollectedHeap* _g1h;
+ G1CMBitMap* _mark_bitmap;
+
+ G1CardLiveData* _act_live_data;
+
+ G1CardLiveData _exp_live_data;
+
+ int _failures;
+
+ HeapRegionClaimer _hr_claimer;
+
+public:
+ G1VerifyCardLiveDataTask(G1CMBitMap* bitmap,
+ G1CardLiveData* act_live_data,
+ uint n_workers)
+ : AbstractGangTask("G1 Verify Card Live Data"),
+ _g1h(G1CollectedHeap::heap()),
+ _mark_bitmap(bitmap),
+ _act_live_data(act_live_data),
+ _exp_live_data(),
+ _failures(0),
+ _hr_claimer(n_workers) {
+ assert(VerifyDuringGC, "don't call this otherwise");
+ _exp_live_data.initialize(_g1h->max_capacity(), _g1h->max_regions());
+ }
+
+ void work(uint worker_id) {
+ G1VerifyCardLiveDataClosure cl(_g1h,
+ _mark_bitmap,
+ _act_live_data,
+ &_exp_live_data);
+ _g1h->heap_region_par_iterate(&cl, worker_id, &_hr_claimer);
+
+ Atomic::add(cl.failures(), &_failures);
+ }
+
+ int failures() const { return _failures; }
+};
+
+void G1CardLiveData::verify(WorkGang* workers, G1CMBitMap* actual_bitmap) {
+ ResourceMark rm;
+
+ G1VerifyCardLiveDataTask cl(actual_bitmap,
+ this,
+ workers->active_workers());
+ workers->run_task(&cl);
+
+ guarantee(cl.failures() == 0, "Unexpected accounting failures");
+}
+
+#ifndef PRODUCT
+void G1CardLiveData::verify_is_clear() {
+ assert(live_cards_bm().count_one_bits() == 0, "Live cards bitmap must be clear.");
+ assert(live_regions_bm().count_one_bits() == 0, "Live regions bitmap must be clear.");
+}
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1CardLiveData.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_G1_G1CARDLIVEDATA_HPP
+#define SHARE_VM_GC_G1_G1CARDLIVEDATA_HPP
+
+#include "gc/g1/g1CollectedHeap.hpp"
+#include "utilities/bitMap.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class G1CollectedHeap;
+class G1CMBitMap;
+class WorkGang;
+
+// Information about object liveness on the Java heap on a "card" basis.
+// Can be used for various purposes, like as remembered set for completely
+// coarsened remembered sets, scrubbing remembered sets or estimating liveness.
+// This information is created as part of the concurrent marking cycle.
+class G1CardLiveData VALUE_OBJ_CLASS_SPEC {
+ friend class G1CardLiveDataHelper;
+ friend class G1VerifyCardLiveDataTask;
+private:
+ typedef BitMap::bm_word_t bm_word_t;
+ // Store some additional information about the covered area to be able to test.
+ size_t _max_capacity;
+ size_t _cards_per_region;
+
+ // The per-card liveness bitmap.
+ bm_word_t* _live_cards;
+ size_t _live_cards_size_in_bits;
+ // The per-region liveness bitmap.
+ bm_word_t* _live_regions;
+ size_t _live_regions_size_in_bits;
+ // The bits in this bitmap contain for every card whether it contains
+ // at least part of at least one live object.
+ BitMap live_cards_bm() const { return BitMap(_live_cards, _live_cards_size_in_bits); }
+ // The bits in this bitmap indicate that a given region contains some live objects.
+ BitMap live_regions_bm() const { return BitMap(_live_regions, _live_regions_size_in_bits); }
+
+ // Allocate a "large" bitmap from virtual memory with the given size in bits.
+ bm_word_t* allocate_large_bitmap(size_t size_in_bits);
+ void free_large_bitmap(bm_word_t* map, size_t size_in_bits);
+
+ inline BitMap live_card_bitmap(uint region);
+
+ inline bool is_card_live_at(BitMap::idx_t idx) const;
+
+ size_t live_region_bitmap_size_in_bits() const;
+ size_t live_card_bitmap_size_in_bits() const;
+public:
+ inline bool is_region_live(uint region) const;
+
+ inline void remove_nonlive_cards(uint region, BitMap* bm);
+ inline void remove_nonlive_regions(BitMap* bm);
+
+ G1CardLiveData();
+ ~G1CardLiveData();
+
+ void initialize(size_t max_capacity, uint num_max_regions);
+ void pretouch();
+
+ // Create the initial liveness data based on the marking result from the bottom
+ // to the ntams of every region in the heap and the marks in the given bitmap.
+ void create(WorkGang* workers, G1CMBitMap* mark_bitmap);
+ // Finalize the liveness data.
+ void finalize(WorkGang* workers, G1CMBitMap* mark_bitmap);
+
+ // Verify that the liveness count data created concurrently matches one created
+ // during this safepoint.
+ void verify(WorkGang* workers, G1CMBitMap* actual_bitmap);
+ // Clear all data structures, prepare for next processing.
+ void clear(WorkGang* workers);
+
+ void verify_is_clear() PRODUCT_RETURN;
+};
+
+#endif /* SHARE_VM_GC_G1_G1CARDLIVEDATA_HPP */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1CardLiveData.inline.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_G1_G1CARDLIVEDATA_INLINE_HPP
+#define SHARE_VM_GC_G1_G1CARDLIVEDATA_INLINE_HPP
+
+#include "gc/g1/g1CardLiveData.hpp"
+#include "utilities/bitMap.inline.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+inline BitMap G1CardLiveData::live_card_bitmap(uint region) {
+ return BitMap(_live_cards + ((size_t)region * _cards_per_region >> LogBitsPerWord), _cards_per_region);
+}
+
+inline bool G1CardLiveData::is_card_live_at(BitMap::idx_t idx) const {
+ return live_cards_bm().at(idx);
+}
+
+inline bool G1CardLiveData::is_region_live(uint region) const {
+ return live_regions_bm().at(region);
+}
+
+inline void G1CardLiveData::remove_nonlive_cards(uint region, BitMap* bm) {
+ bm->set_intersection(live_card_bitmap(region));
+}
+
+inline void G1CardLiveData::remove_nonlive_regions(BitMap* bm) {
+ bm->set_intersection(live_regions_bm());
+}
+
+#endif /* SHARE_VM_GC_G1_G1CARDLIVEDATA_INLINE_HPP */
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1425,6 +1425,7 @@
// the full GC has compacted objects and updated TAMS but not updated
// the prev bitmap.
if (G1VerifyBitmaps) {
+ GCTraceTime(Debug, gc)("Clear Bitmap for Verification");
_cm->clear_prev_bitmap(workers());
}
_verifier->check_bitmaps("Full GC End");
@@ -1828,10 +1829,14 @@
HeapRegion::GrainBytes,
translation_factor,
mtGC);
- if (TracePageSizes) {
- tty->print_cr("G1 '%s': pg_sz=" SIZE_FORMAT " base=" PTR_FORMAT " size=" SIZE_FORMAT " alignment=" SIZE_FORMAT " reqsize=" SIZE_FORMAT,
- description, preferred_page_size, p2i(rs.base()), rs.size(), rs.alignment(), size);
- }
+
+ os::trace_page_sizes_for_requested_size(description,
+ size,
+ preferred_page_size,
+ rs.alignment(),
+ rs.base(),
+ rs.size());
+
return result;
}
@@ -1905,26 +1910,28 @@
HeapRegion::GrainBytes,
1,
mtJavaHeap);
- os::trace_page_sizes("G1 Heap", collector_policy()->min_heap_byte_size(),
- max_byte_size, page_size,
+ os::trace_page_sizes("Heap",
+ collector_policy()->min_heap_byte_size(),
+ max_byte_size,
+ page_size,
heap_rs.base(),
heap_rs.size());
heap_storage->set_mapping_changed_listener(&_listener);
// Create storage for the BOT, card table, card counts table (hot card cache) and the bitmaps.
G1RegionToSpaceMapper* bot_storage =
- create_aux_memory_mapper("Block offset table",
+ create_aux_memory_mapper("Block Offset Table",
G1BlockOffsetTable::compute_size(g1_rs.size() / HeapWordSize),
G1BlockOffsetTable::heap_map_factor());
ReservedSpace cardtable_rs(G1SATBCardTableLoggingModRefBS::compute_size(g1_rs.size() / HeapWordSize));
G1RegionToSpaceMapper* cardtable_storage =
- create_aux_memory_mapper("Card table",
+ create_aux_memory_mapper("Card Table",
G1SATBCardTableLoggingModRefBS::compute_size(g1_rs.size() / HeapWordSize),
G1SATBCardTableLoggingModRefBS::heap_map_factor());
G1RegionToSpaceMapper* card_counts_storage =
- create_aux_memory_mapper("Card counts table",
+ create_aux_memory_mapper("Card Counts Table",
G1CardCounts::compute_size(g1_rs.size() / HeapWordSize),
G1CardCounts::heap_map_factor());
@@ -1944,7 +1951,7 @@
const uint max_region_idx = (1U << (sizeof(RegionIdx_t)*BitsPerByte-1)) - 1;
guarantee((max_regions() - 1) <= max_region_idx, "too many regions");
- G1RemSet::initialize(max_regions());
+ g1_rem_set()->initialize(max_capacity(), max_regions());
size_t max_cards_per_region = ((size_t)1 << (sizeof(CardIdx_t)*BitsPerByte-1)) - 1;
guarantee(HeapRegion::CardsPerRegion > 0, "make sure it's initialized");
@@ -2735,7 +2742,7 @@
_cmThread->print_on(st);
st->cr();
_cm->print_worker_threads_on(st);
- _cg1r->print_worker_threads_on(st);
+ _cg1r->print_worker_threads_on(st); // also prints the sample thread
if (G1StringDedup::is_enabled()) {
G1StringDedup::print_worker_threads_on(st);
}
@@ -2744,7 +2751,8 @@
void G1CollectedHeap::gc_threads_do(ThreadClosure* tc) const {
workers()->threads_do(tc);
tc->do_thread(_cmThread);
- _cg1r->threads_do(tc);
+ _cm->threads_do(tc);
+ _cg1r->threads_do(tc); // also iterates over the sample thread
if (G1StringDedup::is_enabled()) {
G1StringDedup::threads_do(tc);
}
@@ -2939,13 +2947,17 @@
: rset->is_empty();
}
- bool is_typeArray_region(HeapRegion* region) const {
- return oop(region->bottom())->is_typeArray();
- }
-
bool humongous_region_is_candidate(G1CollectedHeap* heap, HeapRegion* region) const {
assert(region->is_starts_humongous(), "Must start a humongous object");
+ oop obj = oop(region->bottom());
+
+ // Dead objects cannot be eager reclaim candidates. Due to class
+ // unloading it is unsafe to query their classes so we return early.
+ if (heap->is_obj_dead(obj, region)) {
+ return false;
+ }
+
// Candidate selection must satisfy the following constraints
// while concurrent marking is in progress:
//
@@ -2982,7 +2994,7 @@
// important use case for eager reclaim, and this special handling
// may reduce needed headroom.
- return is_typeArray_region(region) && is_remset_small(region);
+ return obj->is_typeArray() && is_remset_small(region);
}
public:
@@ -4440,7 +4452,6 @@
}
void G1CollectedHeap::preserve_cm_referents(G1ParScanThreadStateSet* per_thread_states) {
- double preserve_cm_referents_start = os::elapsedTime();
// Any reference objects, in the collection set, that were 'discovered'
// by the CM ref processor should have already been copied (either by
// applying the external root copy closure to the discovered lists, or
@@ -4461,16 +4472,24 @@
// objects discovered by the STW ref processor in case one of these
// referents points to another object which is also referenced by an
// object discovered by the STW ref processor.
-
- uint no_of_gc_workers = workers()->active_workers();
-
- G1ParPreserveCMReferentsTask keep_cm_referents(this,
- per_thread_states,
- no_of_gc_workers,
- _task_queues);
- workers()->run_task(&keep_cm_referents);
-
- g1_policy()->phase_times()->record_preserve_cm_referents_time_ms((os::elapsedTime() - preserve_cm_referents_start) * 1000.0);
+ double preserve_cm_referents_time = 0.0;
+
+ // To avoid spawning task when there is no work to do, check that
+ // a concurrent cycle is active and that some references have been
+ // discovered.
+ if (concurrent_mark()->cmThread()->during_cycle() &&
+ ref_processor_cm()->has_discovered_references()) {
+ double preserve_cm_referents_start = os::elapsedTime();
+ uint no_of_gc_workers = workers()->active_workers();
+ G1ParPreserveCMReferentsTask keep_cm_referents(this,
+ per_thread_states,
+ no_of_gc_workers,
+ _task_queues);
+ workers()->run_task(&keep_cm_referents);
+ preserve_cm_referents_time = os::elapsedTime() - preserve_cm_referents_start;
+ }
+
+ g1_policy()->phase_times()->record_preserve_cm_referents_time_ms(preserve_cm_referents_time * 1000.0);
}
// Weak Reference processing during an evacuation pause (part 1).
@@ -4787,27 +4806,23 @@
class G1ParScrubRemSetTask: public AbstractGangTask {
protected:
G1RemSet* _g1rs;
- BitMap* _region_bm;
- BitMap* _card_bm;
HeapRegionClaimer _hrclaimer;
public:
- G1ParScrubRemSetTask(G1RemSet* g1_rs, BitMap* region_bm, BitMap* card_bm, uint num_workers) :
+ G1ParScrubRemSetTask(G1RemSet* g1_rs, uint num_workers) :
AbstractGangTask("G1 ScrubRS"),
_g1rs(g1_rs),
- _region_bm(region_bm),
- _card_bm(card_bm),
_hrclaimer(num_workers) {
}
void work(uint worker_id) {
- _g1rs->scrub(_region_bm, _card_bm, worker_id, &_hrclaimer);
+ _g1rs->scrub(worker_id, &_hrclaimer);
}
};
-void G1CollectedHeap::scrub_rem_set(BitMap* region_bm, BitMap* card_bm) {
+void G1CollectedHeap::scrub_rem_set() {
uint num_workers = workers()->active_workers();
- G1ParScrubRemSetTask g1_par_scrub_rs_task(g1_rem_set(), region_bm, card_bm, num_workers);
+ G1ParScrubRemSetTask g1_par_scrub_rs_task(g1_rem_set(), num_workers);
workers()->run_task(&g1_par_scrub_rs_task);
}
@@ -4821,6 +4836,9 @@
workers()->run_task(&cleanup_task);
#ifndef PRODUCT
+ // Need to synchronize with concurrent cleanup since it needs to
+ // finish its card table clearing before we can verify.
+ wait_while_free_regions_coming();
_verifier->verify_card_table_cleanup();
#endif
}
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -992,7 +992,8 @@
// The rem set and barrier set.
G1RemSet* g1_rem_set() const { return _g1_rem_set; }
- void scrub_rem_set(BitMap* region_bm, BitMap* card_bm);
+ // Try to minimize the remembered set.
+ void scrub_rem_set();
unsigned get_gc_time_stamp() {
return _gc_time_stamp;
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -28,7 +28,7 @@
#include "gc/g1/g1CollectedHeap.hpp"
#include "gc/g1/g1CollectorPolicy.hpp"
#include "gc/g1/g1CollectorState.hpp"
-#include "gc/g1/g1ConcurrentMark.hpp"
+#include "gc/g1/g1ConcurrentMark.inline.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#include "gc/g1/heapRegionManager.inline.hpp"
#include "gc/g1/heapRegionSet.inline.hpp"
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -33,6 +33,7 @@
#include "gc/g1/g1ConcurrentMark.inline.hpp"
#include "gc/g1/g1HeapVerifier.hpp"
#include "gc/g1/g1OopClosures.inline.hpp"
+#include "gc/g1/g1CardLiveData.inline.hpp"
#include "gc/g1/g1StringDedup.hpp"
#include "gc/g1/heapRegion.inline.hpp"
#include "gc/g1/heapRegionRemSet.hpp"
@@ -355,10 +356,6 @@
_sleep_factor(0.0),
_marking_task_overhead(1.0),
_cleanup_list("Cleanup List"),
- _region_bm((BitMap::idx_t)(g1h->max_regions()), false /* in_resource_area*/),
- _card_bm((g1h->reserved_region().byte_size() + CardTableModRefBS::card_size - 1) >>
- CardTableModRefBS::card_shift,
- false /* in_resource_area*/),
_prevMarkBitMap(&_markBitMap1),
_nextMarkBitMap(&_markBitMap2),
@@ -390,8 +387,6 @@
_parallel_workers(NULL),
- _count_card_bitmaps(NULL),
- _count_marked_bytes(NULL),
_completed_initialization(false) {
_markBitMap1.initialize(g1h->reserved_region(), prev_bitmap_storage);
@@ -505,40 +500,19 @@
_tasks = NEW_C_HEAP_ARRAY(G1CMTask*, _max_worker_id, mtGC);
_accum_task_vtime = NEW_C_HEAP_ARRAY(double, _max_worker_id, mtGC);
- _count_card_bitmaps = NEW_C_HEAP_ARRAY(BitMap, _max_worker_id, mtGC);
- _count_marked_bytes = NEW_C_HEAP_ARRAY(size_t*, _max_worker_id, mtGC);
-
- BitMap::idx_t card_bm_size = _card_bm.size();
-
// so that the assertion in MarkingTaskQueue::task_queue doesn't fail
_active_tasks = _max_worker_id;
- uint max_regions = _g1h->max_regions();
for (uint i = 0; i < _max_worker_id; ++i) {
G1CMTaskQueue* task_queue = new G1CMTaskQueue();
task_queue->initialize();
_task_queues->register_queue(i, task_queue);
- _count_card_bitmaps[i] = BitMap(card_bm_size, false);
- _count_marked_bytes[i] = NEW_C_HEAP_ARRAY(size_t, max_regions, mtGC);
-
- _tasks[i] = new G1CMTask(i, this,
- _count_marked_bytes[i],
- &_count_card_bitmaps[i],
- task_queue, _task_queues);
+ _tasks[i] = new G1CMTask(i, this, task_queue, _task_queues);
_accum_task_vtime[i] = 0.0;
}
- // Calculate the card number for the bottom of the heap. Used
- // in biasing indexes into the accounting card bitmaps.
- _heap_bottom_card_num =
- intptr_t(uintptr_t(_g1h->reserved_region().start()) >>
- CardTableModRefBS::card_shift);
-
- // Clear all the liveness counting data
- clear_all_count_data();
-
// so that the call below can read a sensible value
_heap_start = g1h->reserved_region().start();
set_non_marking_state();
@@ -716,10 +690,11 @@
clear_bitmap(_nextMarkBitMap, _parallel_workers, true);
- // Clear the liveness counting data. If the marking has been aborted, the abort()
+ // Clear the live count data. If the marking has been aborted, the abort()
// call already did that.
if (!has_aborted()) {
- clear_all_count_data();
+ clear_live_data(_parallel_workers);
+ DEBUG_ONLY(verify_live_data_clear());
}
// Repeat the asserts from above.
@@ -901,7 +876,7 @@
double elapsed_vtime_sec = end_vtime_sec - start_vtime_sec;
_cm->clear_has_overflown();
- _cm->do_yield_check(worker_id);
+ _cm->do_yield_check();
jlong sleep_time_ms;
if (!_cm->has_aborted() && the_task->has_aborted()) {
@@ -951,10 +926,10 @@
return n_conc_workers;
}
-void G1ConcurrentMark::scanRootRegion(HeapRegion* hr, uint worker_id) {
+void G1ConcurrentMark::scanRootRegion(HeapRegion* hr) {
// Currently, only survivors can be root regions.
assert(hr->next_top_at_mark_start() == hr->bottom(), "invariant");
- G1RootRegionScanClosure cl(_g1h, this, worker_id);
+ G1RootRegionScanClosure cl(_g1h, this);
const uintx interval = PrefetchScanIntervalInBytes;
HeapWord* curr = hr->bottom();
@@ -983,7 +958,7 @@
G1CMRootRegions* root_regions = _cm->root_regions();
HeapRegion* hr = root_regions->claim_next();
while (hr != NULL) {
- _cm->scanRootRegion(hr, worker_id);
+ _cm->scanRootRegion(hr);
hr = root_regions->claim_next();
}
}
@@ -1107,14 +1082,6 @@
// marking due to overflowing the global mark stack.
reset_marking_state();
} else {
- {
- GCTraceTime(Debug, gc, phases) trace("Aggregate Data", _gc_timer_cm);
-
- // Aggregate the per-task counting data that we have accumulated
- // while marking.
- aggregate_count_data();
- }
-
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
// We're done with marking.
// This is the end of the marking cycle, we're expected all
@@ -1150,363 +1117,6 @@
_gc_tracer_cm->report_object_count_after_gc(&is_alive);
}
-// Base class of the closures that finalize and verify the
-// liveness counting data.
-class G1CMCountDataClosureBase: public HeapRegionClosure {
-protected:
- G1CollectedHeap* _g1h;
- G1ConcurrentMark* _cm;
- CardTableModRefBS* _ct_bs;
-
- BitMap* _region_bm;
- BitMap* _card_bm;
-
- // Takes a region that's not empty (i.e., it has at least one
- // live object in it and sets its corresponding bit on the region
- // bitmap to 1.
- void set_bit_for_region(HeapRegion* hr) {
- BitMap::idx_t index = (BitMap::idx_t) hr->hrm_index();
- _region_bm->par_at_put(index, true);
- }
-
-public:
- G1CMCountDataClosureBase(G1CollectedHeap* g1h,
- BitMap* region_bm, BitMap* card_bm):
- _g1h(g1h), _cm(g1h->concurrent_mark()),
- _ct_bs(barrier_set_cast<CardTableModRefBS>(g1h->barrier_set())),
- _region_bm(region_bm), _card_bm(card_bm) { }
-};
-
-// Closure that calculates the # live objects per region. Used
-// for verification purposes during the cleanup pause.
-class CalcLiveObjectsClosure: public G1CMCountDataClosureBase {
- G1CMBitMapRO* _bm;
- size_t _region_marked_bytes;
-
-public:
- CalcLiveObjectsClosure(G1CMBitMapRO *bm, G1CollectedHeap* g1h,
- BitMap* region_bm, BitMap* card_bm) :
- G1CMCountDataClosureBase(g1h, region_bm, card_bm),
- _bm(bm), _region_marked_bytes(0) { }
-
- bool doHeapRegion(HeapRegion* hr) {
- HeapWord* ntams = hr->next_top_at_mark_start();
- HeapWord* start = hr->bottom();
-
- assert(start <= hr->end() && start <= ntams && ntams <= hr->end(),
- "Preconditions not met - "
- "start: " PTR_FORMAT ", ntams: " PTR_FORMAT ", end: " PTR_FORMAT,
- p2i(start), p2i(ntams), p2i(hr->end()));
-
- // Find the first marked object at or after "start".
- start = _bm->getNextMarkedWordAddress(start, ntams);
-
- size_t marked_bytes = 0;
-
- while (start < ntams) {
- oop obj = oop(start);
- int obj_sz = obj->size();
- HeapWord* obj_end = start + obj_sz;
-
- BitMap::idx_t start_idx = _cm->card_bitmap_index_for(start);
- BitMap::idx_t end_idx = _cm->card_bitmap_index_for(obj_end);
-
- // Note: if we're looking at the last region in heap - obj_end
- // could be actually just beyond the end of the heap; end_idx
- // will then correspond to a (non-existent) card that is also
- // just beyond the heap.
- if (_g1h->is_in_g1_reserved(obj_end) && !_ct_bs->is_card_aligned(obj_end)) {
- // end of object is not card aligned - increment to cover
- // all the cards spanned by the object
- end_idx += 1;
- }
-
- // Set the bits in the card BM for the cards spanned by this object.
- _cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */);
-
- // Add the size of this object to the number of marked bytes.
- marked_bytes += (size_t)obj_sz * HeapWordSize;
-
- // This will happen if we are handling a humongous object that spans
- // several heap regions.
- if (obj_end > hr->end()) {
- break;
- }
- // Find the next marked object after this one.
- start = _bm->getNextMarkedWordAddress(obj_end, ntams);
- }
-
- // Mark the allocated-since-marking portion...
- HeapWord* top = hr->top();
- if (ntams < top) {
- BitMap::idx_t start_idx = _cm->card_bitmap_index_for(ntams);
- BitMap::idx_t end_idx = _cm->card_bitmap_index_for(top);
-
- // Note: if we're looking at the last region in heap - top
- // could be actually just beyond the end of the heap; end_idx
- // will then correspond to a (non-existent) card that is also
- // just beyond the heap.
- if (_g1h->is_in_g1_reserved(top) && !_ct_bs->is_card_aligned(top)) {
- // end of object is not card aligned - increment to cover
- // all the cards spanned by the object
- end_idx += 1;
- }
- _cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */);
-
- // This definitely means the region has live objects.
- set_bit_for_region(hr);
- }
-
- // Update the live region bitmap.
- if (marked_bytes > 0) {
- set_bit_for_region(hr);
- }
-
- // Set the marked bytes for the current region so that
- // it can be queried by a calling verification routine
- _region_marked_bytes = marked_bytes;
-
- return false;
- }
-
- size_t region_marked_bytes() const { return _region_marked_bytes; }
-};
-
-// Heap region closure used for verifying the counting data
-// that was accumulated concurrently and aggregated during
-// the remark pause. This closure is applied to the heap
-// regions during the STW cleanup pause.
-
-class VerifyLiveObjectDataHRClosure: public HeapRegionClosure {
- G1CollectedHeap* _g1h;
- G1ConcurrentMark* _cm;
- CalcLiveObjectsClosure _calc_cl;
- BitMap* _region_bm; // Region BM to be verified
- BitMap* _card_bm; // Card BM to be verified
-
- BitMap* _exp_region_bm; // Expected Region BM values
- BitMap* _exp_card_bm; // Expected card BM values
-
- int _failures;
-
-public:
- VerifyLiveObjectDataHRClosure(G1CollectedHeap* g1h,
- BitMap* region_bm,
- BitMap* card_bm,
- BitMap* exp_region_bm,
- BitMap* exp_card_bm) :
- _g1h(g1h), _cm(g1h->concurrent_mark()),
- _calc_cl(_cm->nextMarkBitMap(), g1h, exp_region_bm, exp_card_bm),
- _region_bm(region_bm), _card_bm(card_bm),
- _exp_region_bm(exp_region_bm), _exp_card_bm(exp_card_bm),
- _failures(0) { }
-
- int failures() const { return _failures; }
-
- bool doHeapRegion(HeapRegion* hr) {
- int failures = 0;
-
- // Call the CalcLiveObjectsClosure to walk the marking bitmap for
- // this region and set the corresponding bits in the expected region
- // and card bitmaps.
- bool res = _calc_cl.doHeapRegion(hr);
- assert(res == false, "should be continuing");
-
- // Verify the marked bytes for this region.
- size_t exp_marked_bytes = _calc_cl.region_marked_bytes();
- size_t act_marked_bytes = hr->next_marked_bytes();
-
- if (exp_marked_bytes > act_marked_bytes) {
- if (hr->is_starts_humongous()) {
- // For start_humongous regions, the size of the whole object will be
- // in exp_marked_bytes.
- HeapRegion* region = hr;
- int num_regions;
- for (num_regions = 0; region != NULL; num_regions++) {
- region = _g1h->next_region_in_humongous(region);
- }
- if ((num_regions-1) * HeapRegion::GrainBytes >= exp_marked_bytes) {
- failures += 1;
- } else if (num_regions * HeapRegion::GrainBytes < exp_marked_bytes) {
- failures += 1;
- }
- } else {
- // We're not OK if expected marked bytes > actual marked bytes. It means
- // we have missed accounting some objects during the actual marking.
- failures += 1;
- }
- }
-
- // Verify the bit, for this region, in the actual and expected
- // (which was just calculated) region bit maps.
- // We're not OK if the bit in the calculated expected region
- // bitmap is set and the bit in the actual region bitmap is not.
- BitMap::idx_t index = (BitMap::idx_t) hr->hrm_index();
-
- bool expected = _exp_region_bm->at(index);
- bool actual = _region_bm->at(index);
- if (expected && !actual) {
- failures += 1;
- }
-
- // Verify that the card bit maps for the cards spanned by the current
- // region match. We have an error if we have a set bit in the expected
- // bit map and the corresponding bit in the actual bitmap is not set.
-
- BitMap::idx_t start_idx = _cm->card_bitmap_index_for(hr->bottom());
- BitMap::idx_t end_idx = _cm->card_bitmap_index_for(hr->top());
-
- for (BitMap::idx_t i = start_idx; i < end_idx; i+=1) {
- expected = _exp_card_bm->at(i);
- actual = _card_bm->at(i);
-
- if (expected && !actual) {
- failures += 1;
- }
- }
-
- _failures += failures;
-
- // We could stop iteration over the heap when we
- // find the first violating region by returning true.
- return false;
- }
-};
-
-class G1ParVerifyFinalCountTask: public AbstractGangTask {
-protected:
- G1CollectedHeap* _g1h;
- G1ConcurrentMark* _cm;
- BitMap* _actual_region_bm;
- BitMap* _actual_card_bm;
-
- uint _n_workers;
-
- BitMap* _expected_region_bm;
- BitMap* _expected_card_bm;
-
- int _failures;
-
- HeapRegionClaimer _hrclaimer;
-
-public:
- G1ParVerifyFinalCountTask(G1CollectedHeap* g1h,
- BitMap* region_bm, BitMap* card_bm,
- BitMap* expected_region_bm, BitMap* expected_card_bm)
- : AbstractGangTask("G1 verify final counting"),
- _g1h(g1h), _cm(_g1h->concurrent_mark()),
- _actual_region_bm(region_bm), _actual_card_bm(card_bm),
- _expected_region_bm(expected_region_bm), _expected_card_bm(expected_card_bm),
- _failures(0),
- _n_workers(_g1h->workers()->active_workers()), _hrclaimer(_n_workers) {
- assert(VerifyDuringGC, "don't call this otherwise");
- assert(_expected_card_bm->size() == _actual_card_bm->size(), "sanity");
- assert(_expected_region_bm->size() == _actual_region_bm->size(), "sanity");
- }
-
- void work(uint worker_id) {
- assert(worker_id < _n_workers, "invariant");
-
- VerifyLiveObjectDataHRClosure verify_cl(_g1h,
- _actual_region_bm, _actual_card_bm,
- _expected_region_bm,
- _expected_card_bm);
-
- _g1h->heap_region_par_iterate(&verify_cl, worker_id, &_hrclaimer);
-
- Atomic::add(verify_cl.failures(), &_failures);
- }
-
- int failures() const { return _failures; }
-};
-
-// Closure that finalizes the liveness counting data.
-// Used during the cleanup pause.
-// Sets the bits corresponding to the interval [NTAMS, top]
-// (which contains the implicitly live objects) in the
-// card liveness bitmap. Also sets the bit for each region,
-// containing live data, in the region liveness bitmap.
-
-class FinalCountDataUpdateClosure: public G1CMCountDataClosureBase {
- public:
- FinalCountDataUpdateClosure(G1CollectedHeap* g1h,
- BitMap* region_bm,
- BitMap* card_bm) :
- G1CMCountDataClosureBase(g1h, region_bm, card_bm) { }
-
- bool doHeapRegion(HeapRegion* hr) {
- HeapWord* ntams = hr->next_top_at_mark_start();
- HeapWord* top = hr->top();
-
- assert(hr->bottom() <= ntams && ntams <= hr->end(), "Preconditions.");
-
- // Mark the allocated-since-marking portion...
- if (ntams < top) {
- // This definitely means the region has live objects.
- set_bit_for_region(hr);
-
- // Now set the bits in the card bitmap for [ntams, top)
- BitMap::idx_t start_idx = _cm->card_bitmap_index_for(ntams);
- BitMap::idx_t end_idx = _cm->card_bitmap_index_for(top);
-
- // Note: if we're looking at the last region in heap - top
- // could be actually just beyond the end of the heap; end_idx
- // will then correspond to a (non-existent) card that is also
- // just beyond the heap.
- if (_g1h->is_in_g1_reserved(top) && !_ct_bs->is_card_aligned(top)) {
- // end of object is not card aligned - increment to cover
- // all the cards spanned by the object
- end_idx += 1;
- }
-
- assert(end_idx <= _card_bm->size(),
- "oob: end_idx= " SIZE_FORMAT ", bitmap size= " SIZE_FORMAT,
- end_idx, _card_bm->size());
- assert(start_idx < _card_bm->size(),
- "oob: start_idx= " SIZE_FORMAT ", bitmap size= " SIZE_FORMAT,
- start_idx, _card_bm->size());
-
- _cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */);
- }
-
- // Set the bit for the region if it contains live data
- if (hr->next_marked_bytes() > 0) {
- set_bit_for_region(hr);
- }
-
- return false;
- }
-};
-
-class G1ParFinalCountTask: public AbstractGangTask {
-protected:
- G1CollectedHeap* _g1h;
- G1ConcurrentMark* _cm;
- BitMap* _actual_region_bm;
- BitMap* _actual_card_bm;
-
- uint _n_workers;
- HeapRegionClaimer _hrclaimer;
-
-public:
- G1ParFinalCountTask(G1CollectedHeap* g1h, BitMap* region_bm, BitMap* card_bm)
- : AbstractGangTask("G1 final counting"),
- _g1h(g1h), _cm(_g1h->concurrent_mark()),
- _actual_region_bm(region_bm), _actual_card_bm(card_bm),
- _n_workers(_g1h->workers()->active_workers()), _hrclaimer(_n_workers) {
- }
-
- void work(uint worker_id) {
- assert(worker_id < _n_workers, "invariant");
-
- FinalCountDataUpdateClosure final_update_cl(_g1h,
- _actual_region_bm,
- _actual_card_bm);
-
- _g1h->heap_region_par_iterate(&final_update_cl, worker_id, &_hrclaimer);
- }
-};
-
class G1NoteEndOfConcMarkClosure : public HeapRegionClosure {
G1CollectedHeap* _g1;
size_t _freed_bytes;
@@ -1637,31 +1247,16 @@
HeapRegionRemSet::reset_for_cleanup_tasks();
- // Do counting once more with the world stopped for good measure.
- G1ParFinalCountTask g1_par_count_task(g1h, &_region_bm, &_card_bm);
-
- g1h->workers()->run_task(&g1_par_count_task);
+ {
+ GCTraceTime(Debug, gc)("Finalize Live Data");
+ finalize_live_data();
+ }
if (VerifyDuringGC) {
- // Verify that the counting data accumulated during marking matches
- // that calculated by walking the marking bitmap.
-
- // Bitmaps to hold expected values
- BitMap expected_region_bm(_region_bm.size(), true);
- BitMap expected_card_bm(_card_bm.size(), true);
-
- G1ParVerifyFinalCountTask g1_par_verify_task(g1h,
- &_region_bm,
- &_card_bm,
- &expected_region_bm,
- &expected_card_bm);
-
- g1h->workers()->run_task(&g1_par_verify_task);
-
- guarantee(g1_par_verify_task.failures() == 0, "Unexpected accounting failures");
+ GCTraceTime(Debug, gc)("Verify Live Data");
+ verify_live_data();
}
- size_t start_used_bytes = g1h->used();
g1h->collector_state()->set_mark_in_progress(false);
double count_end = os::elapsedTime();
@@ -1696,7 +1291,7 @@
// regions.
if (G1ScrubRemSets) {
double rs_scrub_start = os::elapsedTime();
- g1h->scrub_rem_set(&_region_bm, &_card_bm);
+ g1h->scrub_rem_set();
_total_rs_scrub_time += (os::elapsedTime() - rs_scrub_start);
}
@@ -2160,7 +1755,7 @@
oop obj = static_cast<oop>(entry);
assert(obj->is_oop(true /* ignore mark word */),
"Invalid oop in SATB buffer: " PTR_FORMAT, p2i(obj));
- _task->make_reference_grey(obj, hr);
+ _task->make_reference_grey(obj);
}
}
@@ -2401,168 +1996,28 @@
}
}
#endif // PRODUCT
-
-// Aggregate the counting data that was constructed concurrently
-// with marking.
-class AggregateCountDataHRClosure: public HeapRegionClosure {
- G1CollectedHeap* _g1h;
- G1ConcurrentMark* _cm;
- CardTableModRefBS* _ct_bs;
- BitMap* _cm_card_bm;
- uint _max_worker_id;
-
- public:
- AggregateCountDataHRClosure(G1CollectedHeap* g1h,
- BitMap* cm_card_bm,
- uint max_worker_id) :
- _g1h(g1h), _cm(g1h->concurrent_mark()),
- _ct_bs(barrier_set_cast<CardTableModRefBS>(g1h->barrier_set())),
- _cm_card_bm(cm_card_bm), _max_worker_id(max_worker_id) { }
-
- bool doHeapRegion(HeapRegion* hr) {
- HeapWord* start = hr->bottom();
- HeapWord* limit = hr->next_top_at_mark_start();
- HeapWord* end = hr->end();
-
- assert(start <= limit && limit <= hr->top() && hr->top() <= hr->end(),
- "Preconditions not met - "
- "start: " PTR_FORMAT ", limit: " PTR_FORMAT ", "
- "top: " PTR_FORMAT ", end: " PTR_FORMAT,
- p2i(start), p2i(limit), p2i(hr->top()), p2i(hr->end()));
-
- assert(hr->next_marked_bytes() == 0, "Precondition");
-
- if (start == limit) {
- // NTAMS of this region has not been set so nothing to do.
- return false;
- }
-
- // 'start' should be in the heap.
- assert(_g1h->is_in_g1_reserved(start) && _ct_bs->is_card_aligned(start), "sanity");
- // 'end' *may* be just beyond the end of the heap (if hr is the last region)
- assert(!_g1h->is_in_g1_reserved(end) || _ct_bs->is_card_aligned(end), "sanity");
-
- BitMap::idx_t start_idx = _cm->card_bitmap_index_for(start);
- BitMap::idx_t limit_idx = _cm->card_bitmap_index_for(limit);
- BitMap::idx_t end_idx = _cm->card_bitmap_index_for(end);
-
- // If ntams is not card aligned then we bump card bitmap index
- // for limit so that we get the all the cards spanned by
- // the object ending at ntams.
- // Note: if this is the last region in the heap then ntams
- // could be actually just beyond the end of the the heap;
- // limit_idx will then correspond to a (non-existent) card
- // that is also outside the heap.
- if (_g1h->is_in_g1_reserved(limit) && !_ct_bs->is_card_aligned(limit)) {
- limit_idx += 1;
- }
-
- assert(limit_idx <= end_idx, "or else use atomics");
-
- // Aggregate the "stripe" in the count data associated with hr.
- uint hrm_index = hr->hrm_index();
- size_t marked_bytes = 0;
-
- for (uint i = 0; i < _max_worker_id; i += 1) {
- size_t* marked_bytes_array = _cm->count_marked_bytes_array_for(i);
- BitMap* task_card_bm = _cm->count_card_bitmap_for(i);
-
- // Fetch the marked_bytes in this region for task i and
- // add it to the running total for this region.
- marked_bytes += marked_bytes_array[hrm_index];
-
- // Now union the bitmaps[0,max_worker_id)[start_idx..limit_idx)
- // into the global card bitmap.
- BitMap::idx_t scan_idx = task_card_bm->get_next_one_offset(start_idx, limit_idx);
-
- while (scan_idx < limit_idx) {
- assert(task_card_bm->at(scan_idx) == true, "should be");
- _cm_card_bm->set_bit(scan_idx);
- assert(_cm_card_bm->at(scan_idx) == true, "should be");
-
- // BitMap::get_next_one_offset() can handle the case when
- // its left_offset parameter is greater than its right_offset
- // parameter. It does, however, have an early exit if
- // left_offset == right_offset. So let's limit the value
- // passed in for left offset here.
- BitMap::idx_t next_idx = MIN2(scan_idx + 1, limit_idx);
- scan_idx = task_card_bm->get_next_one_offset(next_idx, limit_idx);
- }
- }
-
- // Update the marked bytes for this region.
- hr->add_to_marked_bytes(marked_bytes);
-
- // Next heap region
- return false;
- }
-};
-
-class G1AggregateCountDataTask: public AbstractGangTask {
-protected:
- G1CollectedHeap* _g1h;
- G1ConcurrentMark* _cm;
- BitMap* _cm_card_bm;
- uint _max_worker_id;
- uint _active_workers;
- HeapRegionClaimer _hrclaimer;
-
-public:
- G1AggregateCountDataTask(G1CollectedHeap* g1h,
- G1ConcurrentMark* cm,
- BitMap* cm_card_bm,
- uint max_worker_id,
- uint n_workers) :
- AbstractGangTask("Count Aggregation"),
- _g1h(g1h), _cm(cm), _cm_card_bm(cm_card_bm),
- _max_worker_id(max_worker_id),
- _active_workers(n_workers),
- _hrclaimer(_active_workers) {
- }
-
- void work(uint worker_id) {
- AggregateCountDataHRClosure cl(_g1h, _cm_card_bm, _max_worker_id);
-
- _g1h->heap_region_par_iterate(&cl, worker_id, &_hrclaimer);
- }
-};
-
-
-void G1ConcurrentMark::aggregate_count_data() {
- uint n_workers = _g1h->workers()->active_workers();
-
- G1AggregateCountDataTask g1_par_agg_task(_g1h, this, &_card_bm,
- _max_worker_id, n_workers);
-
- _g1h->workers()->run_task(&g1_par_agg_task);
+void G1ConcurrentMark::create_live_data() {
+ _g1h->g1_rem_set()->create_card_live_data(_parallel_workers, _nextMarkBitMap);
+}
+
+void G1ConcurrentMark::finalize_live_data() {
+ _g1h->g1_rem_set()->finalize_card_live_data(_g1h->workers(), _nextMarkBitMap);
+}
+
+void G1ConcurrentMark::verify_live_data() {
+ _g1h->g1_rem_set()->verify_card_live_data(_g1h->workers(), _nextMarkBitMap);
}
-// Clear the per-worker arrays used to store the per-region counting data
-void G1ConcurrentMark::clear_all_count_data() {
- // Clear the global card bitmap - it will be filled during
- // liveness count aggregation (during remark) and the
- // final counting task.
- _card_bm.clear();
-
- // Clear the global region bitmap - it will be filled as part
- // of the final counting task.
- _region_bm.clear();
-
- uint max_regions = _g1h->max_regions();
- assert(_max_worker_id > 0, "uninitialized");
-
- for (uint i = 0; i < _max_worker_id; i += 1) {
- BitMap* task_card_bm = count_card_bitmap_for(i);
- size_t* marked_bytes_array = count_marked_bytes_array_for(i);
-
- assert(task_card_bm->size() == _card_bm.size(), "size mismatch");
- assert(marked_bytes_array != NULL, "uninitialized");
-
- memset(marked_bytes_array, 0, (size_t) max_regions * sizeof(size_t));
- task_card_bm->clear();
- }
+void G1ConcurrentMark::clear_live_data(WorkGang* workers) {
+ _g1h->g1_rem_set()->clear_card_live_data(workers);
}
+#ifdef ASSERT
+void G1ConcurrentMark::verify_live_data_clear() {
+ _g1h->g1_rem_set()->verify_card_live_data_is_clear();
+}
+#endif
+
void G1ConcurrentMark::print_stats() {
if (!log_is_enabled(Debug, gc, stats)) {
return;
@@ -2574,7 +2029,6 @@
}
}
-// abandon current marking iteration due to a Full GC
void G1ConcurrentMark::abort() {
if (!cmThread()->during_cycle() || _has_aborted) {
// We haven't started a concurrent cycle or we have already aborted it. No need to do anything.
@@ -2583,14 +2037,22 @@
// Clear all marks in the next bitmap for the next marking cycle. This will allow us to skip the next
// concurrent bitmap clearing.
- clear_bitmap(_nextMarkBitMap, _g1h->workers(), false);
-
+ {
+ GCTraceTime(Debug, gc)("Clear Next Bitmap");
+ clear_bitmap(_nextMarkBitMap, _g1h->workers(), false);
+ }
// Note we cannot clear the previous marking bitmap here
// since VerifyDuringGC verifies the objects marked during
// a full GC against the previous bitmap.
- // Clear the liveness counting data
- clear_all_count_data();
+ {
+ GCTraceTime(Debug, gc)("Clear Live Data");
+ clear_live_data(_g1h->workers());
+ }
+ DEBUG_ONLY({
+ GCTraceTime(Debug, gc)("Verify Live Data Clear");
+ verify_live_data_clear();
+ })
// Empty mark stack
reset_marking_state();
for (uint i = 0; i < _max_worker_id; ++i) {
@@ -2634,7 +2096,7 @@
}
print_ms_time_info(" ", "cleanups", _cleanup_times);
- log.trace(" Final counting total time = %8.2f s (avg = %8.2f ms).",
+ log.trace(" Finalize live data total time = %8.2f s (avg = %8.2f ms).",
_total_counting_time, (_cleanup_times.num() > 0 ? _total_counting_time * 1000.0 / (double)_cleanup_times.num() : 0.0));
if (G1ScrubRemSets) {
log.trace(" RS scrub total time = %8.2f s (avg = %8.2f ms).",
@@ -2650,6 +2112,10 @@
_parallel_workers->print_worker_threads_on(st);
}
+void G1ConcurrentMark::threads_do(ThreadClosure* tc) const {
+ _parallel_workers->threads_do(tc);
+}
+
void G1ConcurrentMark::print_on_error(outputStream* st) const {
st->print_cr("Marking Bits (Prev, Next): (CMBitMap*) " PTR_FORMAT ", (CMBitMap*) " PTR_FORMAT,
p2i(_prevMarkBitMap), p2i(_nextMarkBitMap));
@@ -2657,16 +2123,6 @@
_nextMarkBitMap->print_on_error(st, " Next Bits: ");
}
-// We take a break if someone is trying to stop the world.
-bool G1ConcurrentMark::do_yield_check(uint worker_id) {
- if (SuspendibleThreadSet::should_yield()) {
- SuspendibleThreadSet::yield();
- return true;
- } else {
- return false;
- }
-}
-
// Closure for iteration over bitmaps
class G1CMBitMapClosure : public BitMapClosure {
private:
@@ -3473,8 +2929,6 @@
G1CMTask::G1CMTask(uint worker_id,
G1ConcurrentMark* cm,
- size_t* marked_bytes,
- BitMap* card_bm,
G1CMTaskQueue* task_queue,
G1CMTaskQueueSet* task_queues)
: _g1h(G1CollectedHeap::heap()),
@@ -3483,9 +2937,7 @@
_nextMarkBitMap(NULL), _hash_seed(17),
_task_queue(task_queue),
_task_queues(task_queues),
- _cm_oop_closure(NULL),
- _marked_bytes_array(marked_bytes),
- _card_bm(card_bm) {
+ _cm_oop_closure(NULL) {
guarantee(task_queue != NULL, "invariant");
guarantee(task_queues != NULL, "invariant");
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -266,7 +266,7 @@
class G1ConcurrentMark: public CHeapObj<mtGC> {
friend class ConcurrentMarkThread;
friend class G1ParNoteEndTask;
- friend class CalcLiveObjectsClosure;
+ friend class G1VerifyLiveDataClosure;
friend class G1CMRefProcTaskProxy;
friend class G1CMRefProcTaskExecutor;
friend class G1CMKeepAliveAndDrainClosure;
@@ -298,9 +298,6 @@
G1CMBitMapRO* _prevMarkBitMap; // Completed mark bitmap
G1CMBitMap* _nextMarkBitMap; // Under-construction mark bitmap
- BitMap _region_bm;
- BitMap _card_bm;
-
// Heap bounds
HeapWord* _heap_start;
HeapWord* _heap_end;
@@ -461,23 +458,6 @@
void enter_first_sync_barrier(uint worker_id);
void enter_second_sync_barrier(uint worker_id);
- // Live Data Counting data structures...
- // These data structures are initialized at the start of
- // marking. They are written to while marking is active.
- // They are aggregated during remark; the aggregated values
- // are then used to populate the _region_bm, _card_bm, and
- // the total live bytes, which are then subsequently updated
- // during cleanup.
-
- // An array of bitmaps (one bit map per task). Each bitmap
- // is used to record the cards spanned by the live objects
- // marked by that task/worker.
- BitMap* _count_card_bitmaps;
-
- // Used to record the number of marked live bytes
- // (for each region, by worker thread).
- size_t** _count_marked_bytes;
-
// Card index of the bottom of the G1 heap. Used for biasing indices into
// the card bitmaps.
intptr_t _heap_bottom_card_num;
@@ -563,18 +543,10 @@
// G1CollectedHeap
// This notifies CM that a root during initial-mark needs to be
- // grayed. It is MT-safe. word_size is the size of the object in
- // words. It is passed explicitly as sometimes we cannot calculate
- // it from the given object because it might be in an inconsistent
- // state (e.g., in to-space and being copied). So the caller is
- // responsible for dealing with this issue (e.g., get the size from
- // the from-space image when the to-space image might be
- // inconsistent) and always passing the size. hr is the region that
+ // grayed. It is MT-safe. hr is the region that
// contains the object and it's passed optionally from callers who
// might already have it (no point in recalculating it).
inline void grayRoot(oop obj,
- size_t word_size,
- uint worker_id,
HeapRegion* hr = NULL);
// Prepare internal data structures for the next mark cycle. This includes clearing
@@ -603,7 +575,7 @@
void scan_root_regions();
// Scan a single root region and mark everything reachable from it.
- void scanRootRegion(HeapRegion* hr, uint worker_id);
+ void scanRootRegion(HeapRegion* hr);
// Do concurrent phase of marking, to a tentative transitive closure.
void mark_from_roots();
@@ -639,9 +611,9 @@
inline bool isPrevMarked(oop p) const;
- inline bool do_yield_check(uint worker_i = 0);
+ inline bool do_yield_check();
- // Called to abort the marking cycle after a Full GC takes place.
+ // Abandon current marking iteration due to a Full GC.
void abort();
bool has_aborted() { return _has_aborted; }
@@ -649,78 +621,12 @@
void print_summary_info();
void print_worker_threads_on(outputStream* st) const;
+ void threads_do(ThreadClosure* tc) const;
void print_on_error(outputStream* st) const;
- // Liveness counting
-
- // Utility routine to set an exclusive range of cards on the given
- // card liveness bitmap
- inline void set_card_bitmap_range(BitMap* card_bm,
- BitMap::idx_t start_idx,
- BitMap::idx_t end_idx,
- bool is_par);
-
- // Returns the card number of the bottom of the G1 heap.
- // Used in biasing indices into accounting card bitmaps.
- intptr_t heap_bottom_card_num() const {
- return _heap_bottom_card_num;
- }
-
- // Returns the card bitmap for a given task or worker id.
- BitMap* count_card_bitmap_for(uint worker_id) {
- assert(worker_id < _max_worker_id, "oob");
- assert(_count_card_bitmaps != NULL, "uninitialized");
- BitMap* task_card_bm = &_count_card_bitmaps[worker_id];
- assert(task_card_bm->size() == _card_bm.size(), "size mismatch");
- return task_card_bm;
- }
-
- // Returns the array containing the marked bytes for each region,
- // for the given worker or task id.
- size_t* count_marked_bytes_array_for(uint worker_id) {
- assert(worker_id < _max_worker_id, "oob");
- assert(_count_marked_bytes != NULL, "uninitialized");
- size_t* marked_bytes_array = _count_marked_bytes[worker_id];
- assert(marked_bytes_array != NULL, "uninitialized");
- return marked_bytes_array;
- }
-
- // Returns the index in the liveness accounting card table bitmap
- // for the given address
- inline BitMap::idx_t card_bitmap_index_for(HeapWord* addr);
-
- // Counts the size of the given memory region in the the given
- // marked_bytes array slot for the given HeapRegion.
- // Sets the bits in the given card bitmap that are associated with the
- // cards that are spanned by the memory region.
- inline void count_region(MemRegion mr,
- HeapRegion* hr,
- size_t* marked_bytes_array,
- BitMap* task_card_bm);
-
- // Counts the given object in the given task/worker counting
- // data structures.
- inline void count_object(oop obj,
- HeapRegion* hr,
- size_t* marked_bytes_array,
- BitMap* task_card_bm,
- size_t word_size);
-
- // Attempts to mark the given object and, if successful, counts
- // the object in the given task/worker counting structures.
- inline bool par_mark_and_count(oop obj,
- HeapRegion* hr,
- size_t* marked_bytes_array,
- BitMap* task_card_bm);
-
- // Attempts to mark the given object and, if successful, counts
- // the object in the task/worker counting structures for the
- // given worker id.
- inline bool par_mark_and_count(oop obj,
- size_t word_size,
- HeapRegion* hr,
- uint worker_id);
+ // Attempts to mark the given object on the next mark bitmap.
+ inline bool par_mark(oop obj);
// Returns true if initialization was successfully completed.
bool completed_initialization() const {
@@ -730,19 +636,22 @@
ConcurrentGCTimer* gc_timer_cm() const { return _gc_timer_cm; }
G1OldTracer* gc_tracer_cm() const { return _gc_tracer_cm; }
-protected:
- // Clear all the per-task bitmaps and arrays used to store the
- // counting data.
- void clear_all_count_data();
+private:
+ // Clear (Reset) all liveness count data.
+ void clear_live_data(WorkGang* workers);
- // Aggregates the counting data for each worker/task
- // that was constructed while marking. Also sets
- // the amount of marked bytes for each region and
- // the top at concurrent mark count.
- void aggregate_count_data();
+#ifdef ASSERT
+ // Verify all of the above data structures that they are in initial state.
+ void verify_live_data_clear();
+#endif
- // Verification routine
- void verify_count_data();
+ // Aggregates the per-card liveness data based on the current marking. Also sets
+ // the amount of marked bytes for each region.
+ void create_live_data();
+
+ void finalize_live_data();
+
+ void verify_live_data();
};
// A class representing a marking task.
@@ -844,12 +753,6 @@
TruncatedSeq _marking_step_diffs_ms;
- // Counting data structures. Embedding the task's marked_bytes_array
- // and card bitmap into the actual task saves having to go through
- // the ConcurrentMark object.
- size_t* _marked_bytes_array;
- BitMap* _card_bm;
-
// it updates the local fields after this task has claimed
// a new region to scan
void setup_for_region(HeapRegion* hr);
@@ -936,9 +839,8 @@
// Grey the object by marking it. If not already marked, push it on
// the local queue if below the finger.
- // Precondition: obj is in region.
- // Precondition: obj is below region's NTAMS.
- inline void make_reference_grey(oop obj, HeapRegion* region);
+ // obj is below its region's NTAMS.
+ inline void make_reference_grey(oop obj);
// Grey the object (by calling make_grey_reference) if required,
// e.g. obj is below its containing region's NTAMS.
@@ -976,8 +878,6 @@
G1CMTask(uint worker_id,
G1ConcurrentMark *cm,
- size_t* marked_bytes,
- BitMap* card_bm,
G1CMTaskQueue* task_queue,
G1CMTaskQueueSet* task_queues);
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -27,140 +27,11 @@
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1ConcurrentMark.hpp"
+#include "gc/g1/suspendibleThreadSet.hpp"
#include "gc/shared/taskqueue.inline.hpp"
-// Utility routine to set an exclusive range of cards on the given
-// card liveness bitmap
-inline void G1ConcurrentMark::set_card_bitmap_range(BitMap* card_bm,
- BitMap::idx_t start_idx,
- BitMap::idx_t end_idx,
- bool is_par) {
-
- // Set the exclusive bit range [start_idx, end_idx).
- assert((end_idx - start_idx) > 0, "at least one card");
- assert(end_idx <= card_bm->size(), "sanity");
-
- // Silently clip the end index
- end_idx = MIN2(end_idx, card_bm->size());
-
- // For small ranges use a simple loop; otherwise use set_range or
- // use par_at_put_range (if parallel). The range is made up of the
- // cards that are spanned by an object/mem region so 8 cards will
- // allow up to object sizes up to 4K to be handled using the loop.
- if ((end_idx - start_idx) <= 8) {
- for (BitMap::idx_t i = start_idx; i < end_idx; i += 1) {
- if (is_par) {
- card_bm->par_set_bit(i);
- } else {
- card_bm->set_bit(i);
- }
- }
- } else {
- // Note BitMap::par_at_put_range() and BitMap::set_range() are exclusive.
- if (is_par) {
- card_bm->par_at_put_range(start_idx, end_idx, true);
- } else {
- card_bm->set_range(start_idx, end_idx);
- }
- }
-}
-
-// Returns the index in the liveness accounting card bitmap
-// for the given address
-inline BitMap::idx_t G1ConcurrentMark::card_bitmap_index_for(HeapWord* addr) {
- // Below, the term "card num" means the result of shifting an address
- // by the card shift -- address 0 corresponds to card number 0. One
- // must subtract the card num of the bottom of the heap to obtain a
- // card table index.
- intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift);
- return card_num - heap_bottom_card_num();
-}
-
-// Counts the given memory region in the given task/worker
-// counting data structures.
-inline void G1ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr,
- size_t* marked_bytes_array,
- BitMap* task_card_bm) {
- G1CollectedHeap* g1h = _g1h;
- CardTableModRefBS* ct_bs = g1h->g1_barrier_set();
-
- HeapWord* start = mr.start();
- HeapWord* end = mr.end();
- size_t region_size_bytes = mr.byte_size();
- uint index = hr->hrm_index();
-
- assert(hr == g1h->heap_region_containing(start), "sanity");
- assert(marked_bytes_array != NULL, "pre-condition");
- assert(task_card_bm != NULL, "pre-condition");
-
- // Add to the task local marked bytes for this region.
- marked_bytes_array[index] += region_size_bytes;
-
- BitMap::idx_t start_idx = card_bitmap_index_for(start);
- BitMap::idx_t end_idx = card_bitmap_index_for(end);
-
- // Note: if we're looking at the last region in heap - end
- // could be actually just beyond the end of the heap; end_idx
- // will then correspond to a (non-existent) card that is also
- // just beyond the heap.
- if (g1h->is_in_g1_reserved(end) && !ct_bs->is_card_aligned(end)) {
- // end of region is not card aligned - increment to cover
- // all the cards spanned by the region.
- end_idx += 1;
- }
- // The card bitmap is task/worker specific => no need to use
- // the 'par' BitMap routines.
- // Set bits in the exclusive bit range [start_idx, end_idx).
- set_card_bitmap_range(task_card_bm, start_idx, end_idx, false /* is_par */);
-}
-
-// Counts the given object in the given task/worker counting data structures.
-inline void G1ConcurrentMark::count_object(oop obj,
- HeapRegion* hr,
- size_t* marked_bytes_array,
- BitMap* task_card_bm,
- size_t word_size) {
- assert(!hr->is_continues_humongous(), "Cannot enter count_object with continues humongous");
- if (!hr->is_starts_humongous()) {
- MemRegion mr((HeapWord*)obj, word_size);
- count_region(mr, hr, marked_bytes_array, task_card_bm);
- } else {
- do {
- MemRegion mr(hr->bottom(), hr->top());
- count_region(mr, hr, marked_bytes_array, task_card_bm);
- hr = _g1h->next_region_in_humongous(hr);
- } while (hr != NULL);
- }
-}
-
-// Attempts to mark the given object and, if successful, counts
-// the object in the given task/worker counting structures.
-inline bool G1ConcurrentMark::par_mark_and_count(oop obj,
- HeapRegion* hr,
- size_t* marked_bytes_array,
- BitMap* task_card_bm) {
- if (_nextMarkBitMap->parMark((HeapWord*)obj)) {
- // Update the task specific count data for the object.
- count_object(obj, hr, marked_bytes_array, task_card_bm, obj->size());
- return true;
- }
- return false;
-}
-
-// Attempts to mark the given object and, if successful, counts
-// the object in the task/worker counting structures for the
-// given worker id.
-inline bool G1ConcurrentMark::par_mark_and_count(oop obj,
- size_t word_size,
- HeapRegion* hr,
- uint worker_id) {
- if (_nextMarkBitMap->parMark((HeapWord*)obj)) {
- size_t* marked_bytes_array = count_marked_bytes_array_for(worker_id);
- BitMap* task_card_bm = count_card_bitmap_for(worker_id);
- count_object(obj, hr, marked_bytes_array, task_card_bm, word_size);
- return true;
- }
- return false;
+inline bool G1ConcurrentMark::par_mark(oop obj) {
+ return _nextMarkBitMap->parMark((HeapWord*)obj);
}
inline bool G1CMBitMapRO::iterate(BitMapClosure* cl, MemRegion mr) {
@@ -294,10 +165,8 @@
check_limits();
}
-
-
-inline void G1CMTask::make_reference_grey(oop obj, HeapRegion* hr) {
- if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, _card_bm)) {
+inline void G1CMTask::make_reference_grey(oop obj) {
+ if (_cm->par_mark(obj)) {
// No OrderAccess:store_load() is needed. It is implicit in the
// CAS done in G1CMBitMap::parMark() call in the routine above.
HeapWord* global_finger = _cm->finger();
@@ -348,7 +217,7 @@
// anything with it).
HeapRegion* hr = _g1h->heap_region_containing(obj);
if (!hr->obj_allocated_since_next_marking(obj)) {
- make_reference_grey(obj, hr);
+ make_reference_grey(obj);
}
}
}
@@ -370,8 +239,7 @@
return _prevMarkBitMap->isMarked(addr);
}
-inline void G1ConcurrentMark::grayRoot(oop obj, size_t word_size,
- uint worker_id, HeapRegion* hr) {
+inline void G1ConcurrentMark::grayRoot(oop obj, HeapRegion* hr) {
assert(obj != NULL, "pre-condition");
HeapWord* addr = (HeapWord*) obj;
if (hr == NULL) {
@@ -386,9 +254,18 @@
if (addr < hr->next_top_at_mark_start()) {
if (!_nextMarkBitMap->isMarked(addr)) {
- par_mark_and_count(obj, word_size, hr, worker_id);
+ par_mark(obj);
}
}
}
+inline bool G1ConcurrentMark::do_yield_check() {
+ if (SuspendibleThreadSet::should_yield()) {
+ SuspendibleThreadSet::yield();
+ return true;
+ } else {
+ return false;
+ }
+}
+
#endif // SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP
--- a/hotspot/src/share/vm/gc/g1/g1EvacFailure.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1EvacFailure.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -95,8 +95,6 @@
void do_object(oop obj) {
HeapWord* obj_addr = (HeapWord*) obj;
assert(_hr->is_in(obj_addr), "sanity");
- size_t obj_size = obj->size();
- HeapWord* obj_end = obj_addr + obj_size;
if (obj->is_forwarded() && obj->forwardee() == obj) {
// The object failed to move.
@@ -119,8 +117,10 @@
// explicitly and all objects in the CSet are considered
// (implicitly) live. So, we won't mark them explicitly and
// we'll leave them over NTAMS.
- _cm->grayRoot(obj, obj_size, _worker_id, _hr);
+ _cm->grayRoot(obj, _hr);
}
+ size_t obj_size = obj->size();
+
_marked_bytes += (obj_size * HeapWordSize);
obj->set_mark(markOopDesc::prototype());
@@ -138,6 +138,7 @@
// the collection set. So, we'll recreate such entries now.
obj->oop_iterate(_update_rset_cl);
+ HeapWord* obj_end = obj_addr + obj_size;
_last_forwarded_object_end = obj_end;
_hr->cross_threshold(obj_addr, obj_end);
}
--- a/hotspot/src/share/vm/gc/g1/g1OopClosures.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1OopClosures.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -186,11 +186,9 @@
private:
G1CollectedHeap* _g1h;
G1ConcurrentMark* _cm;
- uint _worker_id;
public:
- G1RootRegionScanClosure(G1CollectedHeap* g1h, G1ConcurrentMark* cm,
- uint worker_id) :
- _g1h(g1h), _cm(cm), _worker_id(worker_id) { }
+ G1RootRegionScanClosure(G1CollectedHeap* g1h, G1ConcurrentMark* cm) :
+ _g1h(g1h), _cm(cm) { }
template <class T> void do_oop_nv(T* p);
virtual void do_oop( oop* p) { do_oop_nv(p); }
virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
--- a/hotspot/src/share/vm/gc/g1/g1OopClosures.inline.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1OopClosures.inline.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -131,7 +131,7 @@
if (!oopDesc::is_null(heap_oop)) {
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
HeapRegion* hr = _g1h->heap_region_containing((HeapWord*) obj);
- _cm->grayRoot(obj, obj->size(), _worker_id, hr);
+ _cm->grayRoot(obj, hr);
}
}
@@ -246,7 +246,7 @@
assert(!_g1->heap_region_containing(obj)->in_collection_set(), "should not mark objects in the CSet");
// We know that the object is not moving so it's safe to read its size.
- _cm->grayRoot(obj, (size_t) obj->size(), _worker_id);
+ _cm->grayRoot(obj);
}
void G1ParCopyHelper::mark_forwarded_object(oop from_obj, oop to_obj) {
@@ -261,7 +261,7 @@
// worker so we cannot trust that its to-space image is
// well-formed. So we have to read its size from its from-space
// image which we know should not be changing.
- _cm->grayRoot(to_obj, (size_t) from_obj->size(), _worker_id);
+ _cm->grayRoot(to_obj);
}
template <G1Barrier barrier, G1Mark do_mark_object, bool use_ext>
--- a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -38,6 +38,7 @@
#include "gc/g1/heapRegion.inline.hpp"
#include "gc/g1/heapRegionManager.inline.hpp"
#include "gc/g1/heapRegionRemSet.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
#include "memory/iterator.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
@@ -84,8 +85,16 @@
return MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads);
}
-void G1RemSet::initialize(uint max_regions) {
+void G1RemSet::initialize(size_t capacity, uint max_regions) {
G1FromCardCache::initialize(num_par_rem_sets(), max_regions);
+ {
+ GCTraceTime(Debug, gc, marking)("Initialize Card Live Data");
+ _card_live_data.initialize(capacity, max_regions);
+ }
+ if (G1PretouchAuxiliaryMemory) {
+ GCTraceTime(Debug, gc, marking)("Pre-Touch Card Live Data");
+ _card_live_data.pretouch();
+ }
}
ScanRSClosure::ScanRSClosure(G1ParPushHeapRSClosure* oc,
@@ -312,27 +321,24 @@
_into_cset_dirty_card_queue_set.clear_n_completed_buffers();
}
-class ScrubRSClosure: public HeapRegionClosure {
+class G1ScrubRSClosure: public HeapRegionClosure {
G1CollectedHeap* _g1h;
- BitMap* _region_bm;
- BitMap* _card_bm;
- CardTableModRefBS* _ctbs;
+ G1CardLiveData* _live_data;
public:
- ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) :
+ G1ScrubRSClosure(G1CardLiveData* live_data) :
_g1h(G1CollectedHeap::heap()),
- _region_bm(region_bm), _card_bm(card_bm),
- _ctbs(_g1h->g1_barrier_set()) {}
+ _live_data(live_data) { }
bool doHeapRegion(HeapRegion* r) {
if (!r->is_continues_humongous()) {
- r->rem_set()->scrub(_ctbs, _region_bm, _card_bm);
+ r->rem_set()->scrub(_live_data);
}
return false;
}
};
-void G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm, uint worker_num, HeapRegionClaimer *hrclaimer) {
- ScrubRSClosure scrub_cl(region_bm, card_bm);
+void G1RemSet::scrub(uint worker_num, HeapRegionClaimer *hrclaimer) {
+ G1ScrubRSClosure scrub_cl(&_card_live_data);
_g1->heap_region_par_iterate(&scrub_cl, worker_num, hrclaimer);
}
@@ -580,3 +586,25 @@
assert(JavaThread::dirty_card_queue_set().completed_buffers_num() == 0, "All should be consumed");
}
}
+
+void G1RemSet::create_card_live_data(WorkGang* workers, G1CMBitMap* mark_bitmap) {
+ _card_live_data.create(workers, mark_bitmap);
+}
+
+void G1RemSet::finalize_card_live_data(WorkGang* workers, G1CMBitMap* mark_bitmap) {
+ _card_live_data.finalize(workers, mark_bitmap);
+}
+
+void G1RemSet::verify_card_live_data(WorkGang* workers, G1CMBitMap* bitmap) {
+ _card_live_data.verify(workers, bitmap);
+}
+
+void G1RemSet::clear_card_live_data(WorkGang* workers) {
+ _card_live_data.clear(workers);
+}
+
+#ifdef ASSERT
+void G1RemSet::verify_card_live_data_is_clear() {
+ _card_live_data.verify_is_clear();
+}
+#endif
--- a/hotspot/src/share/vm/gc/g1/g1RemSet.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1RemSet.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -26,6 +26,7 @@
#define SHARE_VM_GC_G1_G1REMSET_HPP
#include "gc/g1/dirtyCardQueue.hpp"
+#include "gc/g1/g1CardLiveData.hpp"
#include "gc/g1/g1RemSetSummary.hpp"
#include "gc/g1/heapRegion.hpp"
#include "memory/allocation.hpp"
@@ -48,9 +49,10 @@
// A G1RemSet in which each heap region has a rem set that records the
// external heap references into it. Uses a mod ref bs to track updates,
// so that they can be used to update the individual region remsets.
-
class G1RemSet: public CHeapObj<mtGC> {
private:
+ G1CardLiveData _card_live_data;
+
G1RemSetSummary _prev_period_summary;
// A DirtyCardQueueSet that is used to hold cards that contain
@@ -83,7 +85,7 @@
static uint num_par_rem_sets();
// Initialize data that depends on the heap size being known.
- static void initialize(uint max_regions);
+ void initialize(size_t capacity, uint max_regions);
// This is called to reset dual hash tables after the gc pause
// is finished and the initial hash table is no longer being
@@ -140,7 +142,7 @@
// set entries that correspond to dead heap ranges. "worker_num" is the
// parallel thread id of the current thread, and "hrclaimer" is the
// HeapRegionClaimer that should be used.
- void scrub(BitMap* region_bm, BitMap* card_bm, uint worker_num, HeapRegionClaimer* hrclaimer);
+ void scrub(uint worker_num, HeapRegionClaimer* hrclaimer);
// Refine the card corresponding to "card_ptr".
// If check_for_refs_into_cset is true, a true result is returned
@@ -162,6 +164,19 @@
size_t conc_refine_cards() const {
return _conc_refine_cards;
}
+
+ void create_card_live_data(WorkGang* workers, G1CMBitMap* mark_bitmap);
+ void finalize_card_live_data(WorkGang* workers, G1CMBitMap* mark_bitmap);
+
+ // Verify that the liveness count data created concurrently matches one created
+ // during this safepoint.
+ void verify_card_live_data(WorkGang* workers, G1CMBitMap* actual_bitmap);
+
+ void clear_card_live_data(WorkGang* workers);
+
+#ifdef ASSERT
+ void verify_card_live_data_is_clear();
+#endif
};
class ScanRSClosure : public HeapRegionClosure {
--- a/hotspot/src/share/vm/gc/g1/g1YoungGenSizer.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1YoungGenSizer.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -25,12 +25,13 @@
#include "precompiled.hpp"
#include "gc/g1/g1YoungGenSizer.hpp"
#include "gc/g1/heapRegion.hpp"
+#include "logging/log.hpp"
G1YoungGenSizer::G1YoungGenSizer() : _sizer_kind(SizerDefaults), _adaptive_size(true),
_min_desired_young_length(0), _max_desired_young_length(0) {
if (FLAG_IS_CMDLINE(NewRatio)) {
if (FLAG_IS_CMDLINE(NewSize) || FLAG_IS_CMDLINE(MaxNewSize)) {
- warning("-XX:NewSize and -XX:MaxNewSize override -XX:NewRatio");
+ log_warning(gc, ergo)("-XX:NewSize and -XX:MaxNewSize override -XX:NewRatio");
} else {
_sizer_kind = SizerNewRatio;
_adaptive_size = false;
@@ -40,9 +41,9 @@
if (NewSize > MaxNewSize) {
if (FLAG_IS_CMDLINE(MaxNewSize)) {
- warning("NewSize (" SIZE_FORMAT "k) is greater than the MaxNewSize (" SIZE_FORMAT "k). "
- "A new max generation size of " SIZE_FORMAT "k will be used.",
- NewSize/K, MaxNewSize/K, NewSize/K);
+ log_warning(gc, ergo)("NewSize (" SIZE_FORMAT "k) is greater than the MaxNewSize (" SIZE_FORMAT "k). "
+ "A new max generation size of " SIZE_FORMAT "k will be used.",
+ NewSize/K, MaxNewSize/K, NewSize/K);
}
MaxNewSize = NewSize;
}
--- a/hotspot/src/share/vm/gc/g1/g1_globals.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1_globals.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -112,8 +112,7 @@
product(size_t, G1ConcRefinementRedZone, 0, \
"Maximum number of enqueued update buffers before mutator " \
"threads start processing new ones instead of enqueueing them. " \
- "Will be selected ergonomically by default. Zero will disable " \
- "concurrent processing.") \
+ "Will be selected ergonomically by default.") \
range(0, max_intx) \
\
product(size_t, G1ConcRefinementGreenZone, 0, \
@@ -127,11 +126,12 @@
"specified number of milliseconds to do miscellaneous work.") \
range(0, max_jint) \
\
- product(size_t, G1ConcRefinementThresholdStep, 0, \
+ product(size_t, G1ConcRefinementThresholdStep, 2, \
"Each time the rset update queue increases by this amount " \
"activate the next refinement thread if available. " \
- "Will be selected ergonomically by default.") \
- range(0, SIZE_MAX) \
+ "The actual step size will be selected ergonomically by " \
+ "default, with this value used to determine a lower bound.") \
+ range(1, SIZE_MAX) \
\
product(intx, G1RSetUpdatingPauseTimePercent, 10, \
"A target percentage of time that is allowed to be spend on " \
@@ -201,9 +201,9 @@
range(0, 32*M) \
constraint(G1HeapRegionSizeConstraintFunc,AfterMemoryInit) \
\
- product(uintx, G1ConcRefinementThreads, 0, \
- "If non-0 is the number of parallel rem set update threads, " \
- "otherwise the value is determined ergonomically.") \
+ product(uint, G1ConcRefinementThreads, 0, \
+ "The number of parallel rem set update threads. " \
+ "Will be set ergonomically by default.") \
range(0, (max_jint-1)/wordSize) \
\
develop(bool, G1VerifyCTCleanup, false, \
@@ -260,6 +260,9 @@
"The target number of mixed GCs after a marking cycle.") \
range(0, max_uintx) \
\
+ experimental(bool, G1PretouchAuxiliaryMemory, false, \
+ "Pre-touch large auxiliary data structures used by the GC.") \
+ \
experimental(bool, G1EagerReclaimHumongousObjects, true, \
"Try to reclaim dead large objects at every young GC.") \
\
--- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -26,6 +26,7 @@
#include "gc/g1/concurrentG1Refine.hpp"
#include "gc/g1/g1BlockOffsetTable.inline.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1CardLiveData.inline.hpp"
#include "gc/g1/heapRegionManager.inline.hpp"
#include "gc/g1/heapRegionRemSet.hpp"
#include "gc/shared/space.inline.hpp"
@@ -141,10 +142,8 @@
add_reference_work(from, /*parallel*/ false);
}
- void scrub(CardTableModRefBS* ctbs, BitMap* card_bm) {
- HeapWord* hr_bot = hr()->bottom();
- size_t hr_first_card_index = ctbs->index_for(hr_bot);
- bm()->set_intersection_at_offset(*card_bm, hr_first_card_index);
+ void scrub(G1CardLiveData* live_data) {
+ live_data->remove_nonlive_cards(hr()->hrm_index(), &_bm);
recount_occupied();
}
@@ -515,14 +514,12 @@
return max;
}
-void OtherRegionsTable::scrub(CardTableModRefBS* ctbs,
- BitMap* region_bm, BitMap* card_bm) {
+void OtherRegionsTable::scrub(G1CardLiveData* live_data) {
// First eliminated garbage regions from the coarse map.
log_develop_trace(gc, remset, scrub)("Scrubbing region %u:", _hr->hrm_index());
- assert(_coarse_map.size() == region_bm->size(), "Precondition");
log_develop_trace(gc, remset, scrub)(" Coarse map: before = " SIZE_FORMAT "...", _n_coarse_entries);
- _coarse_map.set_intersection(*region_bm);
+ live_data->remove_nonlive_regions(&_coarse_map);
_n_coarse_entries = _coarse_map.count_one_bits();
log_develop_trace(gc, remset, scrub)(" after = " SIZE_FORMAT ".", _n_coarse_entries);
@@ -534,7 +531,7 @@
PerRegionTable* nxt = cur->collision_list_next();
// If the entire region is dead, eliminate.
log_develop_trace(gc, remset, scrub)(" For other region %u:", cur->hr()->hrm_index());
- if (!region_bm->at((size_t) cur->hr()->hrm_index())) {
+ if (!live_data->is_region_live(cur->hr()->hrm_index())) {
*prev = nxt;
cur->set_collision_list_next(NULL);
_n_fine_entries--;
@@ -544,7 +541,7 @@
} else {
// Do fine-grain elimination.
log_develop_trace(gc, remset, scrub)(" occ: before = %4d.", cur->occupied());
- cur->scrub(ctbs, card_bm);
+ cur->scrub(live_data);
log_develop_trace(gc, remset, scrub)(" after = %4d.", cur->occupied());
// Did that empty the table completely?
if (cur->occupied() == 0) {
@@ -773,9 +770,8 @@
assert(verify_ready_for_par_iteration(), "post-condition");
}
-void HeapRegionRemSet::scrub(CardTableModRefBS* ctbs,
- BitMap* region_bm, BitMap* card_bm) {
- _other_regions.scrub(ctbs, region_bm, card_bm);
+void HeapRegionRemSet::scrub(G1CardLiveData* live_data) {
+ _other_regions.scrub(live_data);
}
// Code roots support
--- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -35,6 +35,7 @@
class G1CollectedHeap;
class G1BlockOffsetTable;
+class G1CardLiveData;
class HeapRegion;
class HeapRegionRemSetIterator;
class PerRegionTable;
@@ -143,7 +144,7 @@
// Removes any entries shown by the given bitmaps to contain only dead
// objects. Not thread safe.
// Set bits in the bitmaps indicate that the given region or card is live.
- void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm);
+ void scrub(G1CardLiveData* live_data);
// Returns whether this remembered set (and all sub-sets) does not contain any entry.
bool is_empty() const;
@@ -230,10 +231,9 @@
_other_regions.add_reference(from, tid);
}
- // Removes any entries in the remembered set shown by the given bitmaps to
+ // Removes any entries in the remembered set shown by the given card live data to
// contain only dead objects. Not thread safe.
- // One bits in the bitmaps indicate that the given region or card is live.
- void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm);
+ void scrub(G1CardLiveData* live_data);
// The region is being reclaimed; clear its remset, and any mention of
// entries for this region in other remsets.
--- a/hotspot/src/share/vm/gc/parallel/generationSizer.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/parallel/generationSizer.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -26,18 +26,6 @@
#include "gc/parallel/generationSizer.hpp"
#include "gc/shared/collectorPolicy.hpp"
-void GenerationSizer::trace_gen_sizes(const char* const str) {
- if (TracePageSizes) {
- tty->print_cr("%s: " SIZE_FORMAT "," SIZE_FORMAT " "
- SIZE_FORMAT "," SIZE_FORMAT " "
- SIZE_FORMAT,
- str,
- _min_old_size / K, _max_old_size / K,
- _min_young_size / K, _max_young_size / K,
- _max_heap_byte_size / K);
- }
-}
-
void GenerationSizer::initialize_alignments() {
_space_alignment = _gen_alignment = default_gen_alignment();
_heap_alignment = compute_heap_alignment();
@@ -60,7 +48,6 @@
}
void GenerationSizer::initialize_size_info() {
- trace_gen_sizes("ps heap raw");
const size_t max_page_sz = os::page_size_for_region_aligned(_max_heap_byte_size, 8);
const size_t min_pages = 4; // 1 for eden + 1 for each survivor + 1 for old
const size_t min_page_sz = os::page_size_for_region_aligned(_min_heap_byte_size, min_pages);
@@ -76,6 +63,4 @@
initialize_flags();
}
GenCollectorPolicy::initialize_size_info();
-
- trace_gen_sizes("ps heap rnd");
}
--- a/hotspot/src/share/vm/gc/parallel/generationSizer.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/parallel/generationSizer.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -33,8 +33,6 @@
class GenerationSizer : public GenCollectorPolicy {
private:
- void trace_gen_sizes(const char* const str);
-
// The alignment used for boundary between young gen and old gen
static size_t default_gen_alignment() { return 64 * K * HeapWordSize; }
--- a/hotspot/src/share/vm/gc/parallel/parMarkBitMap.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/parallel/parMarkBitMap.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -49,7 +49,7 @@
const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :
MAX2(page_sz, granularity);
ReservedSpace rs(_reserved_byte_size, rs_align, rs_align > 0);
- os::trace_page_sizes("par bitmap", raw_bytes, raw_bytes, page_sz,
+ os::trace_page_sizes("Mark Bitmap", raw_bytes, raw_bytes, page_sz,
rs.base(), rs.size());
MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
--- a/hotspot/src/share/vm/gc/parallel/parallelScavengeHeap.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/parallel/parallelScavengeHeap.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -60,8 +60,10 @@
ReservedSpace heap_rs = Universe::reserve_heap(heap_size, _collector_policy->heap_alignment());
- os::trace_page_sizes("ps main", _collector_policy->min_heap_byte_size(),
- heap_size, generation_alignment(),
+ os::trace_page_sizes("Heap",
+ _collector_policy->min_heap_byte_size(),
+ heap_size,
+ generation_alignment(),
heap_rs.base(),
heap_rs.size());
--- a/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -32,7 +32,6 @@
#include "gc/shared/gcPolicyCounters.hpp"
#include "logging/log.hpp"
#include "runtime/timer.hpp"
-#include "utilities/top.hpp"
#include <math.h>
--- a/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -426,7 +426,7 @@
const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :
MAX2(page_sz, granularity);
ReservedSpace rs(_reserved_byte_size, rs_align, rs_align > 0);
- os::trace_page_sizes("par compact", raw_bytes, raw_bytes, page_sz, rs.base(),
+ os::trace_page_sizes("Parallel Compact Data", raw_bytes, raw_bytes, page_sz, rs.base(),
rs.size());
MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
--- a/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -692,7 +692,7 @@
_promo_failure_scan_stack.clear(true); // Clear cached segments.
remove_forwarding_pointers();
- log_debug(gc)("Promotion failed");
+ log_info(gc, promotion)("Promotion failed");
// Add to-space to the list of space to compact
// when a promotion failure has occurred. In that
// case there can be live objects in to-space
@@ -739,8 +739,7 @@
eden()->object_iterate(&rspc);
from()->object_iterate(&rspc);
- // Now restore saved marks, if any.
- _preserved_marks_set.restore();
+ _preserved_marks_set.restore(GenCollectedHeap::heap()->workers());
}
void DefNewGeneration::handle_promotion_failure(oop old) {
--- a/hotspot/src/share/vm/gc/shared/cardTableModRefBS.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/cardTableModRefBS.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -93,7 +93,7 @@
MemTracker::record_virtual_memory_type((address)heap_rs.base(), mtGC);
- os::trace_page_sizes("card table", _guard_index + 1, _guard_index + 1,
+ os::trace_page_sizes("Card Table", _guard_index + 1, _guard_index + 1,
_page_size, heap_rs.base(), heap_rs.size());
if (!heap_rs.is_reserved()) {
vm_exit_during_initialization("Could not reserve enough space for the "
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -167,6 +167,14 @@
SIZE_FORMAT, total_reserved, alignment);
*heap_rs = Universe::reserve_heap(total_reserved, alignment);
+
+ os::trace_page_sizes("Heap",
+ collector_policy()->min_heap_byte_size(),
+ total_reserved,
+ alignment,
+ heap_rs->base(),
+ heap_rs->size());
+
return heap_rs->base();
}
--- a/hotspot/src/share/vm/gc/shared/preservedMarks.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/preservedMarks.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -24,24 +24,30 @@
#include "precompiled.hpp"
#include "gc/shared/preservedMarks.inline.hpp"
+#include "gc/shared/workgroup.hpp"
#include "memory/allocation.inline.hpp"
-#include "oops/oop.inline.hpp"
void PreservedMarks::restore() {
- // First, iterate over the stack and restore all marks.
- StackIterator<OopAndMarkOop, mtGC> iter(_stack);
- while (!iter.is_empty()) {
- OopAndMarkOop elem = iter.next();
+ while (!_stack.is_empty()) {
+ const OopAndMarkOop elem = _stack.pop();
elem.set_mark();
}
+ assert_empty();
+}
- // Second, reclaim all the stack memory
- _stack.clear(true /* clear_cache */);
+#ifndef PRODUCT
+void PreservedMarks::assert_empty() {
+ assert(_stack.is_empty(), "stack expected to be empty, size = "SIZE_FORMAT,
+ _stack.size());
+ assert(_stack.cache_size() == 0,
+ "stack expected to have no cached segments, cache size = "SIZE_FORMAT,
+ _stack.cache_size());
}
+#endif // ndef PRODUCT
void RemoveForwardedPointerClosure::do_object(oop obj) {
if (obj->is_forwarded()) {
- obj->init_mark();
+ PreservedMarks::init_forwarded_mark(obj);
}
}
@@ -61,15 +67,48 @@
assert_empty();
}
+class ParRestoreTask : public AbstractGangTask {
+private:
+ PreservedMarksSet* const _preserved_marks_set;
+ SequentialSubTasksDone _sub_tasks;
+ volatile size_t* const _total_size_addr;
+
+public:
+ virtual void work(uint worker_id) {
+ uint task_id = 0;
+ while (!_sub_tasks.is_task_claimed(/* reference */ task_id)) {
+ PreservedMarks* const preserved_marks = _preserved_marks_set->get(task_id);
+ const size_t size = preserved_marks->size();
+ preserved_marks->restore();
+ // Only do the atomic add if the size is > 0.
+ if (size > 0) {
+ Atomic::add(size, _total_size_addr);
+ }
+ }
+ _sub_tasks.all_tasks_completed();
+ }
+
+ ParRestoreTask(uint worker_num,
+ PreservedMarksSet* preserved_marks_set,
+ volatile size_t* total_size_addr)
+ : AbstractGangTask("Parallel Preserved Mark Restoration"),
+ _preserved_marks_set(preserved_marks_set),
+ _total_size_addr(total_size_addr) {
+ _sub_tasks.set_n_threads(worker_num);
+ _sub_tasks.set_n_tasks(preserved_marks_set->num());
+ }
+};
+
+void PreservedMarksSet::restore_internal(WorkGang* workers,
+ volatile size_t* total_size_addr) {
+ assert(workers != NULL, "pre-condition");
+ ParRestoreTask task(workers->active_workers(), this, total_size_addr);
+ workers->run_task(&task);
+}
+
+// temporary, used by PS
void PreservedMarksSet::restore() {
- size_t total_size = 0;
- for (uint i = 0; i < _num; i += 1) {
- total_size += get(i)->size();
- get(i)->restore();
- }
- assert_empty();
-
- log_trace(gc)("Restored " SIZE_FORMAT " marks", total_size);
+ restore<WorkGang>(NULL);
}
void PreservedMarksSet::reclaim() {
@@ -92,7 +131,7 @@
void PreservedMarksSet::assert_empty() {
assert(_stacks != NULL && _num > 0, "should have been initialized");
for (uint i = 0; i < _num; i += 1) {
- assert(get(i)->is_empty(), "stack should be empty");
+ get(i)->assert_empty();
}
}
#endif // ndef PRODUCT
--- a/hotspot/src/share/vm/gc/shared/preservedMarks.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/preservedMarks.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -44,6 +44,8 @@
};
typedef Stack<OopAndMarkOop, mtGC> OopAndMarkOopStack;
+class WorkGang;
+
class PreservedMarks VALUE_OBJ_CLASS_SPEC {
private:
OopAndMarkOopStack _stack;
@@ -52,13 +54,19 @@
inline void push(oop obj, markOop m);
public:
- bool is_empty() const { return _stack.is_empty(); }
size_t size() const { return _stack.size(); }
inline void push_if_necessary(oop obj, markOop m);
- // Iterate over the stack, restore the preserved marks, then reclaim
- // the memory taken up by stack chunks.
+ // Iterate over the stack, restore all preserved marks, and
+ // reclaim the memory taken up by the stack segments.
void restore();
- ~PreservedMarks() { assert(is_empty(), "should have been cleared"); }
+
+ inline static void init_forwarded_mark(oop obj);
+
+ // Assert the stack is empty and has no cached segments.
+ void assert_empty() PRODUCT_RETURN;
+
+ inline PreservedMarks();
+ ~PreservedMarks() { assert_empty(); }
};
class RemoveForwardedPointerClosure: public ObjectClosure {
@@ -82,7 +90,12 @@
// or == NULL if they have not.
Padded<PreservedMarks>* _stacks;
+ // Internal version of restore() that uses a WorkGang for parallelism.
+ void restore_internal(WorkGang* workers, volatile size_t* total_size_addr);
+
public:
+ uint num() const { return _num; }
+
// Return the i'th stack.
PreservedMarks* get(uint i = 0) const {
assert(_num > 0 && _stacks != NULL, "stacks should have been initialized");
@@ -92,13 +105,23 @@
// Allocate stack array.
void init(uint num);
- // Iterate over all stacks, restore all preserved marks, then
- // reclaim the memory taken up by stack chunks.
+
+ // Itrerate over all stacks, restore all presered marks, and reclaim
+ // the memory taken up by the stack segments. If the executor is
+ // NULL, restoration will be done serially. If the executor is not
+ // NULL, restoration could be done in parallel (when it makes
+ // sense). Supported executors: WorkGang (Serial, CMS, G1)
+ template <class E>
+ inline void restore(E* executor);
+
+ // Do the restoration serially. Temporary, to be used by PS until we
+ // can support GCTaskManager in restore(E*).
void restore();
+
// Reclaim stack array.
void reclaim();
- // Assert all the stacks are empty.
+ // Assert all the stacks are empty and have no cached segments.
void assert_empty() PRODUCT_RETURN;
PreservedMarksSet(bool in_c_heap)
--- a/hotspot/src/share/vm/gc/shared/preservedMarks.inline.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/preservedMarks.inline.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -22,13 +22,13 @@
*
*/
-#include "gc/shared/preservedMarks.hpp"
-#include "oops/markOop.inline.hpp"
-#include "utilities/stack.inline.hpp"
-
#ifndef SHARE_VM_GC_SHARED_PRESERVEDMARKS_INLINE_HPP
#define SHARE_VM_GC_SHARED_PRESERVEDMARKS_INLINE_HPP
+#include "gc/shared/preservedMarks.hpp"
+#include "oops/oop.inline.hpp"
+#include "utilities/stack.inline.hpp"
+
inline bool PreservedMarks::should_preserve_mark(oop obj, markOop m) const {
return m->must_be_preserved_for_promotion_failure(obj);
}
@@ -45,4 +45,48 @@
}
}
+inline void PreservedMarks::init_forwarded_mark(oop obj) {
+ obj->init_mark();
+}
+
+template <class E>
+inline void PreservedMarksSet::restore(E* executor) {
+ volatile size_t total_size = 0;
+
+#ifdef ASSERT
+ // This is to make sure the total_size we'll calculate below is correct.
+ size_t total_size_before = 0;
+ for (uint i = 0; i < _num; i += 1) {
+ total_size_before += get(i)->size();
+ }
+#endif // def ASSERT
+
+ if (executor == NULL) {
+ for (uint i = 0; i < _num; i += 1) {
+ total_size += get(i)->size();
+ get(i)->restore();
+ }
+ } else {
+ // Right now, if the executor is not NULL we do the work in
+ // parallel. In the future we might want to do the restoration
+ // serially, if there's only a small number of marks per stack.
+ restore_internal(executor, &total_size);
+ }
+ assert_empty();
+
+ assert(total_size == total_size_before,
+ "total_size = " SIZE_FORMAT " before = " SIZE_FORMAT,
+ total_size, total_size_before);
+
+ log_trace(gc)("Restored " SIZE_FORMAT " marks", total_size);
+}
+
+inline PreservedMarks::PreservedMarks()
+ : _stack(OopAndMarkOopStack::default_segment_size(),
+ // This stack should be used very infrequently so there's
+ // no point in caching stack segments (there will be a
+ // waste of space most of the time). So we set the max
+ // cache size to 0.
+ 0 /* max_cache_size */) { }
+
#endif // SHARE_VM_GC_SHARED_PRESERVEDMARKS_INLINE_HPP
--- a/hotspot/src/share/vm/gc/shared/referenceProcessor.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/referenceProcessor.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1090,6 +1090,15 @@
return true;
}
+bool ReferenceProcessor::has_discovered_references() {
+ for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
+ if (!_discovered_refs[i].is_empty()) {
+ return true;
+ }
+ }
+ return false;
+}
+
// Preclean the discovered references by removing those
// whose referents are alive, and by marking from those that
// are not active. These lists can be handled here
--- a/hotspot/src/share/vm/gc/shared/referenceProcessor.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/referenceProcessor.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -412,6 +412,9 @@
// Discover a Reference object, using appropriate discovery criteria
bool discover_reference(oop obj, ReferenceType rt);
+ // Has discovered references that need handling
+ bool has_discovered_references();
+
// Process references found during GC (called by the garbage collector)
ReferenceProcessorStats
process_discovered_references(BoolObjectClosure* is_alive,
--- a/hotspot/src/share/vm/gc/shared/space.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/space.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -411,22 +411,6 @@
return compact_top;
}
-
-bool CompactibleSpace::insert_deadspace(size_t& allowed_deadspace_words,
- HeapWord* q, size_t deadlength) {
- if (allowed_deadspace_words >= deadlength) {
- allowed_deadspace_words -= deadlength;
- CollectedHeap::fill_with_object(q, deadlength);
- oop(q)->set_mark(oop(q)->mark()->set_marked());
- assert((int) deadlength == oop(q)->size(), "bad filler object size");
- // Recall that we required "q == compaction_top".
- return true;
- } else {
- allowed_deadspace_words = 0;
- return false;
- }
-}
-
void ContiguousSpace::prepare_for_compaction(CompactPoint* cp) {
scan_and_forward(this, cp);
}
--- a/hotspot/src/share/vm/gc/shared/space.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/space.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -362,6 +362,12 @@
inline size_t obj_size(const HeapWord* addr) const;
+ template <class SpaceType>
+ static inline void verify_up_to_first_dead(SpaceType* space) NOT_DEBUG_RETURN;
+
+ template <class SpaceType>
+ static inline void clear_empty_region(SpaceType* space);
+
public:
CompactibleSpace() :
_compaction_top(NULL), _next_compaction_space(NULL) {}
@@ -455,16 +461,6 @@
return end();
}
- // Requires "allowed_deadspace_words > 0", that "q" is the start of a
- // free block of the given "word_len", and that "q", were it an object,
- // would not move if forwarded. If the size allows, fill the free
- // block with an object, to prevent excessive compaction. Returns "true"
- // iff the free region was made deadspace, and modifies
- // "allowed_deadspace_words" to reflect the number of available deadspace
- // words remaining after this operation.
- bool insert_deadspace(size_t& allowed_deadspace_words, HeapWord* q,
- size_t word_len);
-
// Below are template functions for scan_and_* algorithms (avoiding virtual calls).
// The space argument should be a subclass of CompactibleSpace, implementing
// scan_limit(), scanned_block_is_obj(), and scanned_block_size(),
--- a/hotspot/src/share/vm/gc/shared/space.inline.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/space.inline.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -31,6 +31,7 @@
#include "gc/shared/space.hpp"
#include "gc/shared/spaceDecorator.hpp"
#include "memory/universe.hpp"
+#include "oops/oopsHierarchy.hpp"
#include "runtime/prefetch.inline.hpp"
#include "runtime/safepoint.hpp"
@@ -75,11 +76,61 @@
return oop(addr)->size();
}
+class DeadSpacer : StackObj {
+ size_t _allowed_deadspace_words;
+ bool _active;
+ CompactibleSpace* _space;
+
+public:
+ DeadSpacer(CompactibleSpace* space) : _space(space), _allowed_deadspace_words(0) {
+ size_t ratio = _space->allowed_dead_ratio();
+ _active = ratio > 0;
+
+ if (_active) {
+ assert(!UseG1GC, "G1 should not be using dead space");
+
+ // We allow some amount of garbage towards the bottom of the space, so
+ // we don't start compacting before there is a significant gain to be made.
+ // Occasionally, we want to ensure a full compaction, which is determined
+ // by the MarkSweepAlwaysCompactCount parameter.
+ if ((MarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0) {
+ _allowed_deadspace_words = (space->capacity() * ratio / 100) / HeapWordSize;
+ } else {
+ _active = false;
+ }
+ }
+ }
+
+
+ bool insert_deadspace(HeapWord* dead_start, HeapWord* dead_end) {
+ if (!_active) {
+ return false;
+ }
+
+ size_t dead_length = pointer_delta(dead_end, dead_start);
+ if (_allowed_deadspace_words >= dead_length) {
+ _allowed_deadspace_words -= dead_length;
+ CollectedHeap::fill_with_object(dead_start, dead_length);
+ oop obj = oop(dead_start);
+ obj->set_mark(obj->mark()->set_marked());
+
+ assert(dead_length == (size_t)obj->size(), "bad filler object size");
+ log_develop_trace(gc, compaction)("Inserting object to dead space: " PTR_FORMAT ", " PTR_FORMAT ", " SIZE_FORMAT "b",
+ p2i(dead_start), p2i(dead_end), dead_length * HeapWordSize);
+
+ return true;
+ } else {
+ _active = false;
+ return false;
+ }
+ }
+
+};
+
template <class SpaceType>
inline void CompactibleSpace::scan_and_forward(SpaceType* space, CompactPoint* cp) {
// Compute the new addresses for the live objects and store it in the mark
// Used by universe::mark_sweep_phase2()
- HeapWord* compact_top; // This is where we are currently compacting to.
// We're sure to be here before any objects are compacted into this
// space, so this is a good time to initialize this:
@@ -90,89 +141,73 @@
assert(cp->threshold == NULL, "just checking");
assert(cp->gen->first_compaction_space() == space, "just checking");
cp->space = cp->gen->first_compaction_space();
- compact_top = cp->space->bottom();
- cp->space->set_compaction_top(compact_top);
cp->threshold = cp->space->initialize_threshold();
- } else {
- compact_top = cp->space->compaction_top();
+ cp->space->set_compaction_top(cp->space->bottom());
}
- // We allow some amount of garbage towards the bottom of the space, so
- // we don't start compacting before there is a significant gain to be made.
- // Occasionally, we want to ensure a full compaction, which is determined
- // by the MarkSweepAlwaysCompactCount parameter.
- uint invocations = MarkSweep::total_invocations();
- bool skip_dead = ((invocations % MarkSweepAlwaysCompactCount) != 0);
+ HeapWord* compact_top = cp->space->compaction_top(); // This is where we are currently compacting to.
- size_t allowed_deadspace = 0;
- if (skip_dead) {
- const size_t ratio = space->allowed_dead_ratio();
- allowed_deadspace = (space->capacity() * ratio / 100) / HeapWordSize;
- }
+ DeadSpacer dead_spacer(space);
- HeapWord* q = space->bottom();
- HeapWord* t = space->scan_limit();
-
- HeapWord* end_of_live= q; // One byte beyond the last byte of the last
- // live object.
- HeapWord* first_dead = space->end(); // The first dead object.
+ HeapWord* end_of_live = space->bottom(); // One byte beyond the last byte of the last live object.
+ HeapWord* first_dead = NULL; // The first dead object.
const intx interval = PrefetchScanIntervalInBytes;
- while (q < t) {
- assert(!space->scanned_block_is_obj(q) ||
- oop(q)->mark()->is_marked() || oop(q)->mark()->is_unlocked() ||
- oop(q)->mark()->has_bias_pattern(),
+ HeapWord* cur_obj = space->bottom();
+ HeapWord* scan_limit = space->scan_limit();
+
+ while (cur_obj < scan_limit) {
+ assert(!space->scanned_block_is_obj(cur_obj) ||
+ oop(cur_obj)->mark()->is_marked() || oop(cur_obj)->mark()->is_unlocked() ||
+ oop(cur_obj)->mark()->has_bias_pattern(),
"these are the only valid states during a mark sweep");
- if (space->scanned_block_is_obj(q) && oop(q)->is_gc_marked()) {
- // prefetch beyond q
- Prefetch::write(q, interval);
- size_t size = space->scanned_block_size(q);
- compact_top = cp->space->forward(oop(q), size, cp, compact_top);
- q += size;
- end_of_live = q;
+ if (space->scanned_block_is_obj(cur_obj) && oop(cur_obj)->is_gc_marked()) {
+ // prefetch beyond cur_obj
+ Prefetch::write(cur_obj, interval);
+ size_t size = space->scanned_block_size(cur_obj);
+ compact_top = cp->space->forward(oop(cur_obj), size, cp, compact_top);
+ cur_obj += size;
+ end_of_live = cur_obj;
} else {
// run over all the contiguous dead objects
- HeapWord* end = q;
+ HeapWord* end = cur_obj;
do {
// prefetch beyond end
Prefetch::write(end, interval);
end += space->scanned_block_size(end);
- } while (end < t && (!space->scanned_block_is_obj(end) || !oop(end)->is_gc_marked()));
+ } while (end < scan_limit && (!space->scanned_block_is_obj(end) || !oop(end)->is_gc_marked()));
// see if we might want to pretend this object is alive so that
// we don't have to compact quite as often.
- if (allowed_deadspace > 0 && q == compact_top) {
- size_t sz = pointer_delta(end, q);
- if (space->insert_deadspace(allowed_deadspace, q, sz)) {
- compact_top = cp->space->forward(oop(q), sz, cp, compact_top);
- q = end;
- end_of_live = end;
- continue;
+ if (cur_obj == compact_top && dead_spacer.insert_deadspace(cur_obj, end)) {
+ oop obj = oop(cur_obj);
+ compact_top = cp->space->forward(obj, obj->size(), cp, compact_top);
+ end_of_live = end;
+ } else {
+ // otherwise, it really is a free region.
+
+ // cur_obj is a pointer to a dead object. Use this dead memory to store a pointer to the next live object.
+ *(HeapWord**)cur_obj = end;
+
+ // see if this is the first dead region.
+ if (first_dead == NULL) {
+ first_dead = cur_obj;
}
}
- // otherwise, it really is a free region.
-
- // q is a pointer to a dead object. Use this dead memory to store a pointer to the next live object.
- (*(HeapWord**)q) = end;
-
- // see if this is the first dead region.
- if (q < first_dead) {
- first_dead = q;
- }
-
// move on to the next object
- q = end;
+ cur_obj = end;
}
}
- assert(q == t, "just checking");
+ assert(cur_obj == scan_limit, "just checking");
space->_end_of_live = end_of_live;
- if (end_of_live < first_dead) {
- first_dead = end_of_live;
+ if (first_dead != NULL) {
+ space->_first_dead = first_dead;
+ } else {
+ space->_first_dead = end_of_live;
}
- space->_first_dead = first_dead;
// save the compaction_top of the compaction space.
cp->space->set_compaction_top(compact_top);
@@ -183,127 +218,58 @@
// adjust all the interior pointers to point at the new locations of objects
// Used by MarkSweep::mark_sweep_phase3()
- HeapWord* q = space->bottom();
- HeapWord* t = space->_end_of_live; // Established by "prepare_for_compaction".
-
- assert(space->_first_dead <= space->_end_of_live, "Stands to reason, no?");
-
- if (q < t && space->_first_dead > q && !oop(q)->is_gc_marked()) {
- // we have a chunk of the space which hasn't moved and we've
- // reinitialized the mark word during the previous pass, so we can't
- // use is_gc_marked for the traversal.
- HeapWord* end = space->_first_dead;
+ HeapWord* cur_obj = space->bottom();
+ HeapWord* const end_of_live = space->_end_of_live; // Established by "scan_and_forward".
+ HeapWord* const first_dead = space->_first_dead; // Established by "scan_and_forward".
- while (q < end) {
- // I originally tried to conjoin "block_start(q) == q" to the
- // assertion below, but that doesn't work, because you can't
- // accurately traverse previous objects to get to the current one
- // after their pointers have been
- // updated, until the actual compaction is done. dld, 4/00
- assert(space->block_is_obj(q), "should be at block boundaries, and should be looking at objs");
-
- // point all the oops to the new location
- size_t size = MarkSweep::adjust_pointers(oop(q));
- size = space->adjust_obj_size(size);
-
- q += size;
- }
-
- if (space->_first_dead == t) {
- q = t;
- } else {
- // The first dead object is no longer an object. At that memory address,
- // there is a pointer to the first live object that the previous phase found.
- q = *((HeapWord**)(space->_first_dead));
- }
- }
+ assert(first_dead <= end_of_live, "Stands to reason, no?");
const intx interval = PrefetchScanIntervalInBytes;
- debug_only(HeapWord* prev_q = NULL);
- while (q < t) {
- // prefetch beyond q
- Prefetch::write(q, interval);
- if (oop(q)->is_gc_marked()) {
- // q is alive
+ debug_only(HeapWord* prev_obj = NULL);
+ while (cur_obj < end_of_live) {
+ Prefetch::write(cur_obj, interval);
+ if (cur_obj < first_dead || oop(cur_obj)->is_gc_marked()) {
+ // cur_obj is alive
// point all the oops to the new location
- size_t size = MarkSweep::adjust_pointers(oop(q));
+ size_t size = MarkSweep::adjust_pointers(oop(cur_obj));
size = space->adjust_obj_size(size);
- debug_only(prev_q = q);
- q += size;
+ debug_only(prev_obj = cur_obj);
+ cur_obj += size;
} else {
- debug_only(prev_q = q);
- // q is not a live object, instead it points at the next live object
- q = *(HeapWord**)q;
- assert(q > prev_q, "we should be moving forward through memory, q: " PTR_FORMAT ", prev_q: " PTR_FORMAT, p2i(q), p2i(prev_q));
+ debug_only(prev_obj = cur_obj);
+ // cur_obj is not a live object, instead it points at the next live object
+ cur_obj = *(HeapWord**)cur_obj;
+ assert(cur_obj > prev_obj, "we should be moving forward through memory, cur_obj: " PTR_FORMAT ", prev_obj: " PTR_FORMAT, p2i(cur_obj), p2i(prev_obj));
}
}
- assert(q == t, "just checking");
+ assert(cur_obj == end_of_live, "just checking");
}
+#ifdef ASSERT
+template <class SpaceType>
+inline void CompactibleSpace::verify_up_to_first_dead(SpaceType* space) {
+ HeapWord* cur_obj = space->bottom();
+
+ if (cur_obj < space->_end_of_live && space->_first_dead > cur_obj && !oop(cur_obj)->is_gc_marked()) {
+ // we have a chunk of the space which hasn't moved and we've reinitialized
+ // the mark word during the previous pass, so we can't use is_gc_marked for
+ // the traversal.
+ HeapWord* prev_obj = NULL;
+
+ while (cur_obj < space->_first_dead) {
+ size_t size = space->obj_size(cur_obj);
+ assert(!oop(cur_obj)->is_gc_marked(), "should be unmarked (special dense prefix handling)");
+ prev_obj = cur_obj;
+ cur_obj += size;
+ }
+ }
+}
+#endif
+
template <class SpaceType>
-inline void CompactibleSpace::scan_and_compact(SpaceType* space) {
- // Copy all live objects to their new location
- // Used by MarkSweep::mark_sweep_phase4()
-
- HeapWord* q = space->bottom();
- HeapWord* const t = space->_end_of_live;
- debug_only(HeapWord* prev_q = NULL);
-
- if (q < t && space->_first_dead > q && !oop(q)->is_gc_marked()) {
- #ifdef ASSERT // Debug only
- // we have a chunk of the space which hasn't moved and we've reinitialized
- // the mark word during the previous pass, so we can't use is_gc_marked for
- // the traversal.
- HeapWord* const end = space->_first_dead;
-
- while (q < end) {
- size_t size = space->obj_size(q);
- assert(!oop(q)->is_gc_marked(), "should be unmarked (special dense prefix handling)");
- prev_q = q;
- q += size;
- }
- #endif
-
- if (space->_first_dead == t) {
- q = t;
- } else {
- // $$$ Funky
- q = (HeapWord*) oop(space->_first_dead)->mark()->decode_pointer();
- }
- }
-
- const intx scan_interval = PrefetchScanIntervalInBytes;
- const intx copy_interval = PrefetchCopyIntervalInBytes;
- while (q < t) {
- if (!oop(q)->is_gc_marked()) {
- // mark is pointer to next marked oop
- debug_only(prev_q = q);
- q = (HeapWord*) oop(q)->mark()->decode_pointer();
- assert(q > prev_q, "we should be moving forward through memory");
- } else {
- // prefetch beyond q
- Prefetch::read(q, scan_interval);
-
- // size and destination
- size_t size = space->obj_size(q);
- HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee();
-
- // prefetch beyond compaction_top
- Prefetch::write(compaction_top, copy_interval);
-
- // copy object and reinit its mark
- assert(q != compaction_top, "everything in this pass should be moving");
- Copy::aligned_conjoint_words(q, compaction_top, size);
- oop(compaction_top)->init_mark();
- assert(oop(compaction_top)->klass() != NULL, "should have a class");
-
- debug_only(prev_q = q);
- q += size;
- }
- }
-
+inline void CompactibleSpace::clear_empty_region(SpaceType* space) {
// Let's remember if we were empty before we did the compaction.
bool was_empty = space->used_region().is_empty();
// Reset space after compaction is complete
@@ -320,6 +286,65 @@
}
}
+template <class SpaceType>
+inline void CompactibleSpace::scan_and_compact(SpaceType* space) {
+ // Copy all live objects to their new location
+ // Used by MarkSweep::mark_sweep_phase4()
+
+ verify_up_to_first_dead(space);
+
+ HeapWord* const end_of_live = space->_end_of_live;
+
+ assert(space->_first_dead <= end_of_live, "Invariant. _first_dead: " PTR_FORMAT " <= end_of_live: " PTR_FORMAT, p2i(space->_first_dead), p2i(end_of_live));
+ if (space->_first_dead == end_of_live && !oop(space->bottom())->is_gc_marked()) {
+ // Nothing to compact. The space is either empty or all live object should be left in place.
+ clear_empty_region(space);
+ return;
+ }
+
+ const intx scan_interval = PrefetchScanIntervalInBytes;
+ const intx copy_interval = PrefetchCopyIntervalInBytes;
+
+ assert(space->bottom() < end_of_live, "bottom: " PTR_FORMAT " should be < end_of_live: " PTR_FORMAT, p2i(space->bottom()), p2i(end_of_live));
+ HeapWord* cur_obj = space->bottom();
+ if (space->_first_dead > cur_obj && !oop(cur_obj)->is_gc_marked()) {
+ // All object before _first_dead can be skipped. They should not be moved.
+ // A pointer to the first live object is stored at the memory location for _first_dead.
+ cur_obj = *(HeapWord**)(space->_first_dead);
+ }
+
+ debug_only(HeapWord* prev_obj = NULL);
+ while (cur_obj < end_of_live) {
+ if (!oop(cur_obj)->is_gc_marked()) {
+ debug_only(prev_obj = cur_obj);
+ // The first word of the dead object contains a pointer to the next live object or end of space.
+ cur_obj = *(HeapWord**)cur_obj;
+ assert(cur_obj > prev_obj, "we should be moving forward through memory");
+ } else {
+ // prefetch beyond q
+ Prefetch::read(cur_obj, scan_interval);
+
+ // size and destination
+ size_t size = space->obj_size(cur_obj);
+ HeapWord* compaction_top = (HeapWord*)oop(cur_obj)->forwardee();
+
+ // prefetch beyond compaction_top
+ Prefetch::write(compaction_top, copy_interval);
+
+ // copy object and reinit its mark
+ assert(cur_obj != compaction_top, "everything in this pass should be moving");
+ Copy::aligned_conjoint_words(cur_obj, compaction_top, size);
+ oop(compaction_top)->init_mark();
+ assert(oop(compaction_top)->klass() != NULL, "should have a class");
+
+ debug_only(prev_obj = cur_obj);
+ cur_obj += size;
+ }
+ }
+
+ clear_empty_region(space);
+}
+
size_t ContiguousSpace::scanned_block_size(const HeapWord* addr) const {
return oop(addr)->size();
}
--- a/hotspot/src/share/vm/interpreter/abstractInterpreter.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "asm/macroAssembler.inline.hpp"
+#include "compiler/disassembler.hpp"
#include "interpreter/bytecodeHistogram.hpp"
#include "interpreter/bytecodeInterpreter.hpp"
#include "interpreter/interpreter.hpp"
@@ -32,6 +33,7 @@
#include "interpreter/interp_masm.hpp"
#include "interpreter/templateTable.hpp"
#include "memory/allocation.inline.hpp"
+#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp"
#include "oops/arrayOop.hpp"
#include "oops/methodData.hpp"
@@ -93,6 +95,7 @@
address AbstractInterpreter::_native_entry_end = NULL;
address AbstractInterpreter::_slow_signature_handler;
address AbstractInterpreter::_entry_table [AbstractInterpreter::number_of_method_entries];
+address AbstractInterpreter::_cds_entry_table [AbstractInterpreter::number_of_method_entries];
address AbstractInterpreter::_native_abi_to_tosca [AbstractInterpreter::number_of_result_handlers];
//------------------------------------------------------------------------------------------------------------------------
@@ -204,15 +207,42 @@
return zerolocals;
}
+#if INCLUDE_CDS
+
+address AbstractInterpreter::get_trampoline_code_buffer(AbstractInterpreter::MethodKind kind) {
+ const size_t trampoline_size = SharedRuntime::trampoline_size();
+ address addr = MetaspaceShared::cds_i2i_entry_code_buffers((size_t)(AbstractInterpreter::number_of_method_entries) * trampoline_size);
+ addr += (size_t)(kind) * trampoline_size;
+
+ return addr;
+}
+
+void AbstractInterpreter::update_cds_entry_table(AbstractInterpreter::MethodKind kind) {
+ if (DumpSharedSpaces || UseSharedSpaces) {
+ address trampoline = get_trampoline_code_buffer(kind);
+ _cds_entry_table[kind] = trampoline;
+
+ CodeBuffer buffer(trampoline, (int)(SharedRuntime::trampoline_size()));
+ MacroAssembler _masm(&buffer);
+ SharedRuntime::generate_trampoline(&_masm, _entry_table[kind]);
+
+ if (PrintInterpreter) {
+ Disassembler::decode(buffer.insts_begin(), buffer.insts_end());
+ }
+ }
+}
+
+#endif
void AbstractInterpreter::set_entry_for_kind(AbstractInterpreter::MethodKind kind, address entry) {
assert(kind >= method_handle_invoke_FIRST &&
kind <= method_handle_invoke_LAST, "late initialization only for MH entry points");
assert(_entry_table[kind] == _entry_table[abstract], "previous value must be AME entry");
_entry_table[kind] = entry;
+
+ update_cds_entry_table(kind);
}
-
// Return true if the interpreter can prove that the given bytecode has
// not yet been executed (in Java semantics, not in actual operation).
bool AbstractInterpreter::is_not_reached(const methodHandle& method, int bci) {
@@ -416,5 +446,6 @@
for (int i = method_handle_invoke_FIRST; i <= method_handle_invoke_LAST; i++) {
MethodKind kind = (MethodKind) i;
_entry_table[kind] = _entry_table[Interpreter::abstract];
+ Interpreter::update_cds_entry_table(kind);
}
}
--- a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -28,9 +28,8 @@
#include "asm/macroAssembler.hpp"
#include "code/stubs.hpp"
#include "interpreter/bytecodes.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/thread.hpp"
#include "runtime/vmThread.hpp"
-#include "utilities/top.hpp"
// This file contains the platform-independent parts
// of the abstract interpreter and the abstract interpreter generator.
@@ -113,6 +112,7 @@
// method entry points
static address _entry_table[number_of_method_entries]; // entry points for a given method
+ static address _cds_entry_table[number_of_method_entries]; // entry points for methods in the CDS archive
static address _native_abi_to_tosca[number_of_result_handlers]; // for native method result handlers
static address _slow_signature_handler; // the native method generic (slow) signature handler
@@ -132,6 +132,17 @@
static address entry_for_kind(MethodKind k) { assert(0 <= k && k < number_of_method_entries, "illegal kind"); return _entry_table[k]; }
static address entry_for_method(methodHandle m) { return entry_for_kind(method_kind(m)); }
+ static address entry_for_cds_method(methodHandle m) {
+ MethodKind k = method_kind(m);
+ assert(0 <= k && k < number_of_method_entries, "illegal kind");
+ return _cds_entry_table[k];
+ }
+
+ // used by class data sharing
+ static void update_cds_entry_table(MethodKind kind) NOT_CDS_RETURN;
+
+ static address get_trampoline_code_buffer(AbstractInterpreter::MethodKind kind) NOT_CDS_RETURN_(0);
+
// used for bootstrapping method handles:
static void set_entry_for_kind(MethodKind k, address e);
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1767,8 +1767,19 @@
((objArrayOop) arrObj)->obj_at_put(index, rhsObject);
UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3);
}
- CASE(_bastore):
- ARRAY_STOREFROM32(T_BYTE, jbyte, "%d", STACK_INT, 0);
+ CASE(_bastore): {
+ ARRAY_INTRO(-3);
+ int item = STACK_INT(-1);
+ // if it is a T_BOOLEAN array, mask the stored value to 0/1
+ if (arrObj->klass() == Universe::boolArrayKlassObj()) {
+ item &= 1;
+ } else {
+ assert(arrObj->klass() == Universe::byteArrayKlassObj(),
+ "should be byte array otherwise");
+ }
+ ((typeArrayOop)arrObj)->byte_at_put(index, item);
+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3);
+ }
CASE(_castore):
ARRAY_STOREFROM32(T_CHAR, jchar, "%d", STACK_INT, 0);
CASE(_sastore):
@@ -1999,7 +2010,7 @@
} else if (tos_type == ltos) {
SET_STACK_LONG(obj->long_field_acquire(field_offset), 0);
MORE_STACK(1);
- } else if (tos_type == btos) {
+ } else if (tos_type == btos || tos_type == ztos) {
SET_STACK_INT(obj->byte_field_acquire(field_offset), -1);
} else if (tos_type == ctos) {
SET_STACK_INT(obj->char_field_acquire(field_offset), -1);
@@ -2020,7 +2031,7 @@
} else if (tos_type == ltos) {
SET_STACK_LONG(obj->long_field(field_offset), 0);
MORE_STACK(1);
- } else if (tos_type == btos) {
+ } else if (tos_type == btos || tos_type == ztos) {
SET_STACK_INT(obj->byte_field(field_offset), -1);
} else if (tos_type == ctos) {
SET_STACK_INT(obj->char_field(field_offset), -1);
@@ -2109,6 +2120,9 @@
obj->release_obj_field_put(field_offset, STACK_OBJECT(-1));
} else if (tos_type == btos) {
obj->release_byte_field_put(field_offset, STACK_INT(-1));
+ } else if (tos_type == ztos) {
+ int bool_field = STACK_INT(-1); // only store LSB
+ obj->release_byte_field_put(field_offset, (bool_field & 1));
} else if (tos_type == ltos) {
obj->release_long_field_put(field_offset, STACK_LONG(-1));
} else if (tos_type == ctos) {
@@ -2129,6 +2143,9 @@
obj->obj_field_put(field_offset, STACK_OBJECT(-1));
} else if (tos_type == btos) {
obj->byte_field_put(field_offset, STACK_INT(-1));
+ } else if (tos_type == ztos) {
+ int bool_field = STACK_INT(-1); // only store LSB
+ obj->byte_field_put(field_offset, (bool_field & 1));
} else if (tos_type == ltos) {
obj->long_field_put(field_offset, STACK_LONG(-1));
} else if (tos_type == ctos) {
--- a/hotspot/src/share/vm/interpreter/bytecodeTracer.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecodeTracer.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -26,6 +26,7 @@
#define SHARE_VM_INTERPRETER_BYTECODETRACER_HPP
#include "memory/allocation.hpp"
+#include "utilities/ostream.hpp"
// The BytecodeTracer is a helper class used by the interpreter for run-time
// bytecode tracing. If bytecode tracing is turned on, trace() will be called
--- a/hotspot/src/share/vm/interpreter/bytecodes.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecodes.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -496,6 +496,7 @@
def(_fast_aputfield , "fast_aputfield" , "bJJ" , NULL , T_OBJECT , 0, true , _putfield );
def(_fast_bputfield , "fast_bputfield" , "bJJ" , NULL , T_INT , 0, true , _putfield );
+ def(_fast_zputfield , "fast_zputfield" , "bJJ" , NULL , T_INT , 0, true , _putfield );
def(_fast_cputfield , "fast_cputfield" , "bJJ" , NULL , T_CHAR , 0, true , _putfield );
def(_fast_dputfield , "fast_dputfield" , "bJJ" , NULL , T_DOUBLE , 0, true , _putfield );
def(_fast_fputfield , "fast_fputfield" , "bJJ" , NULL , T_FLOAT , 0, true , _putfield );
--- a/hotspot/src/share/vm/interpreter/bytecodes.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecodes.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -26,11 +26,12 @@
#define SHARE_VM_INTERPRETER_BYTECODES_HPP
#include "memory/allocation.hpp"
-#include "utilities/top.hpp"
// Bytecodes specifies all bytecodes used in the VM and
// provides utility functions to get bytecode attributes.
+class Method;
+
// NOTE: replicated in SA in vm/agent/sun/jvm/hotspot/interpreter/Bytecodes.java
class Bytecodes: AllStatic {
public:
@@ -256,6 +257,7 @@
_fast_aputfield ,
_fast_bputfield ,
+ _fast_zputfield ,
_fast_cputfield ,
_fast_dputfield ,
_fast_fputfield ,
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -313,18 +313,7 @@
THROW_HANDLE(exception);
IRT_END
-IRT_ENTRY(address, InterpreterRuntime::check_ReservedStackAccess_annotated_methods(JavaThread* thread))
- frame fr = thread->last_frame();
- assert(fr.is_java_frame(), "Must be a Java frame");
- frame activation = SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
- if (activation.sp() != NULL) {
- thread->disable_stack_reserved_zone();
- thread->set_reserved_stack_activation((address)activation.unextended_sp());
- }
- return (address)activation.sp();
-IRT_END
-
- IRT_ENTRY(void, InterpreterRuntime::throw_delayed_StackOverflowError(JavaThread* thread))
+IRT_ENTRY(void, InterpreterRuntime::throw_delayed_StackOverflowError(JavaThread* thread))
Handle exception = get_preinitialized_exception(
SystemDictionary::StackOverflowError_klass(),
CHECK);
@@ -1088,7 +1077,8 @@
char sig_type = '\0';
switch(cp_entry->flag_state()) {
- case btos: sig_type = 'Z'; break;
+ case btos: sig_type = 'B'; break;
+ case ztos: sig_type = 'Z'; break;
case ctos: sig_type = 'C'; break;
case stos: sig_type = 'S'; break;
case itos: sig_type = 'I'; break;
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -31,8 +31,7 @@
#include "oops/method.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/signature.hpp"
-#include "runtime/thread.inline.hpp"
-#include "utilities/top.hpp"
+#include "runtime/thread.hpp"
// The InterpreterRuntime is called by the interpreter for everything
// that cannot/should not be dealt with in assembly and needs C support.
@@ -91,8 +90,6 @@
// Quicken instance-of and check-cast bytecodes
static void quicken_io_cc(JavaThread* thread);
- static address check_ReservedStackAccess_annotated_methods(JavaThread* thread);
-
// Exceptions thrown by the interpreter
static void throw_AbstractMethodError(JavaThread* thread);
static void throw_IncompatibleClassChangeError(JavaThread* thread);
--- a/hotspot/src/share/vm/interpreter/linkResolver.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/linkResolver.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -26,7 +26,6 @@
#define SHARE_VM_INTERPRETER_LINKRESOLVER_HPP
#include "oops/method.hpp"
-#include "utilities/top.hpp"
// All the necessary definitions for run-time link resolution.
--- a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -89,8 +89,9 @@
// Implementation of EntryPoint
EntryPoint::EntryPoint() {
- assert(number_of_states == 9, "check the code below");
+ assert(number_of_states == 10, "check the code below");
_entry[btos] = NULL;
+ _entry[ztos] = NULL;
_entry[ctos] = NULL;
_entry[stos] = NULL;
_entry[atos] = NULL;
@@ -102,9 +103,10 @@
}
-EntryPoint::EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) {
- assert(number_of_states == 9, "check the code below");
+EntryPoint::EntryPoint(address bentry, address zentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) {
+ assert(number_of_states == 10, "check the code below");
_entry[btos] = bentry;
+ _entry[ztos] = zentry;
_entry[ctos] = centry;
_entry[stos] = sentry;
_entry[atos] = aentry;
@@ -155,6 +157,7 @@
return
EntryPoint(
_table[btos][i],
+ _table[ztos][i],
_table[ctos][i],
_table[stos][i],
_table[atos][i],
@@ -169,8 +172,9 @@
void DispatchTable::set_entry(int i, EntryPoint& entry) {
assert(0 <= i && i < length, "index out of bounds");
- assert(number_of_states == 9, "check the code below");
+ assert(number_of_states == 10, "check the code below");
_table[btos][i] = entry.entry(btos);
+ _table[ztos][i] = entry.entry(ztos);
_table[ctos][i] = entry.entry(ctos);
_table[stos][i] = entry.entry(stos);
_table[atos][i] = entry.entry(atos);
--- a/hotspot/src/share/vm/interpreter/templateInterpreter.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/templateInterpreter.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -47,7 +47,7 @@
public:
// Construction
EntryPoint();
- EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry);
+ EntryPoint(address bentry, address zentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry);
// Attributes
address entry(TosState state) const; // return target address for a given tosca state
--- a/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -74,6 +74,7 @@
Interpreter::_trace_code =
EntryPoint(
generate_trace_code(btos),
+ generate_trace_code(ztos),
generate_trace_code(ctos),
generate_trace_code(stos),
generate_trace_code(atos),
@@ -94,6 +95,7 @@
generate_return_entry_for(itos, i, index_size),
generate_return_entry_for(itos, i, index_size),
generate_return_entry_for(itos, i, index_size),
+ generate_return_entry_for(itos, i, index_size),
generate_return_entry_for(atos, i, index_size),
generate_return_entry_for(itos, i, index_size),
generate_return_entry_for(ltos, i, index_size),
@@ -105,13 +107,16 @@
}
{ CodeletMark cm(_masm, "invoke return entry points");
- const TosState states[] = {itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos};
+ // These states are in order specified in TosState, except btos/ztos/ctos/stos are
+ // really the same as itos since there is no top of stack optimization for these types
+ const TosState states[] = {itos, itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos, ilgl};
const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic);
const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface);
const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic);
for (int i = 0; i < Interpreter::number_of_return_addrs; i++) {
TosState state = states[i];
+ assert(state != ilgl, "states array is wrong above");
Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2));
Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2));
Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4));
@@ -122,6 +127,7 @@
Interpreter::_earlyret_entry =
EntryPoint(
generate_earlyret_entry_for(btos),
+ generate_earlyret_entry_for(ztos),
generate_earlyret_entry_for(ctos),
generate_earlyret_entry_for(stos),
generate_earlyret_entry_for(atos),
@@ -140,6 +146,7 @@
generate_deopt_entry_for(itos, i),
generate_deopt_entry_for(itos, i),
generate_deopt_entry_for(itos, i),
+ generate_deopt_entry_for(itos, i),
generate_deopt_entry_for(atos, i),
generate_deopt_entry_for(itos, i),
generate_deopt_entry_for(ltos, i),
@@ -167,6 +174,7 @@
Interpreter::_continuation_entry =
EntryPoint(
generate_continuation_for(btos),
+ generate_continuation_for(ztos),
generate_continuation_for(ctos),
generate_continuation_for(stos),
generate_continuation_for(atos),
@@ -182,6 +190,7 @@
Interpreter::_safept_entry =
EntryPoint(
generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+ generate_safept_entry_for(ztos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
@@ -212,6 +221,7 @@
#define method_entry(kind) \
{ CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \
Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind); \
+ Interpreter::update_cds_entry_table(Interpreter::kind); \
}
// all non-native method kinds
@@ -300,7 +310,7 @@
void TemplateInterpreterGenerator::set_unimplemented(int i) {
address e = _unimplemented_bytecode;
- EntryPoint entry(e, e, e, e, e, e, e, e, e);
+ EntryPoint entry(e, e, e, e, e, e, e, e, e, e);
Interpreter::_normal_table.set_entry(i, entry);
Interpreter::_wentry_point[i] = _unimplemented_bytecode;
}
@@ -315,6 +325,7 @@
assert(_unimplemented_bytecode != NULL, "should have been generated before");
assert(_illegal_bytecode_sequence != NULL, "should have been generated before");
address bep = _illegal_bytecode_sequence;
+ address zep = _illegal_bytecode_sequence;
address cep = _illegal_bytecode_sequence;
address sep = _illegal_bytecode_sequence;
address aep = _illegal_bytecode_sequence;
@@ -336,7 +347,7 @@
set_wide_entry_point(t, wep);
}
// set entry points
- EntryPoint entry(bep, cep, sep, aep, iep, lep, fep, dep, vep);
+ EntryPoint entry(bep, zep, cep, sep, aep, iep, lep, fep, dep, vep);
Interpreter::_normal_table.set_entry(code, entry);
Interpreter::_wentry_point[code] = wep;
CodeCacheExtensions::completed_template_interpreter_entries(_masm, code);
@@ -354,6 +365,7 @@
assert(t->is_valid(), "template must exist");
switch (t->tos_in()) {
case btos:
+ case ztos:
case ctos:
case stos:
ShouldNotReachHere(); // btos/ctos/stos should use itos.
--- a/hotspot/src/share/vm/interpreter/templateTable.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/templateTable.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -488,6 +488,7 @@
def(Bytecodes::_fast_aputfield , ubcp|____|____|____, atos, vtos, fast_storefield , atos );
def(Bytecodes::_fast_bputfield , ubcp|____|____|____, itos, vtos, fast_storefield , itos );
+ def(Bytecodes::_fast_zputfield , ubcp|____|____|____, itos, vtos, fast_storefield , itos );
def(Bytecodes::_fast_cputfield , ubcp|____|____|____, itos, vtos, fast_storefield , itos );
def(Bytecodes::_fast_dputfield , ubcp|____|____|____, dtos, vtos, fast_storefield , dtos );
def(Bytecodes::_fast_fputfield , ubcp|____|____|____, ftos, vtos, fast_storefield , ftos );
--- a/hotspot/src/share/vm/logging/log.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/log.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -31,7 +31,10 @@
#include "gc/shared/gcTraceTime.inline.hpp"
#include "logging/log.hpp"
#include "logging/logConfiguration.hpp"
+#include "logging/logFileOutput.hpp"
#include "logging/logOutput.hpp"
+#include "logging/logTagLevelExpression.hpp"
+#include "logging/logTagSet.hpp"
#include "logging/logStream.inline.hpp"
#include "memory/resourceArea.hpp"
@@ -44,6 +47,13 @@
#define assert_char_not_in(c, s) \
assert(strchr(s, c) == NULL, "Expected '%s' to *not* contain character '%c'", s, c)
+void Test_log_tag_combinations_limit() {
+ assert(LogTagLevelExpression::MaxCombinations > LogTagSet::ntagsets(),
+ "Combination limit (" SIZE_FORMAT ") not sufficient "
+ "for configuring all available tag sets (" SIZE_FORMAT ")",
+ LogTagLevelExpression::MaxCombinations, LogTagSet::ntagsets());
+}
+
class TestLogFile {
private:
char file_name[256];
@@ -129,6 +139,131 @@
assert_str_eq("all=off", stdoutput->config_string());
}
+static size_t number_of_lines_with_substring_in_file(const char* filename,
+ const char* substr) {
+ ResourceMark rm;
+ size_t ret = 0;
+ FILE* fp = fopen(filename, "r");
+ assert(fp != NULL, "error opening file %s: %s", filename, strerror(errno));
+
+ int buflen = 512;
+ char* buf = NEW_RESOURCE_ARRAY(char, buflen);
+ long pos = 0;
+
+ while (fgets(buf, buflen, fp) != NULL) {
+ if (buf[strlen(buf) - 1] != '\n' && !feof(fp)) {
+ // retry with a larger buffer
+ buf = REALLOC_RESOURCE_ARRAY(char, buf, buflen, buflen * 2);
+ buflen *= 2;
+ // rewind to beginning of line
+ fseek(fp, pos, SEEK_SET);
+ continue;
+ }
+ pos = ftell(fp);
+ if (strstr(buf, substr) != NULL) {
+ ret++;
+ }
+ }
+
+ fclose(fp);
+ return ret;
+}
+
+static bool file_exists(const char* filename) {
+ struct stat st;
+ return os::stat(filename, &st) == 0;
+}
+
+static void delete_file(const char* filename) {
+ if (!file_exists(filename)) {
+ return;
+ }
+ int ret = remove(filename);
+ assert(ret == 0, "failed to remove file '%s': %s", filename, strerror(errno));
+}
+
+static void create_directory(const char* name) {
+ assert(!file_exists(name), "can't create directory: %s already exists", name);
+ bool failed;
+#ifdef _WINDOWS
+ failed = !CreateDirectory(name, NULL);
+#else
+ failed = mkdir(name, 0777);
+#endif
+ assert(!failed, "failed to create directory %s", name);
+}
+
+static const char* ExpectedLine = "a (hopefully) unique log line for testing";
+
+static void init_file(const char* filename, const char* options = "") {
+ LogConfiguration::parse_log_arguments(filename, "logging=trace", "", options,
+ Log(logging)::error_stream());
+ log_debug(logging)("%s", ExpectedLine);
+ LogConfiguration::parse_log_arguments(filename, "all=off", "", "",
+ Log(logging)::error_stream());
+}
+
+void Test_log_file_startup_rotation() {
+ ResourceMark rm;
+ const size_t rotations = 5;
+ const char* filename = "start-rotate-test";
+ char* rotated_file[rotations];
+ for (size_t i = 0; i < rotations; i++) {
+ size_t len = strlen(filename) + 3;
+ rotated_file[i] = NEW_RESOURCE_ARRAY(char, len);
+ jio_snprintf(rotated_file[i], len, "%s." SIZE_FORMAT, filename, i);
+ delete_file(rotated_file[i]);
+ };
+
+ delete_file(filename);
+ init_file(filename);
+ assert(file_exists(filename),
+ "configured logging to file '%s' but file was not found", filename);
+
+ // Initialize the same file a bunch more times to trigger rotations
+ for (size_t i = 0; i < rotations; i++) {
+ init_file(filename);
+ assert(file_exists(rotated_file[i]), "existing file was not rotated");
+ }
+
+ // Remove a file and expect its slot to be re-used
+ delete_file(rotated_file[1]);
+ init_file(filename);
+ assert(file_exists(rotated_file[1]), "log file not properly rotated");
+
+ // Clean up after test
+ delete_file(filename);
+ for (size_t i = 0; i < rotations; i++) {
+ delete_file(rotated_file[i]);
+ }
+}
+
+void Test_log_file_startup_truncation() {
+ ResourceMark rm;
+ const char* filename = "start-truncate-test";
+ const char* archived_filename = "start-truncate-test.0";
+
+ delete_file(filename);
+ delete_file(archived_filename);
+
+ // Use the same log file twice and expect it to be overwritten/truncated
+ init_file(filename, "filecount=0");
+ assert(file_exists(filename), "couldn't find log file: %s", filename);
+
+ init_file(filename, "filecount=0");
+ assert(file_exists(filename), "couldn't find log file: %s", filename);
+ assert(!file_exists(archived_filename),
+ "existing log file %s was not properly truncated when filecount was 0",
+ filename);
+
+ // Verify that the file was really truncated and not just appended
+ assert(number_of_lines_with_substring_in_file(filename, ExpectedLine) == 1,
+ "log file %s appended rather than truncated", filename);
+
+ delete_file(filename);
+ delete_file(archived_filename);
+}
+
static int Test_logconfiguration_subscribe_triggered = 0;
static void Test_logconfiguration_subscribe_helper() {
@@ -361,11 +496,32 @@
Test_logstream_helper(stream);
}
+static void Test_logstreamcheap_log() {
+ Log(gc) log;
+ LogStreamCHeap stream(log.debug());
+
+ Test_logstream_helper(&stream);
+}
+
+static void Test_logstreamcheap_logtarget() {
+ LogTarget(Debug, gc) log;
+ LogStreamCHeap stream(log);
+
+ Test_logstream_helper(&stream);
+}
+
void Test_logstream() {
+ // Test LogStreams with embedded ResourceMark.
Test_logstream_log();
Test_logstream_logtarget();
Test_logstream_logstreamhandle();
+
+ // Test LogStreams without embedded ResourceMark.
Test_logstream_no_rm();
+
+ // Test LogStreams backed by CHeap memory.
+ Test_logstreamcheap_log();
+ Test_logstreamcheap_logtarget();
}
void Test_loghandle_on() {
@@ -377,7 +533,7 @@
assert(log_handle.is_debug(), "assert");
- // Try to log trough a LogHandle.
+ // Try to log through a LogHandle.
log_handle.debug("%d workers", 3);
FILE* fp = fopen(log_file.name(), "r");
@@ -408,7 +564,7 @@
return;
}
- // Try to log trough a LogHandle. Should fail, since only info is turned on.
+ // Try to log through a LogHandle. Should fail, since only info is turned on.
log_handle.debug("%d workers", 3);
// Log a dummy line so that fgets doesn't return NULL because the file is empty.
@@ -440,7 +596,7 @@
assert(log_handle.is_enabled(), "assert");
- // Try to log trough a LogHandle.
+ // Try to log through a LogHandle.
log_handle.print("%d workers", 3);
FILE* fp = fopen(log_file.name(), "r");
@@ -471,7 +627,7 @@
return;
}
- // Try to log trough a LogHandle. Should fail, since only info is turned on.
+ // Try to log through a LogHandle. Should fail, since only info is turned on.
log_handle.print("%d workers", 3);
// Log a dummy line so that fgets doesn't return NULL because the file is empty.
@@ -711,4 +867,20 @@
Test_log_gctracetime_no_heap_no_cause();
}
+void Test_invalid_log_file() {
+ ResourceMark rm;
+ stringStream ss;
+ const char* target_name = "tmplogdir";
+
+ // Attempt to log to a directory (existing log not a regular file)
+ create_directory(target_name);
+ LogFileOutput bad_file("tmplogdir");
+ assert(bad_file.initialize("", &ss) == false, "file was initialized "
+ "when there was an existing directory with the same name");
+ assert(strstr(ss.as_string(), "tmplogdir is not a regular file") != NULL,
+ "missing expected error message, received msg: %s", ss.as_string());
+ ss.reset();
+ remove(target_name);
+}
+
#endif // PRODUCT
--- a/hotspot/src/share/vm/logging/logConfiguration.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logConfiguration.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -145,7 +145,7 @@
return NULL;
}
- bool success = output->initialize(options);
+ bool success = output->initialize(options, errstream);
if (!success) {
errstream->print_cr("Initialization of output '%s' using options '%s' failed.", name, options);
delete output;
--- a/hotspot/src/share/vm/logging/logFileOutput.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logFileOutput.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -41,8 +41,9 @@
LogFileOutput::LogFileOutput(const char* name)
: LogFileStreamOutput(NULL), _name(os::strdup_check_oom(name, mtLogging)),
- _file_name(NULL), _archive_name(NULL), _archive_name_len(0), _current_size(0),
- _rotate_size(0), _current_file(1), _file_count(0), _rotation_semaphore(1) {
+ _file_name(NULL), _archive_name(NULL), _archive_name_len(0),
+ _rotate_size(DefaultFileSize), _file_count(DefaultFileCount),
+ _current_size(0), _current_file(0), _rotation_semaphore(1) {
_file_name = make_file_name(name, _pid_str, _vm_start_time_str);
}
@@ -59,9 +60,6 @@
LogFileOutput::~LogFileOutput() {
if (_stream != NULL) {
- if (_archive_name != NULL) {
- archive();
- }
if (fclose(_stream) != 0) {
jio_fprintf(defaultStream::error_stream(), "Could not close log file '%s' (%s).\n",
_file_name, os::strerror(errno));
@@ -72,7 +70,7 @@
os::free(const_cast<char*>(_name));
}
-size_t LogFileOutput::parse_value(const char* value_str) {
+static size_t parse_value(const char* value_str) {
char* end;
unsigned long long value = strtoull(value_str, &end, 10);
if (!isdigit(*value_str) || end != value_str + strlen(value_str) || value >= SIZE_MAX) {
@@ -81,7 +79,80 @@
return value;
}
-bool LogFileOutput::configure_rotation(const char* options) {
+static bool file_exists(const char* filename) {
+ struct stat dummy_stat;
+ return os::stat(filename, &dummy_stat) == 0;
+}
+
+static uint number_of_digits(uint number) {
+ return number < 10 ? 1 : (number < 100 ? 2 : 3);
+}
+
+static bool is_regular_file(const char* filename) {
+ struct stat st;
+ int ret = os::stat(filename, &st);
+ if (ret != 0) {
+ return false;
+ }
+#ifdef _WINDOWS
+ return (st.st_mode & S_IFMT) == _S_IFREG;
+#else
+ return S_ISREG(st.st_mode);
+#endif
+}
+
+// Try to find the next number that should be used for file rotation.
+// Return UINT_MAX on error.
+static uint next_file_number(const char* filename,
+ uint number_of_digits,
+ uint filecount,
+ outputStream* errstream) {
+ bool found = false;
+ uint next_num = 0;
+
+ // len is filename + dot + digits + null char
+ size_t len = strlen(filename) + number_of_digits + 2;
+ char* archive_name = NEW_C_HEAP_ARRAY(char, len, mtLogging);
+ char* oldest_name = NEW_C_HEAP_ARRAY(char, len, mtLogging);
+
+ for (uint i = 0; i < filecount; i++) {
+ int ret = jio_snprintf(archive_name, len, "%s.%0*u",
+ filename, number_of_digits, i);
+ assert(ret > 0 && static_cast<size_t>(ret) == len - 1,
+ "incorrect buffer length calculation");
+
+ if (file_exists(archive_name) && !is_regular_file(archive_name)) {
+ // We've encountered something that's not a regular file among the
+ // possible file rotation targets. Fail immediately to prevent
+ // problems later.
+ errstream->print_cr("Possible rotation target file '%s' already exists "
+ "but is not a regular file.", archive_name);
+ next_num = UINT_MAX;
+ break;
+ }
+
+ // Stop looking if we find an unused file name
+ if (!file_exists(archive_name)) {
+ next_num = i;
+ found = true;
+ break;
+ }
+
+ // Keep track of oldest existing log file
+ if (!found
+ || os::compare_file_modified_times(oldest_name, archive_name) > 0) {
+ strcpy(oldest_name, archive_name);
+ next_num = i;
+ found = true;
+ }
+ }
+
+ FREE_C_HEAP_ARRAY(char, oldest_name);
+ FREE_C_HEAP_ARRAY(char, archive_name);
+ return next_num;
+}
+
+bool LogFileOutput::parse_options(const char* options, outputStream* errstream) {
if (options == NULL || strlen(options) == 0) {
return true;
}
@@ -107,22 +178,25 @@
if (strcmp(FileCountOptionKey, key) == 0) {
size_t value = parse_value(value_str);
- if (value == SIZE_MAX || value >= UINT_MAX) {
+ if (value > MaxRotationFileCount) {
+ errstream->print_cr("Invalid option: %s must be in range [0, %u]",
+ FileCountOptionKey,
+ MaxRotationFileCount);
success = false;
break;
}
_file_count = static_cast<uint>(value);
- _file_count_max_digits = static_cast<uint>(log10(static_cast<double>(_file_count)) + 1);
- _archive_name_len = 2 + strlen(_file_name) + _file_count_max_digits;
- _archive_name = NEW_C_HEAP_ARRAY(char, _archive_name_len, mtLogging);
} else if (strcmp(FileSizeOptionKey, key) == 0) {
size_t value = parse_value(value_str);
if (value == SIZE_MAX || value > SIZE_MAX / K) {
+ errstream->print_cr("Invalid option: %s must be in range [0, "
+ SIZE_FORMAT "]", FileSizeOptionKey, SIZE_MAX / K);
success = false;
break;
}
_rotate_size = value * K;
} else {
+ errstream->print_cr("Invalid option '%s' for log file output.", key);
success = false;
break;
}
@@ -133,15 +207,54 @@
return success;
}
-bool LogFileOutput::initialize(const char* options) {
- if (!configure_rotation(options)) {
+bool LogFileOutput::initialize(const char* options, outputStream* errstream) {
+ if (!parse_options(options, errstream)) {
return false;
}
+
+ if (_file_count > 0) {
+ // compute digits with filecount - 1 since numbers will start from 0
+ _file_count_max_digits = number_of_digits(_file_count - 1);
+ _archive_name_len = 2 + strlen(_file_name) + _file_count_max_digits;
+ _archive_name = NEW_C_HEAP_ARRAY(char, _archive_name_len, mtLogging);
+ }
+
+ log_trace(logging)("Initializing logging to file '%s' (filecount: %u"
+ ", filesize: " SIZE_FORMAT " KiB).",
+ _file_name, _file_count, _rotate_size / K);
+
+ if (_file_count > 0 && file_exists(_file_name)) {
+ if (!is_regular_file(_file_name)) {
+ errstream->print_cr("Unable to log to file %s with log file rotation: "
+ "%s is not a regular file",
+ _file_name, _file_name);
+ return false;
+ }
+ _current_file = next_file_number(_file_name,
+ _file_count_max_digits,
+ _file_count,
+ errstream);
+ if (_current_file == UINT_MAX) {
+ return false;
+ }
+ log_trace(logging)("Existing log file found, saving it as '%s.%0*u'",
+ _file_name, _file_count_max_digits, _current_file);
+ archive();
+ increment_file_count();
+ }
+
_stream = fopen(_file_name, FileOpenMode);
if (_stream == NULL) {
- log_error(logging)("Could not open log file '%s' (%s).\n", _file_name, os::strerror(errno));
+ errstream->print_cr("Error opening log file '%s': %s",
+ _file_name, strerror(errno));
return false;
}
+
+ if (_file_count == 0 && is_regular_file(_file_name)) {
+ log_trace(logging)("Truncating log file");
+ os::ftruncate(os::fileno(_stream), 0);
+ }
+
return true;
}
@@ -210,7 +323,7 @@
// Reset accumulated size, increase current file counter, and check for file count wrap-around.
_current_size = 0;
- _current_file = (_current_file >= _file_count ? 1 : _current_file + 1);
+ increment_file_count();
}
char* LogFileOutput::make_file_name(const char* file_name,
--- a/hotspot/src/share/vm/logging/logFileOutput.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logFileOutput.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -39,8 +39,11 @@
static const char* PidFilenamePlaceholder;
static const char* TimestampFilenamePlaceholder;
static const char* TimestampFormat;
+ static const size_t DefaultFileCount = 5;
+ static const size_t DefaultFileSize = 20 * M;
static const size_t StartTimeBufferSize = 20;
- static const size_t PidBufferSize = 21;
+ static const size_t PidBufferSize = 21;
+ static const uint MaxRotationFileCount = 1000;
static char _pid_str[PidBufferSize];
static char _vm_start_time_str[StartTimeBufferSize];
@@ -61,18 +64,24 @@
void archive();
void rotate();
- bool configure_rotation(const char* options);
+ bool parse_options(const char* options, outputStream* errstream);
char *make_file_name(const char* file_name, const char* pid_string, const char* timestamp_string);
- static size_t parse_value(const char* value_str);
bool should_rotate() {
return _file_count > 0 && _rotate_size > 0 && _current_size >= _rotate_size;
}
+ void increment_file_count() {
+ _current_file++;
+ if (_current_file == _file_count) {
+ _current_file = 0;
+ }
+ }
+
public:
LogFileOutput(const char *name);
virtual ~LogFileOutput();
- virtual bool initialize(const char* options);
+ virtual bool initialize(const char* options, outputStream* errstream);
virtual int write(const LogDecorations& decorations, const char* msg);
virtual void force_rotate();
--- a/hotspot/src/share/vm/logging/logFileStreamOutput.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logFileStreamOutput.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -53,7 +53,7 @@
LogStdoutOutput() : LogFileStreamOutput(stdout) {
set_config_string("all=off");
}
- virtual bool initialize(const char* options) {
+ virtual bool initialize(const char* options, outputStream* errstream) {
return false;
}
public:
@@ -69,7 +69,7 @@
LogStderrOutput() : LogFileStreamOutput(stderr) {
set_config_string("all=warning");
}
- virtual bool initialize(const char* options) {
+ virtual bool initialize(const char* options, outputStream* errstream) {
return false;
}
public:
--- a/hotspot/src/share/vm/logging/logHandle.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logHandle.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -67,13 +67,13 @@
// This can be used to pass a Log instance as a parameter without
// polluting the surrounding API with template functions.
class LogTargetHandle {
- friend class LogStream;
-
private:
const LogLevelType _level;
LogTagSet* _tagset;
public:
+ LogTargetHandle(LogLevelType level, LogTagSet* tagset) : _level(level), _tagset(tagset) {}
+
template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
LogTargetHandle(const LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>& type_carrier) :
_level(level),
--- a/hotspot/src/share/vm/logging/logOutput.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logOutput.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -82,7 +82,7 @@
}
virtual const char* name() const = 0;
- virtual bool initialize(const char* options) = 0;
+ virtual bool initialize(const char* options, outputStream* errstream) = 0;
virtual int write(const LogDecorations &decorations, const char* msg) = 0;
};
--- a/hotspot/src/share/vm/logging/logPrefix.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logPrefix.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -55,6 +55,7 @@
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ergo, cset)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ergo, heap)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ergo, ihop)) \
+ LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ergo, refine)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, heap)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, heap, region)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, freelist)) \
--- a/hotspot/src/share/vm/logging/logStream.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logStream.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "logging/log.hpp"
-#include "logging/logStream.hpp"
+#include "logging/logStream.inline.hpp"
// Create a log stream without an embedded ResourceMark.
// The function is placed here to be called out-of-line in log.hpp.
--- a/hotspot/src/share/vm/logging/logStream.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logStream.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -26,23 +26,100 @@
#define SHARE_VM_LOGGING_LOGSTREAM_HPP
#include "logging/log.hpp"
+#include "logging/logHandle.hpp"
+#include "memory/resourceArea.hpp"
#include "utilities/ostream.hpp"
-// An output stream that logs to the logging framework.
-// Requires a ResourceMark on the stack.
-class LogStreamNoResourceMark : public outputStream {
-private:
- stringStream _current_line;
- LogLevelType _level;
- LogTagSet* _tagset;
+// The base class of an output stream that logs to the logging framework.
+template <class streamClass>
+class LogStreamBase : public outputStream {
+ streamClass _current_line;
+ LogTargetHandle _log_handle;
public:
- LogStreamNoResourceMark(LogLevelType level, LogTagSet* tagset) : _level(level), _tagset(tagset) {}
- ~LogStreamNoResourceMark() {
+ // Constructor to support creation from a LogTarget instance.
+ //
+ // LogTarget(Debug, gc) log;
+ // LogStreamBase(log) stream;
+ template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
+ LogStreamBase(const LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>& type_carrier) :
+ _log_handle(level, &LogTagSetMapping<T0, T1, T2, T3, T4>::tagset()) {}
+
+ // Constructor to support creation from typed (likely NULL) pointer. Mostly used by the logging framework.
+ //
+ // LogStreamBase stream(log.debug());
+ // or
+ // LogStreamBase stream((LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>*)NULL);
+ template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
+ LogStreamBase(const LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>* type_carrier) :
+ _log_handle(level, &LogTagSetMapping<T0, T1, T2, T3, T4>::tagset()) {}
+
+ // Constructor to support creation from a LogTargetHandle.
+ //
+ // LogTarget(Debug, gc) log;
+ // LogTargetHandle(log) handle;
+ // LogStreamBase stream(handle);
+ LogStreamBase(LogTargetHandle handle) : _log_handle(handle) {}
+
+ // Constructor to support creation from a log level and tagset.
+ //
+ // LogStreamBase(level, tageset);
+ LogStreamBase(LogLevelType level, LogTagSet* tagset) : _log_handle(level, tagset) {}
+
+ ~LogStreamBase() {
guarantee(_current_line.size() == 0, "Buffer not flushed. Missing call to print_cr()?");
}
+public:
void write(const char* s, size_t len);
};
+// A stringStream with an embedded ResourceMark.
+class stringStreamWithResourceMark : outputStream {
+ private:
+ // The stringStream Resource allocate in the constructor,
+ // so the order of the fields is important.
+ ResourceMark _embedded_resource_mark;
+ stringStream _stream;
+
+ public:
+ stringStreamWithResourceMark(size_t initial_bufsize = 256) :
+ _embedded_resource_mark(),
+ _stream(initial_bufsize) {}
+
+ virtual void write(const char* c, size_t len) { _stream.write(c, len); }
+ size_t size() { return _stream.size(); }
+ const char* base() { return _stream.base(); }
+ void reset() { _stream.reset(); }
+ char* as_string() { return _stream.as_string(); }
+};
+
+// An output stream that logs to the logging framework.
+//
+// The backing buffer is allocated in Resource memory.
+// The caller is required to have a ResourceMark on the stack.
+typedef LogStreamBase<stringStream> LogStreamNoResourceMark;
+
+// An output stream that logs to the logging framework.
+//
+// The backing buffer is allocated in CHeap memory.
+typedef LogStreamBase<bufferedStream> LogStreamCHeap;
+
+// An output stream that logs to the logging framework, and embeds a ResourceMark.
+//
+// The backing buffer is allocated in Resource memory.
+// The class is intended to be stack allocated.
+// The class provides its own ResourceMark,
+// so care needs to be taken when nested ResourceMarks are used.
+typedef LogStreamBase<stringStreamWithResourceMark> LogStream;
+
+// Support creation of a LogStream without having to provide a LogTarget pointer.
+#define LogStreamHandle(level, ...) LogStreamTemplate<LogLevel::level, LOG_TAGS(__VA_ARGS__)>
+
+template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
+class LogStreamTemplate : public LogStream {
+public:
+ LogStreamTemplate() : LogStream((LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>*)NULL) {}
+};
+
#endif // SHARE_VM_LOGGING_LOGSTREAM_HPP
--- a/hotspot/src/share/vm/logging/logStream.inline.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logStream.inline.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -30,10 +30,12 @@
#include "memory/resourceArea.hpp"
#include "utilities/ostream.hpp"
-inline void LogStreamNoResourceMark::write(const char* s, size_t len) {
+template <class streamClass>
+inline void LogStreamBase<streamClass>::write(const char* s, size_t len) {
if (len > 0 && s[len - 1] == '\n') {
_current_line.write(s, len - 1);
- _tagset->write(_level, "%s", _current_line.as_string());
+ _current_line.write("\0", 1);
+ _log_handle.print("%s", _current_line.base());
_current_line.reset();
} else {
_current_line.write(s, len);
@@ -41,54 +43,4 @@
update_position(s, len);
}
-// An output stream that logs to the logging framework, and embeds a ResourceMark.
-//
-// The class is intended to be stack allocated.
-// Care needs to be taken when nested ResourceMarks are used.
-class LogStream : public outputStream {
-private:
- ResourceMark _embedded_resource_mark;
- LogStreamNoResourceMark _stream;
-
-public:
- // Constructor to support creation from a LogTarget instance.
- //
- // LogTarget(Debug, gc) log;
- // LogStream(log) stream;
- template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
- LogStream(const LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>& type_carrier) :
- _embedded_resource_mark(),
- _stream(level, &LogTagSetMapping<T0, T1, T2, T3, T4>::tagset()) {}
-
- // Constructor to support creation from typed (likely NULL) pointer. Mostly used by the logging framework.
- //
- // LogStream stream(log.debug());
- // LogStream stream((LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>*)NULL);
- template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
- LogStream(const LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>* type_carrier) :
- _embedded_resource_mark(),
- _stream(level, &LogTagSetMapping<T0, T1, T2, T3, T4>::tagset()) {}
-
- // Constructor to support creation from a LogTargetHandle.
- //
- // LogTarget(Debug, gc) log;
- // LogTargetHandle(log) handle;
- // LogStream stream(handle);
- LogStream(LogTargetHandle handle) :
- _embedded_resource_mark(),
- _stream(handle._level, handle._tagset) {}
-
- // Override of outputStream::write.
- void write(const char* s, size_t len) { _stream.write(s, len); }
-};
-
-// Support creation of a LogStream without having to provide a LogTarget pointer.
-#define LogStreamHandle(level, ...) LogStreamTemplate<LogLevel::level, LOG_TAGS(__VA_ARGS__)>
-
-template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
-class LogStreamTemplate : public LogStream {
-public:
- LogStreamTemplate() : LogStream((LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>*)NULL) {}
-};
-
#endif // SHARE_VM_LOGGING_LOGSTREAM_INLINE_HPP
--- a/hotspot/src/share/vm/logging/logTag.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTag.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -48,6 +48,7 @@
LOG_TAG(classpath) \
LOG_TAG(compaction) \
LOG_TAG(constraints) \
+ LOG_TAG(coops) \
LOG_TAG(cpu) \
LOG_TAG(cset) \
LOG_TAG(defaultmethods) \
@@ -69,6 +70,7 @@
LOG_TAG(monitorinflation) \
LOG_TAG(monitormismatch) \
LOG_TAG(os) \
+ LOG_TAG(pagesize) \
LOG_TAG(phases) \
LOG_TAG(plab) \
LOG_TAG(promotion) \
--- a/hotspot/src/share/vm/logging/logTagLevelExpression.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTagLevelExpression.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -36,9 +36,12 @@
// Class used to temporary encode a 'what'-expression during log configuration.
// Consists of a combination of tags and levels, e.g. "tag1+tag2=level1,tag3*=level2".
class LogTagLevelExpression : public StackObj {
- friend void LogConfiguration::configure_stdout(LogLevelType, bool, ...);
+ public:
+ static const size_t MaxCombinations = 256;
+
private:
- static const size_t MaxCombinations = 32;
+ friend void LogConfiguration::configure_stdout(LogLevelType, bool, ...);
+
static const char* DefaultExpressionString;
size_t _ntags, _ncombinations;
--- a/hotspot/src/share/vm/logging/logTagSet.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTagSet.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -98,6 +98,7 @@
const size_t vwrite_buffer_size = 512;
void LogTagSet::vwrite(LogLevelType level, const char* fmt, va_list args) {
+ assert(level >= LogLevel::First && level <= LogLevel::Last, "Log level:%d is incorrect", level);
char buf[vwrite_buffer_size];
va_list saved_args; // For re-format on buf overflow.
va_copy(saved_args, args);
--- a/hotspot/src/share/vm/logging/logTagSet.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTagSet.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -64,6 +64,10 @@
return _list;
}
+ static size_t ntagsets() {
+ return _ntagsets;
+ }
+
LogTagSet* next() {
return _next;
}
--- a/hotspot/src/share/vm/memory/allocation.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/memory/allocation.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -143,8 +143,9 @@
mtTest = 0x0D, // Test type for verifying NMT
mtTracing = 0x0E, // memory used for Tracing
mtLogging = 0x0F, // memory for logging
- mtNone = 0x10, // undefined
- mt_number_of_types = 0x11 // number of memory types (mtDontTrack
+ mtArguments = 0x10, // memory for argument processing
+ mtNone = 0x11, // undefined
+ mt_number_of_types = 0x12 // number of memory types (mtDontTrack
// is not included as validate type)
};
--- a/hotspot/src/share/vm/memory/filemap.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/memory/filemap.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -959,6 +959,16 @@
return false;
}
+// Check if a given address is within one of the shared regions (ro, rw, md, mc)
+bool FileMapInfo::is_in_shared_region(const void* p, int idx) {
+ assert((idx >= MetaspaceShared::ro) && (idx <= MetaspaceShared::mc), "invalid region index");
+ char* base = _header->region_addr(idx);
+ if (p >= base && p < base + _header->_space[idx]._used) {
+ return true;
+ }
+ return false;
+}
+
void FileMapInfo::print_shared_spaces() {
tty->print_cr("Shared Spaces:");
for (int i = 0; i < MetaspaceShared::n_regions; i++) {
--- a/hotspot/src/share/vm/memory/filemap.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/memory/filemap.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -107,6 +107,8 @@
int _narrow_klass_shift; // save narrow klass base and shift
address _narrow_klass_base;
char* _misc_data_patching_start;
+ address _cds_i2i_entry_code_buffers;
+ size_t _cds_i2i_entry_code_buffers_size;
struct space_info {
int _crc; // crc checksum of the current space
@@ -195,6 +197,19 @@
char* misc_data_patching_start() { return _header->_misc_data_patching_start; }
void set_misc_data_patching_start(char* p) { _header->_misc_data_patching_start = p; }
+ address cds_i2i_entry_code_buffers() {
+ return _header->_cds_i2i_entry_code_buffers;
+ }
+ void set_cds_i2i_entry_code_buffers(address addr) {
+ _header->_cds_i2i_entry_code_buffers = addr;
+ }
+ size_t cds_i2i_entry_code_buffers_size() {
+ return _header->_cds_i2i_entry_code_buffers_size;
+ }
+ void set_cds_i2i_entry_code_buffers_size(size_t s) {
+ _header->_cds_i2i_entry_code_buffers_size = s;
+ }
+
static FileMapInfo* current_info() {
CDS_ONLY(return _current_info;)
NOT_CDS(return NULL;)
@@ -234,6 +249,7 @@
// Return true if given address is in the mapped shared space.
bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false);
+ bool is_in_shared_region(const void* p, int idx) NOT_CDS_RETURN_(false);
void print_shared_spaces() NOT_CDS_RETURN;
static size_t shared_spaces_size() {
--- a/hotspot/src/share/vm/memory/iterator.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/memory/iterator.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -27,7 +27,7 @@
#include "memory/allocation.hpp"
#include "memory/memRegion.hpp"
-#include "utilities/top.hpp"
+#include "oops/oopsHierarchy.hpp"
class CodeBlob;
class nmethod;
@@ -35,6 +35,7 @@
class DataLayout;
class KlassClosure;
class ClassLoaderData;
+class Symbol;
// The following classes are C++ `closures` for iterating over objects, roots and spaces
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -59,6 +59,8 @@
bool MetaspaceShared::_check_classes_made_progress;
bool MetaspaceShared::_has_error_classes;
bool MetaspaceShared::_archive_loading_failed = false;
+address MetaspaceShared::_cds_i2i_entry_code_buffers = NULL;
+size_t MetaspaceShared::_cds_i2i_entry_code_buffers_size = 0;
SharedMiscRegion MetaspaceShared::_mc;
SharedMiscRegion MetaspaceShared::_md;
@@ -129,6 +131,21 @@
soc->do_tag(666);
}
+address MetaspaceShared::cds_i2i_entry_code_buffers(size_t total_size) {
+ if (DumpSharedSpaces) {
+ if (_cds_i2i_entry_code_buffers == NULL) {
+ _cds_i2i_entry_code_buffers = (address)misc_data_space_alloc(total_size);
+ _cds_i2i_entry_code_buffers_size = total_size;
+ }
+ } else if (UseSharedSpaces) {
+ assert(_cds_i2i_entry_code_buffers != NULL, "must already been initialized");
+ } else {
+ return NULL;
+ }
+
+ assert(_cds_i2i_entry_code_buffers_size == total_size, "must not change");
+ return _cds_i2i_entry_code_buffers;
+}
// CDS code for dumping shared archive.
@@ -576,6 +593,8 @@
&md_top, md_end,
&mc_top, mc_end);
+ guarantee(md_top <= md_end, "Insufficient space for vtables.");
+
// Reorder the system dictionary. (Moving the symbols affects
// how the hash table indices are calculated.)
// Not doing this either.
@@ -668,6 +687,8 @@
FileMapInfo* mapinfo = new FileMapInfo();
mapinfo->populate_header(MetaspaceShared::max_alignment());
mapinfo->set_misc_data_patching_start((char*)vtbl_list);
+ mapinfo->set_cds_i2i_entry_code_buffers(MetaspaceShared::cds_i2i_entry_code_buffers());
+ mapinfo->set_cds_i2i_entry_code_buffers_size(MetaspaceShared::cds_i2i_entry_code_buffers_size());
for (int pass=1; pass<=2; pass++) {
if (pass == 1) {
@@ -686,7 +707,7 @@
mapinfo->write_region(MetaspaceShared::md, _md_vs.low(),
pointer_delta(md_top, _md_vs.low(), sizeof(char)),
SharedMiscDataSize,
- false, false);
+ false, true);
mapinfo->write_region(MetaspaceShared::mc, _mc_vs.low(),
pointer_delta(mc_top, _mc_vs.low(), sizeof(char)),
SharedMiscCodeSize,
@@ -980,6 +1001,11 @@
return UseSharedSpaces && FileMapInfo::current_info()->is_in_shared_space(p);
}
+// Return true if given address is in the misc data region
+bool MetaspaceShared::is_in_shared_region(const void* p, int idx) {
+ return UseSharedSpaces && FileMapInfo::current_info()->is_in_shared_region(p, idx);
+}
+
bool MetaspaceShared::is_string_region(int idx) {
return (idx >= MetaspaceShared::first_string &&
idx < MetaspaceShared::first_string + MetaspaceShared::max_strings);
@@ -1053,6 +1079,8 @@
void MetaspaceShared::initialize_shared_spaces() {
FileMapInfo *mapinfo = FileMapInfo::current_info();
+ _cds_i2i_entry_code_buffers = mapinfo->cds_i2i_entry_code_buffers();
+ _cds_i2i_entry_code_buffers_size = mapinfo->cds_i2i_entry_code_buffers_size();
char* buffer = mapinfo->misc_data_patching_start();
// Skip over (reserve space for) a list of addresses of C++ vtables
--- a/hotspot/src/share/vm/memory/metaspaceShared.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -50,17 +50,14 @@
#define MIN_SHARED_READ_ONLY_SIZE (NOT_LP64(8*M) LP64_ONLY(9*M))
// the MIN_SHARED_MISC_DATA_SIZE and MIN_SHARED_MISC_CODE_SIZE estimates are based on
-// MetaspaceShared::generate_vtable_methods().
-// The minimum size only accounts for the vtable methods. Any size less than the
-// minimum required size would cause vm crash when allocating the vtable methods.
-#define SHARED_MISC_SIZE_FOR(size) (DEFAULT_VTBL_VIRTUALS_COUNT*DEFAULT_VTBL_LIST_SIZE*size)
+// the sizes required for dumping the archive using the default classlist. The sizes
+// are multiplied by 1.5 for a safety margin.
#define DEFAULT_SHARED_MISC_DATA_SIZE (NOT_LP64(2*M) LP64_ONLY(4*M))
-#define MIN_SHARED_MISC_DATA_SIZE (SHARED_MISC_SIZE_FOR(sizeof(void*)))
+#define MIN_SHARED_MISC_DATA_SIZE (NOT_LP64(1*M) LP64_ONLY(1200*K))
#define DEFAULT_SHARED_MISC_CODE_SIZE (120*K)
-#define MIN_SHARED_MISC_CODE_SIZE (SHARED_MISC_SIZE_FOR(sizeof(void*))+SHARED_MISC_SIZE_FOR(DEFAULT_VTBL_METHOD_SIZE)+DEFAULT_VTBL_COMMON_CODE_SIZE)
-
+#define MIN_SHARED_MISC_CODE_SIZE (NOT_LP64(63*K) LP64_ONLY(69*K))
#define DEFAULT_COMBINED_SIZE (DEFAULT_SHARED_READ_WRITE_SIZE+DEFAULT_SHARED_READ_ONLY_SIZE+DEFAULT_SHARED_MISC_DATA_SIZE+DEFAULT_SHARED_MISC_CODE_SIZE)
// the max size is the MAX size (ie. 0x7FFFFFFF) - the total size of
@@ -128,6 +125,8 @@
static bool _check_classes_made_progress;
static bool _has_error_classes;
static bool _archive_loading_failed;
+ static address _cds_i2i_entry_code_buffers;
+ static size_t _cds_i2i_entry_code_buffers_size;
// Used only during dumping.
static SharedMiscRegion _md;
@@ -185,6 +184,9 @@
// Return true if given address is in the mapped shared space.
static bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false);
+ // Return true if given address is in the shared region corresponding to the idx
+ static bool is_in_shared_region(const void* p, int idx) NOT_CDS_RETURN_(false);
+
static bool is_string_region(int idx) NOT_CDS_RETURN_(false);
static void generate_vtable_methods(void** vtbl_list,
@@ -218,6 +220,15 @@
static char* misc_code_space_alloc(size_t num_bytes) { return _mc.alloc(num_bytes); }
static char* misc_data_space_alloc(size_t num_bytes) { return _md.alloc(num_bytes); }
+ static address cds_i2i_entry_code_buffers(size_t total_size);
+
+ static address cds_i2i_entry_code_buffers() {
+ return _cds_i2i_entry_code_buffers;
+ }
+ static size_t cds_i2i_entry_code_buffers_size() {
+ return _cds_i2i_entry_code_buffers_size;
+ }
+
static SharedMiscRegion* misc_code_region() {
assert(DumpSharedSpaces, "used during dumping only");
return &_mc;
--- a/hotspot/src/share/vm/memory/resourceArea.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/memory/resourceArea.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -26,7 +26,7 @@
#define SHARE_VM_MEMORY_RESOURCEAREA_HPP
#include "memory/allocation.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/thread.hpp"
// The resource area holds temporary data structures in the VM.
// The actual allocation areas are thread local. Typical usage:
--- a/hotspot/src/share/vm/memory/universe.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/memory/universe.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -747,8 +747,10 @@
Universe::set_narrow_ptrs_base(Universe::narrow_oop_base());
- if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) {
- Universe::print_compressed_oops_mode(tty);
+ if (log_is_enabled(Info, gc, heap, coops)) {
+ ResourceMark rm;
+ outputStream* logst = Log(gc, heap, coops)::info_stream();
+ Universe::print_compressed_oops_mode(logst);
}
// Tell tests in which mode we run.
@@ -776,8 +778,8 @@
}
void Universe::print_compressed_oops_mode(outputStream* st) {
- st->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB",
- p2i(Universe::heap()->base()), Universe::heap()->reserved_region().byte_size()/M);
+ st->print("Heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB",
+ p2i(Universe::heap()->base()), Universe::heap()->reserved_region().byte_size()/M);
st->print(", Compressed Oops mode: %s", narrow_oop_mode_to_string(narrow_oop_mode()));
--- a/hotspot/src/share/vm/memory/virtualspace.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/memory/virtualspace.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -24,6 +24,8 @@
#include "precompiled.hpp"
#include "code/codeCacheExtensions.hpp"
+#include "logging/log.hpp"
+#include "memory/resourceArea.hpp"
#include "memory/virtualspace.hpp"
#include "oops/markOop.hpp"
#include "oops/oop.inline.hpp"
@@ -78,10 +80,7 @@
// Different reserve address may be acceptable in other cases
// but for compressed oops heap should be at requested address.
assert(UseCompressedOops, "currently requested address used only for compressed oops");
- if (PrintCompressedOopsMode) {
- tty->cr();
- tty->print_cr("Reserved memory not at requested address: " PTR_FORMAT " vs " PTR_FORMAT, p2i(base), p2i(requested_address));
- }
+ log_debug(gc, heap, coops)("Reserved memory not at requested address: " PTR_FORMAT " vs " PTR_FORMAT, p2i(base), p2i(requested_address));
// OS ignored requested address. Try different address.
if (special) {
if (!os::release_memory_special(base, size)) {
@@ -143,10 +142,7 @@
// failed; try to reserve regular memory below
if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||
!FLAG_IS_DEFAULT(LargePageSizeInBytes))) {
- if (PrintCompressedOopsMode) {
- tty->cr();
- tty->print_cr("Reserve regular memory without large pages.");
- }
+ log_debug(gc, heap, coops)("Reserve regular memory without large pages");
}
}
}
@@ -286,11 +282,10 @@
if (!os::protect_memory(_base, _noaccess_prefix, os::MEM_PROT_NONE, _special)) {
fatal("cannot protect protection page");
}
- if (PrintCompressedOopsMode) {
- tty->cr();
- tty->print_cr("Protected page at the reserved heap base: "
- PTR_FORMAT " / " INTX_FORMAT " bytes", p2i(_base), _noaccess_prefix);
- }
+ log_debug(gc, heap, coops)("Protected page at the reserved heap base: "
+ PTR_FORMAT " / " INTX_FORMAT " bytes",
+ p2i(_base),
+ _noaccess_prefix);
assert(Universe::narrow_oop_use_implicit_null_checks() == true, "not initialized?");
} else {
Universe::set_narrow_oop_use_implicit_null_checks(false);
@@ -321,10 +316,10 @@
bool special = large && !os::can_commit_large_page_memory();
char* base = NULL;
- if (PrintCompressedOopsMode && Verbose) {
- tty->print("Trying to allocate at address " PTR_FORMAT " heap of size " SIZE_FORMAT_HEX ".\n",
- p2i(requested_address), size);
- }
+ log_trace(gc, heap, coops)("Trying to allocate at address " PTR_FORMAT
+ " heap of size " SIZE_FORMAT_HEX,
+ p2i(requested_address),
+ size);
if (special) {
base = os::reserve_memory_special(size, alignment, requested_address, false);
@@ -343,10 +338,7 @@
// Failed; try to reserve regular memory below
if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||
!FLAG_IS_DEFAULT(LargePageSizeInBytes))) {
- if (PrintCompressedOopsMode) {
- tty->cr();
- tty->print_cr("Reserve regular memory without large pages.");
- }
+ log_debug(gc, heap, coops)("Reserve regular memory without large pages");
}
// Optimistically assume that the OSes returns an aligned base pointer.
@@ -558,9 +550,7 @@
// Last, desperate try without any placement.
if (_base == NULL) {
- if (PrintCompressedOopsMode && Verbose) {
- tty->print("Trying to allocate at address NULL heap of size " SIZE_FORMAT_HEX ".\n", size + noaccess_prefix);
- }
+ log_trace(gc, heap, coops)("Trying to allocate at address NULL heap of size " SIZE_FORMAT_HEX, size + noaccess_prefix);
initialize(size + noaccess_prefix, alignment, large, NULL, false);
}
}
--- a/hotspot/src/share/vm/oops/constMethod.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/constMethod.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -66,6 +66,7 @@
set_max_locals(0);
set_method_idnum(0);
set_size_of_parameters(0);
+ set_result_type(T_VOID);
}
// Accessor that copies to metadata.
--- a/hotspot/src/share/vm/oops/constMethod.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/constMethod.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -121,6 +121,7 @@
};
class KlassSizeStats;
+class AdapterHandlerEntry;
// Class to collect the sizes of ConstMethod inline tables
#define INLINE_TABLES_DO(do_element) \
@@ -201,8 +202,15 @@
// Raw stackmap data for the method
Array<u1>* _stackmap_data;
+ // Adapter blob (i2c/c2i) for this Method*. Set once when method is linked.
+ union {
+ AdapterHandlerEntry* _adapter;
+ AdapterHandlerEntry** _adapter_trampoline;
+ };
+
int _constMethod_size;
u2 _flags;
+ u1 _result_type; // BasicType of result
// Size of Java bytecodes allocated immediately after Method*.
u2 _code_size;
@@ -276,6 +284,29 @@
void copy_stackmap_data(ClassLoaderData* loader_data, u1* sd, int length, TRAPS);
bool has_stackmap_table() const { return _stackmap_data != NULL; }
+ // adapter
+ void set_adapter_entry(AdapterHandlerEntry* adapter) {
+ assert(!is_shared(), "shared methods have fixed adapter_trampoline");
+ _adapter = adapter;
+ }
+ void set_adapter_trampoline(AdapterHandlerEntry** trampoline) {
+ assert(DumpSharedSpaces, "must be");
+ assert(*trampoline == NULL, "must be NULL during dump time, to be initialized at run time");
+ _adapter_trampoline = trampoline;
+ }
+ void update_adapter_trampoline(AdapterHandlerEntry* adapter) {
+ assert(is_shared(), "must be");
+ *_adapter_trampoline = adapter;
+ assert(this->adapter() == adapter, "must be");
+ }
+ AdapterHandlerEntry* adapter() {
+ if (is_shared()) {
+ return *_adapter_trampoline;
+ } else {
+ return _adapter;
+ }
+ }
+
void init_fingerprint() {
const uint64_t initval = UCONST64(0x8000000000000000);
_fingerprint = initval;
@@ -464,6 +495,8 @@
static ByteSize size_of_parameters_offset()
{ return byte_offset_of(ConstMethod, _size_of_parameters); }
+ static ByteSize result_type_offset()
+ { return byte_offset_of(ConstMethod, _result_type); }
// Unique id for the method
static const u2 MAX_IDNUM;
@@ -486,6 +519,8 @@
int size_of_parameters() const { return _size_of_parameters; }
void set_size_of_parameters(int size) { _size_of_parameters = size; }
+ void set_result_type(BasicType rt) { assert(rt < 16, "result type too large");
+ _result_type = (u1)rt; }
// Deallocation for RedefineClasses
void deallocate_contents(ClassLoaderData* loader_data);
bool is_klass() const { return false; }
--- a/hotspot/src/share/vm/oops/constantPool.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/constantPool.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -283,8 +283,9 @@
this_key->record_dependency(k(), CHECK_NULL); // Can throw OOM
// logging for classresolve tag.
- trace_class_resolution(this_cp, k);
-
+ if (log_is_enabled(Debug, classresolve)){
+ trace_class_resolution(this_cp, k);
+ }
this_cp->klass_at_put(which, k());
entry = this_cp->resolved_klass_at(which);
assert(entry.is_resolved() && entry.get_klass()->is_klass(), "must be resolved at this point");
@@ -340,9 +341,7 @@
int cache_index = decode_cpcache_index(which, true);
if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) {
// FIXME: should be an assert
- if (PrintMiscellaneous && (Verbose||WizardMode)) {
- tty->print_cr("bad operand %d in:", which); cpool->print();
- }
+ log_debug(classresolve)("bad operand %d in:", which); cpool->print();
return NULL;
}
ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);
@@ -396,7 +395,7 @@
int i = which;
if (!uncached && cache() != NULL) {
if (ConstantPool::is_invokedynamic_index(which)) {
- // Invokedynamic index is index into resolved_references
+ // Invokedynamic index is index into the constant pool cache
int pool_index = invokedynamic_cp_cache_entry_at(which)->constant_pool_index();
pool_index = invoke_dynamic_name_and_type_ref_index_at(pool_index);
assert(tag_at(pool_index).is_name_and_type(), "");
@@ -672,10 +671,11 @@
int callee_index = this_cp->method_handle_klass_index_at(index);
Symbol* name = this_cp->method_handle_name_ref_at(index);
Symbol* signature = this_cp->method_handle_signature_ref_at(index);
- if (PrintMiscellaneous)
- tty->print_cr("resolve JVM_CONSTANT_MethodHandle:%d [%d/%d/%d] %s.%s",
- ref_kind, index, this_cp->method_handle_index_at(index),
- callee_index, name->as_C_string(), signature->as_C_string());
+ { ResourceMark rm(THREAD);
+ log_debug(classresolve)("resolve JVM_CONSTANT_MethodHandle:%d [%d/%d/%d] %s.%s",
+ ref_kind, index, this_cp->method_handle_index_at(index),
+ callee_index, name->as_C_string(), signature->as_C_string());
+ }
KlassHandle callee;
{ Klass* k = klass_at_impl(this_cp, callee_index, true, CHECK_NULL);
callee = KlassHandle(THREAD, k);
@@ -694,10 +694,11 @@
case JVM_CONSTANT_MethodType:
{
Symbol* signature = this_cp->method_type_signature_at(index);
- if (PrintMiscellaneous)
- tty->print_cr("resolve JVM_CONSTANT_MethodType [%d/%d] %s",
- index, this_cp->method_type_index_at(index),
- signature->as_C_string());
+ { ResourceMark rm(THREAD);
+ log_debug(classresolve)("resolve JVM_CONSTANT_MethodType [%d/%d] %s",
+ index, this_cp->method_type_index_at(index),
+ signature->as_C_string());
+ }
KlassHandle klass(THREAD, this_cp->pool_holder());
Handle value = SystemDictionary::find_method_handle_type(signature, klass, THREAD);
result_oop = value();
@@ -964,8 +965,8 @@
case JVM_CONSTANT_MethodType:
{
- int k1 = method_type_index_at_error_ok(index1);
- int k2 = cp2->method_type_index_at_error_ok(index2);
+ int k1 = method_type_index_at(index1);
+ int k2 = cp2->method_type_index_at(index2);
bool match = compare_entry_to(k1, cp2, k2, CHECK_false);
if (match) {
return true;
@@ -974,11 +975,11 @@
case JVM_CONSTANT_MethodHandle:
{
- int k1 = method_handle_ref_kind_at_error_ok(index1);
- int k2 = cp2->method_handle_ref_kind_at_error_ok(index2);
+ int k1 = method_handle_ref_kind_at(index1);
+ int k2 = cp2->method_handle_ref_kind_at(index2);
if (k1 == k2) {
- int i1 = method_handle_index_at_error_ok(index1);
- int i2 = cp2->method_handle_index_at_error_ok(index2);
+ int i1 = method_handle_index_at(index1);
+ int i2 = cp2->method_handle_index_at(index2);
bool match = compare_entry_to(i1, cp2, i2, CHECK_false);
if (match) {
return true;
@@ -1310,15 +1311,15 @@
case JVM_CONSTANT_MethodType:
case JVM_CONSTANT_MethodTypeInError:
{
- jint k = from_cp->method_type_index_at_error_ok(from_i);
+ jint k = from_cp->method_type_index_at(from_i);
to_cp->method_type_index_at_put(to_i, k);
} break;
case JVM_CONSTANT_MethodHandle:
case JVM_CONSTANT_MethodHandleInError:
{
- int k1 = from_cp->method_handle_ref_kind_at_error_ok(from_i);
- int k2 = from_cp->method_handle_index_at_error_ok(from_i);
+ int k1 = from_cp->method_handle_ref_kind_at(from_i);
+ int k2 = from_cp->method_handle_index_at(from_i);
to_cp->method_handle_index_at_put(to_i, k1, k2);
} break;
@@ -1754,8 +1755,8 @@
case JVM_CONSTANT_MethodHandle:
case JVM_CONSTANT_MethodHandleInError: {
*bytes = JVM_CONSTANT_MethodHandle;
- int kind = method_handle_ref_kind_at_error_ok(idx);
- idx1 = method_handle_index_at_error_ok(idx);
+ int kind = method_handle_ref_kind_at(idx);
+ idx1 = method_handle_index_at(idx);
*(bytes+1) = (unsigned char) kind;
Bytes::put_Java_u2((address) (bytes+2), idx1);
DBG(printf("JVM_CONSTANT_MethodHandle: %d %hd", kind, idx1));
@@ -1764,7 +1765,7 @@
case JVM_CONSTANT_MethodType:
case JVM_CONSTANT_MethodTypeInError: {
*bytes = JVM_CONSTANT_MethodType;
- idx1 = method_type_index_at_error_ok(idx);
+ idx1 = method_type_index_at(idx);
Bytes::put_Java_u2((address) (bytes+1), idx1);
DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1));
break;
@@ -1952,12 +1953,12 @@
break;
case JVM_CONSTANT_MethodHandle :
case JVM_CONSTANT_MethodHandleInError :
- st->print("ref_kind=%d", method_handle_ref_kind_at_error_ok(index));
- st->print(" ref_index=%d", method_handle_index_at_error_ok(index));
+ st->print("ref_kind=%d", method_handle_ref_kind_at(index));
+ st->print(" ref_index=%d", method_handle_index_at(index));
break;
case JVM_CONSTANT_MethodType :
case JVM_CONSTANT_MethodTypeInError :
- st->print("signature_index=%d", method_type_index_at_error_ok(index));
+ st->print("signature_index=%d", method_type_index_at(index));
break;
case JVM_CONSTANT_InvokeDynamic :
{
--- a/hotspot/src/share/vm/oops/constantPool.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/constantPool.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -460,41 +460,21 @@
return *int_at_addr(which);
}
- private:
- int method_handle_ref_kind_at(int which, bool error_ok) {
+ int method_handle_ref_kind_at(int which) {
assert(tag_at(which).is_method_handle() ||
- (error_ok && tag_at(which).is_method_handle_in_error()), "Corrupted constant pool");
+ tag_at(which).is_method_handle_in_error(), "Corrupted constant pool");
return extract_low_short_from_int(*int_at_addr(which)); // mask out unwanted ref_index bits
}
- int method_handle_index_at(int which, bool error_ok) {
+ int method_handle_index_at(int which) {
assert(tag_at(which).is_method_handle() ||
- (error_ok && tag_at(which).is_method_handle_in_error()), "Corrupted constant pool");
+ tag_at(which).is_method_handle_in_error(), "Corrupted constant pool");
return extract_high_short_from_int(*int_at_addr(which)); // shift out unwanted ref_kind bits
}
- int method_type_index_at(int which, bool error_ok) {
+ int method_type_index_at(int which) {
assert(tag_at(which).is_method_type() ||
- (error_ok && tag_at(which).is_method_type_in_error()), "Corrupted constant pool");
+ tag_at(which).is_method_type_in_error(), "Corrupted constant pool");
return *int_at_addr(which);
}
- public:
- int method_handle_ref_kind_at(int which) {
- return method_handle_ref_kind_at(which, false);
- }
- int method_handle_ref_kind_at_error_ok(int which) {
- return method_handle_ref_kind_at(which, true);
- }
- int method_handle_index_at(int which) {
- return method_handle_index_at(which, false);
- }
- int method_handle_index_at_error_ok(int which) {
- return method_handle_index_at(which, true);
- }
- int method_type_index_at(int which) {
- return method_type_index_at(which, false);
- }
- int method_type_index_at_error_ok(int which) {
- return method_type_index_at(which, true);
- }
// Derived queries:
Symbol* method_handle_name_ref_at(int which) {
--- a/hotspot/src/share/vm/oops/cpCache.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/cpCache.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -77,18 +77,19 @@
// f2 flag true if f2 contains an oop (e.g., virtual final method)
// fv flag true if invokeinterface used for method in class Object
//
-// The flags 31, 30, 29, 28 together build a 4 bit number 0 to 8 with the
+// The flags 31, 30, 29, 28 together build a 4 bit number 0 to 16 with the
// following mapping to the TosState states:
//
// btos: 0
-// ctos: 1
-// stos: 2
-// itos: 3
-// ltos: 4
-// ftos: 5
-// dtos: 6
-// atos: 7
-// vtos: 8
+// ztos: 1
+// ctos: 2
+// stos: 3
+// itos: 4
+// ltos: 5
+// ftos: 6
+// dtos: 7
+// atos: 8
+// vtos: 9
//
// Entry specific: field entries:
// _indices = get (b1 section) and put (b2 section) bytecodes, original constant pool index
@@ -352,14 +353,8 @@
bool has_method_type() const { return (!is_f1_null()) && (_flags & (1 << has_method_type_shift)) != 0; }
bool is_method_entry() const { return (_flags & (1 << is_field_entry_shift)) == 0; }
bool is_field_entry() const { return (_flags & (1 << is_field_entry_shift)) != 0; }
- bool is_byte() const { return flag_state() == btos; }
- bool is_char() const { return flag_state() == ctos; }
- bool is_short() const { return flag_state() == stos; }
- bool is_int() const { return flag_state() == itos; }
bool is_long() const { return flag_state() == ltos; }
- bool is_float() const { return flag_state() == ftos; }
bool is_double() const { return flag_state() == dtos; }
- bool is_object() const { return flag_state() == atos; }
TosState flag_state() const { assert((uint)number_of_states <= (uint)tos_state_mask+1, "");
return (TosState)((_flags >> tos_state_shift) & tos_state_mask); }
--- a/hotspot/src/share/vm/oops/klass.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/klass.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -342,6 +342,21 @@
assert(btvalue >= T_BOOLEAN && btvalue <= T_OBJECT, "sanity");
return (BasicType) btvalue;
}
+
+ // Want a pattern to quickly diff against layout header in register
+ // find something less clever!
+ static int layout_helper_boolean_diffbit() {
+ jint zlh = array_layout_helper(T_BOOLEAN);
+ jint blh = array_layout_helper(T_BYTE);
+ assert(zlh != blh, "array layout helpers must differ");
+ int diffbit = 1;
+ while ((diffbit & (zlh ^ blh)) == 0 && (diffbit & zlh) == 0) {
+ diffbit <<= 1;
+ assert(diffbit != 0, "make sure T_BOOLEAN has a different bit than T_BYTE");
+ }
+ return diffbit;
+ }
+
static int layout_helper_log2_element_size(jint lh) {
assert(lh < (jint)_lh_neutral_value, "must be array");
int l2esz = (lh >> _lh_log2_element_size_shift) & _lh_log2_element_size_mask;
--- a/hotspot/src/share/vm/oops/method.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/method.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -38,6 +38,7 @@
#include "interpreter/oopMapCache.hpp"
#include "memory/heapInspection.hpp"
#include "memory/metadataFactory.hpp"
+#include "memory/metaspaceShared.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "oops/constMethod.hpp"
@@ -83,9 +84,6 @@
NoSafepointVerifier no_safepoint;
set_constMethod(xconst);
set_access_flags(access_flags);
-#ifdef CC_INTERP
- set_result_index(T_VOID);
-#endif
set_intrinsic_id(vmIntrinsics::_none);
set_jfr_towrite(false);
set_force_inline(false);
@@ -123,18 +121,18 @@
}
address Method::get_i2c_entry() {
- assert(_adapter != NULL, "must have");
- return _adapter->get_i2c_entry();
+ assert(adapter() != NULL, "must have");
+ return adapter()->get_i2c_entry();
}
address Method::get_c2i_entry() {
- assert(_adapter != NULL, "must have");
- return _adapter->get_c2i_entry();
+ assert(adapter() != NULL, "must have");
+ return adapter()->get_c2i_entry();
}
address Method::get_c2i_unverified_entry() {
- assert(_adapter != NULL, "must have");
- return _adapter->get_c2i_unverified_entry();
+ assert(adapter() != NULL, "must have");
+ return adapter()->get_c2i_unverified_entry();
}
char* Method::name_and_sig_as_C_string() const {
@@ -444,12 +442,6 @@
set_size_of_parameters(asc.size() + (is_static() ? 0 : 1));
}
-#ifdef CC_INTERP
-void Method::set_result_index(BasicType type) {
- _result_index = Interpreter::BasicType_as_index(type);
-}
-#endif
-
BasicType Method::result_type() const {
ResultTypeFinder rtf(signature());
return rtf.type();
@@ -892,10 +884,10 @@
// this may be NULL if c2i adapters have not been made yet
// Only should happen at allocate time.
- if (_adapter == NULL) {
+ if (adapter() == NULL) {
_from_compiled_entry = NULL;
} else {
- _from_compiled_entry = _adapter->get_c2i_entry();
+ _from_compiled_entry = adapter()->get_c2i_entry();
}
OrderAccess::storestore();
_from_interpreted_entry = _i2i_entry;
@@ -903,47 +895,68 @@
_code = NULL;
}
+#if INCLUDE_CDS
// Called by class data sharing to remove any entry points (which are not shared)
void Method::unlink_method() {
_code = NULL;
- _i2i_entry = NULL;
- _from_interpreted_entry = NULL;
+
+ assert(DumpSharedSpaces, "dump time only");
+ // Set the values to what they should be at run time. Note that
+ // this Method can no longer be executed during dump time.
+ _i2i_entry = Interpreter::entry_for_cds_method(this);
+ _from_interpreted_entry = _i2i_entry;
+
if (is_native()) {
*native_function_addr() = NULL;
set_signature_handler(NULL);
}
NOT_PRODUCT(set_compiled_invocation_count(0);)
- _adapter = NULL;
- _from_compiled_entry = NULL;
+
+ CDSAdapterHandlerEntry* cds_adapter = (CDSAdapterHandlerEntry*)adapter();
+ constMethod()->set_adapter_trampoline(cds_adapter->get_adapter_trampoline());
+ _from_compiled_entry = cds_adapter->get_c2i_entry_trampoline();
+ assert(*((int*)_from_compiled_entry) == 0, "must be NULL during dump time, to be initialized at run time");
+
// In case of DumpSharedSpaces, _method_data should always be NULL.
- //
- // During runtime (!DumpSharedSpaces), when we are cleaning a
- // shared class that failed to load, this->link_method() may
- // have already been called (before an exception happened), so
- // this->_method_data may not be NULL.
- assert(!DumpSharedSpaces || _method_data == NULL, "unexpected method data?");
+ assert(_method_data == NULL, "unexpected method data?");
set_method_data(NULL);
clear_method_counters();
}
+#endif
// Called when the method_holder is getting linked. Setup entrypoints so the method
// is ready to be called from interpreter, compiler, and vtables.
void Method::link_method(const methodHandle& h_method, TRAPS) {
// If the code cache is full, we may reenter this function for the
// leftover methods that weren't linked.
- if (_i2i_entry != NULL) return;
+ if (is_shared()) {
+ if (adapter() != NULL) return;
+ } else {
+ if (_i2i_entry != NULL) return;
- assert(_adapter == NULL, "init'd to NULL" );
+ assert(adapter() == NULL, "init'd to NULL" );
+ }
assert( _code == NULL, "nothing compiled yet" );
// Setup interpreter entrypoint
assert(this == h_method(), "wrong h_method()" );
- address entry = Interpreter::entry_for_method(h_method);
+ address entry;
+
+ if (this->is_shared()) {
+ entry = Interpreter::entry_for_cds_method(h_method);
+ } else {
+ entry = Interpreter::entry_for_method(h_method);
+ }
assert(entry != NULL, "interpreter entry must be non-null");
- // Sets both _i2i_entry and _from_interpreted_entry
- set_interpreter_entry(entry);
+ if (is_shared()) {
+ assert(entry == _i2i_entry && entry == _from_interpreted_entry,
+ "should be correctly set during dump time");
+ } else {
+ // Sets both _i2i_entry and _from_interpreted_entry
+ set_interpreter_entry(entry);
+ }
// Don't overwrite already registered native entries.
if (is_native() && !has_native_function()) {
@@ -975,8 +988,13 @@
THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(), "Out of space in CodeCache for adapters");
}
- mh->set_adapter_entry(adapter);
- mh->_from_compiled_entry = adapter->get_c2i_entry();
+ if (mh->is_shared()) {
+ assert(mh->adapter() == adapter, "must be");
+ assert(mh->_from_compiled_entry != NULL, "must be"); // FIXME, the instructions also not NULL
+ } else {
+ mh->set_adapter_entry(adapter);
+ mh->_from_compiled_entry = adapter->get_c2i_entry();
+ }
return adapter->get_c2i_entry();
}
@@ -992,6 +1010,14 @@
}
}
+volatile address Method::from_compiled_entry_no_trampoline() const {
+ nmethod *code = (nmethod *)OrderAccess::load_ptr_acquire(&_code);
+ if (code) {
+ return code->verified_entry_point();
+ } else {
+ return adapter()->get_c2i_entry();
+ }
+}
// The verified_code_entry() must be called when a invoke is resolved
// on this method.
@@ -1185,10 +1211,8 @@
m->set_signature_index(_imcp_invoke_signature);
assert(MethodHandles::is_signature_polymorphic_name(m->name()), "");
assert(m->signature() == signature, "");
-#ifdef CC_INTERP
ResultTypeFinder rtf(signature);
- m->set_result_index(rtf.type());
-#endif
+ m->constMethod()->set_result_type(rtf.type());
m->compute_size_of_parameters(THREAD);
m->init_intrinsic_id();
assert(m->is_method_handle_intrinsic(), "");
--- a/hotspot/src/share/vm/oops/method.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/method.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -69,9 +69,6 @@
AccessFlags _access_flags; // Access flags
int _vtable_index; // vtable index of this method (see VtableIndexFlag)
// note: can have vtables with >2**16 elements (because of inheritance)
-#ifdef CC_INTERP
- int _result_index; // C++ interpreter needs for converting results to/from stack
-#endif
u2 _intrinsic_id; // vmSymbols::intrinsic_id (0 == _none)
// Flags
@@ -93,8 +90,6 @@
#endif
// Entry point for calling both from and to the interpreter.
address _i2i_entry; // All-args-on-stack calling convention
- // Adapter blob (i2c/c2i) for this Method*. Set once when method is linked.
- AdapterHandlerEntry* _adapter;
// Entry point for calling from compiled code, to compiled code if it exists
// or else the interpreter.
volatile address _from_compiled_entry; // Cache of: _code ? _code->entry_point() : _adapter->c2i_entry()
@@ -137,6 +132,7 @@
static address make_adapters(methodHandle mh, TRAPS);
volatile address from_compiled_entry() const { return (address)OrderAccess::load_ptr_acquire(&_from_compiled_entry); }
+ volatile address from_compiled_entry_no_trampoline() const;
volatile address from_interpreted_entry() const{ return (address)OrderAccess::load_ptr_acquire(&_from_interpreted_entry); }
// access flag
@@ -172,11 +168,6 @@
return constMethod()->type_annotations();
}
-#ifdef CC_INTERP
- void set_result_index(BasicType type);
- int result_index() { return _result_index; }
-#endif
-
// Helper routine: get klass name + "." + method name + signature as
// C string, for the purpose of providing more useful NoSuchMethodErrors
// and fatal error handling. The string is allocated in resource
@@ -435,15 +426,23 @@
nmethod* volatile code() const { assert( check_code(), "" ); return (nmethod *)OrderAccess::load_ptr_acquire(&_code); }
void clear_code(); // Clear out any compiled code
static void set_code(methodHandle mh, nmethod* code);
- void set_adapter_entry(AdapterHandlerEntry* adapter) { _adapter = adapter; }
+ void set_adapter_entry(AdapterHandlerEntry* adapter) {
+ constMethod()->set_adapter_entry(adapter);
+ }
+ void update_adapter_trampoline(AdapterHandlerEntry* adapter) {
+ constMethod()->update_adapter_trampoline(adapter);
+ }
+
address get_i2c_entry();
address get_c2i_entry();
address get_c2i_unverified_entry();
- AdapterHandlerEntry* adapter() { return _adapter; }
+ AdapterHandlerEntry* adapter() const {
+ return constMethod()->adapter();
+ }
// setup entry points
void link_method(const methodHandle& method, TRAPS);
- // clear entry points. Used by sharing code
- void unlink_method();
+ // clear entry points. Used by sharing code during dump time
+ void unlink_method() NOT_CDS_RETURN;
// vtable index
enum VtableIndexFlag {
@@ -469,7 +468,15 @@
// interpreter entry
address interpreter_entry() const { return _i2i_entry; }
// Only used when first initialize so we can set _i2i_entry and _from_interpreted_entry
- void set_interpreter_entry(address entry) { _i2i_entry = entry; _from_interpreted_entry = entry; }
+ void set_interpreter_entry(address entry) {
+ assert(!is_shared(), "shared method's interpreter entry should not be changed at run time");
+ if (_i2i_entry != entry) {
+ _i2i_entry = entry;
+ }
+ if (_from_interpreted_entry != entry) {
+ _from_interpreted_entry = entry;
+ }
+ }
// native function (used for native methods only)
enum {
@@ -537,7 +544,6 @@
void compute_size_of_parameters(Thread *thread); // word size of parameters (receiver if any + arguments)
Symbol* klass_name() const; // returns the name of the method holder
BasicType result_type() const; // type of the method result
- int result_type_index() const; // type index of the method result
bool is_returning_oop() const { BasicType r = result_type(); return (r == T_OBJECT || r == T_ARRAY); }
bool is_returning_fp() const { BasicType r = result_type(); return (r == T_FLOAT || r == T_DOUBLE); }
@@ -638,9 +644,6 @@
// interpreter support
static ByteSize const_offset() { return byte_offset_of(Method, _constMethod ); }
static ByteSize access_flags_offset() { return byte_offset_of(Method, _access_flags ); }
-#ifdef CC_INTERP
- static ByteSize result_index_offset() { return byte_offset_of(Method, _result_index ); }
-#endif /* CC_INTERP */
static ByteSize from_compiled_offset() { return byte_offset_of(Method, _from_compiled_entry); }
static ByteSize code_offset() { return byte_offset_of(Method, _code); }
static ByteSize method_data_offset() {
--- a/hotspot/src/share/vm/oops/methodData.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/methodData.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1729,6 +1729,7 @@
}
void MethodData::clean_method_data(BoolObjectClosure* is_alive) {
+ ResourceMark rm;
for (ProfileData* data = first_data();
is_valid(data);
data = next_data(data)) {
@@ -1745,6 +1746,7 @@
}
void MethodData::clean_weak_method_links() {
+ ResourceMark rm;
for (ProfileData* data = first_data();
is_valid(data);
data = next_data(data)) {
@@ -1758,6 +1760,7 @@
#ifdef ASSERT
void MethodData::verify_clean_weak_method_links() {
+ ResourceMark rm;
for (ProfileData* data = first_data();
is_valid(data);
data = next_data(data)) {
--- a/hotspot/src/share/vm/oops/oop.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/oop.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -30,7 +30,6 @@
#include "memory/memRegion.hpp"
#include "oops/metadata.hpp"
#include "utilities/macros.hpp"
-#include "utilities/top.hpp"
// oopDesc is the top baseclass for objects classes. The {name}Desc classes describe
// the format of Java objects so the fields can be accessed from C++.
--- a/hotspot/src/share/vm/oops/oop.inline.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -443,7 +443,7 @@
void oopDesc::char_field_put(int offset, jchar contents) { *char_field_addr(offset) = (jint) contents; }
jboolean oopDesc::bool_field(int offset) const { return (jboolean) *bool_field_addr(offset); }
-void oopDesc::bool_field_put(int offset, jboolean contents) { *bool_field_addr(offset) = (jint) contents; }
+void oopDesc::bool_field_put(int offset, jboolean contents) { *bool_field_addr(offset) = (((jint) contents) & 1); }
jint oopDesc::int_field(int offset) const { return *int_field_addr(offset); }
void oopDesc::int_field_put(int offset, jint contents) { *int_field_addr(offset) = contents; }
@@ -483,7 +483,7 @@
void oopDesc::release_char_field_put(int offset, jchar contents) { OrderAccess::release_store(char_field_addr(offset), contents); }
jboolean oopDesc::bool_field_acquire(int offset) const { return OrderAccess::load_acquire(bool_field_addr(offset)); }
-void oopDesc::release_bool_field_put(int offset, jboolean contents) { OrderAccess::release_store(bool_field_addr(offset), contents); }
+void oopDesc::release_bool_field_put(int offset, jboolean contents) { OrderAccess::release_store(bool_field_addr(offset), (contents & 1)); }
jint oopDesc::int_field_acquire(int offset) const { return OrderAccess::load_acquire(int_field_addr(offset)); }
void oopDesc::release_int_field_put(int offset, jint contents) { OrderAccess::release_store(int_field_addr(offset), contents); }
--- a/hotspot/src/share/vm/oops/symbol.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/symbol.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -25,9 +25,10 @@
#ifndef SHARE_VM_OOPS_SYMBOL_HPP
#define SHARE_VM_OOPS_SYMBOL_HPP
-#include "utilities/utf8.hpp"
#include "memory/allocation.hpp"
#include "runtime/atomic.hpp"
+#include "utilities/exceptions.hpp"
+#include "utilities/utf8.hpp"
// A Symbol is a canonicalized string.
// All Symbols reside in global SymbolTable and are reference counted.
--- a/hotspot/src/share/vm/oops/typeArrayOop.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/typeArrayOop.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -96,7 +96,7 @@
void byte_at_put(int which, jbyte contents) { *byte_at_addr(which) = contents; }
jboolean bool_at(int which) const { return *bool_at_addr(which); }
- void bool_at_put(int which, jboolean contents) { *bool_at_addr(which) = contents; }
+ void bool_at_put(int which, jboolean contents) { *bool_at_addr(which) = (((jint)contents) & 1); }
jchar char_at(int which) const { return *char_at_addr(which); }
void char_at_put(int which, jchar contents) { *char_at_addr(which) = contents; }
--- a/hotspot/src/share/vm/opto/memnode.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/memnode.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -2389,7 +2389,7 @@
ctl != NULL, "raw memory operations should have control edge");
switch (bt) {
- case T_BOOLEAN:
+ case T_BOOLEAN: val = gvn.transform(new AndINode(val, gvn.intcon(0x1))); // Fall through to T_BYTE case
case T_BYTE: return new StoreBNode(ctl, mem, adr, adr_type, val, mo);
case T_INT: return new StoreINode(ctl, mem, adr, adr_type, val, mo);
case T_CHAR:
--- a/hotspot/src/share/vm/opto/parse1.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/parse1.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -730,6 +730,26 @@
#endif
}
+static Node* mask_int_value(Node* v, BasicType bt, PhaseGVN* gvn) {
+ switch (bt) {
+ case T_BYTE:
+ v = gvn->transform(new LShiftINode(v, gvn->intcon(24)));
+ v = gvn->transform(new RShiftINode(v, gvn->intcon(24)));
+ break;
+ case T_SHORT:
+ v = gvn->transform(new LShiftINode(v, gvn->intcon(16)));
+ v = gvn->transform(new RShiftINode(v, gvn->intcon(16)));
+ break;
+ case T_CHAR:
+ v = gvn->transform(new AndINode(v, gvn->intcon(0xFFFF)));
+ break;
+ case T_BOOLEAN:
+ v = gvn->transform(new AndINode(v, gvn->intcon(0x1)));
+ break;
+ }
+ return v;
+}
+
//-------------------------------build_exits----------------------------------
// Build normal and exceptional exit merge points.
void Parse::build_exits() {
@@ -754,6 +774,16 @@
// Add a return value to the exit state. (Do not push it yet.)
if (tf()->range()->cnt() > TypeFunc::Parms) {
const Type* ret_type = tf()->range()->field_at(TypeFunc::Parms);
+ if (ret_type->isa_int()) {
+ BasicType ret_bt = method()->return_type()->basic_type();
+ if (ret_bt == T_BOOLEAN ||
+ ret_bt == T_CHAR ||
+ ret_bt == T_BYTE ||
+ ret_bt == T_SHORT) {
+ ret_type = TypeInt::INT;
+ }
+ }
+
// Don't "bind" an unloaded return klass to the ret_phi. If the klass
// becomes loaded during the subsequent parsing, the loaded and unloaded
// types will not join when we transform and push in do_exits().
@@ -1014,6 +1044,10 @@
}
return;
}
+ if (ret_type->isa_int()) {
+ BasicType ret_bt = method()->return_type()->basic_type();
+ ret_phi = mask_int_value(ret_phi, ret_bt, &_gvn);
+ }
_exits.push_node(ret_type->basic_type(), ret_phi);
}
--- a/hotspot/src/share/vm/opto/parse2.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/parse2.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -64,11 +64,15 @@
//--------------------------------array_store----------------------------------
void Parse::array_store(BasicType elem_type) {
- Node* adr = array_addressing(elem_type, 1);
+ const Type* elem = Type::TOP;
+ Node* adr = array_addressing(elem_type, 1, &elem);
if (stopped()) return; // guaranteed null or range check
Node* val = pop();
dec_sp(2); // Pop array and index
const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(elem_type);
+ if (elem == TypeInt::BOOL) {
+ elem_type = T_BOOLEAN;
+ }
store_to_memory(control(), adr, val, elem_type, adr_type, StoreNode::release_if_reference(elem_type));
}
--- a/hotspot/src/share/vm/opto/type.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/type.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1820,13 +1820,15 @@
break;
case T_OBJECT:
case T_ARRAY:
+ case T_FLOAT:
+ case T_INT:
+ field_array[pos++] = get_const_type(type);
+ break;
case T_BOOLEAN:
case T_CHAR:
- case T_FLOAT:
case T_BYTE:
case T_SHORT:
- case T_INT:
- field_array[pos++] = get_const_type(type);
+ field_array[pos++] = TypeInt::INT;
break;
default:
ShouldNotReachHere();
--- a/hotspot/src/share/vm/precompiled/precompiled.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/precompiled/precompiled.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -242,7 +242,6 @@
# include "utilities/ostream.hpp"
# include "utilities/preserveException.hpp"
# include "utilities/sizes.hpp"
-# include "utilities/top.hpp"
# include "utilities/utf8.hpp"
#ifdef COMPILER2
# include "libadt/dict.hpp"
--- a/hotspot/src/share/vm/prims/jni.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/prims/jni.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -919,7 +919,14 @@
protected:
va_list _ap;
- inline void get_bool() { _arguments->push_int(va_arg(_ap, jint)); } // bool is coerced to int when using va_arg
+ inline void get_bool() {
+ // Normalize boolean arguments from native code by converting 1-255 to JNI_TRUE and
+ // 0 to JNI_FALSE. Boolean return values from native are normalized the same in
+ // TemplateInterpreterGenerator::generate_result_handler_for and
+ // SharedRuntime::generate_native_wrapper.
+ jboolean b = va_arg(_ap, jint);
+ _arguments->push_int((jint)(b == 0 ? JNI_FALSE : JNI_TRUE));
+ }
inline void get_char() { _arguments->push_int(va_arg(_ap, jint)); } // char is coerced to int when using va_arg
inline void get_short() { _arguments->push_int(va_arg(_ap, jint)); } // short is coerced to int when using va_arg
inline void get_byte() { _arguments->push_int(va_arg(_ap, jint)); } // byte is coerced to int when using va_arg
@@ -960,9 +967,17 @@
while ( 1 ) {
switch ( fingerprint & parameter_feature_mask ) {
case bool_parm:
+ get_bool();
+ break;
case char_parm:
+ get_char();
+ break;
case short_parm:
+ get_short();
+ break;
case byte_parm:
+ get_byte();
+ break;
case int_parm:
get_int();
break;
@@ -996,7 +1011,14 @@
protected:
const jvalue *_ap;
- inline void get_bool() { _arguments->push_int((jint)(_ap++)->z); }
+ inline void get_bool() {
+ // Normalize boolean arguments from native code by converting 1-255 to JNI_TRUE and
+ // 0 to JNI_FALSE. Boolean return values from native are normalized the same in
+ // TemplateInterpreterGenerator::generate_result_handler_for and
+ // SharedRuntime::generate_native_wrapper.
+ jboolean b = (_ap++)->z;
+ _arguments->push_int((jint)(b == 0 ? JNI_FALSE : JNI_TRUE));
+ }
inline void get_char() { _arguments->push_int((jint)(_ap++)->c); }
inline void get_short() { _arguments->push_int((jint)(_ap++)->s); }
inline void get_byte() { _arguments->push_int((jint)(_ap++)->b); }
@@ -2188,6 +2210,7 @@
field_value.unionType = value; \
o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \
} \
+ if (SigType == 'Z') { value = ((jboolean)value) & 1; } \
o->Fieldname##_field_put(offset, value); \
ReturnProbe; \
JNI_END
@@ -2387,6 +2410,7 @@
field_value.unionType = value; \
JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \
} \
+ if (SigType == 'Z') { value = ((jboolean)value) & 1; } \
id->holder()->java_mirror()-> Fieldname##_field_put (id->offset(), value); \
ReturnProbe;\
JNI_END
--- a/hotspot/src/share/vm/prims/jvm.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvm.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -79,7 +79,6 @@
#include "utilities/events.hpp"
#include "utilities/histogram.hpp"
#include "utilities/macros.hpp"
-#include "utilities/top.hpp"
#include "utilities/utf8.hpp"
#if INCLUDE_CDS
#include "classfile/sharedClassUtil.hpp"
@@ -534,7 +533,6 @@
JVM_ENTRY(jobject, JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mode,
jint skip_frames, jint frame_count, jint start_index,
- jobjectArray classes,
jobjectArray frames))
JVMWrapper("JVM_CallStackWalk");
JavaThread* jt = (JavaThread*) THREAD;
@@ -543,78 +541,51 @@
}
Handle stackStream_h(THREAD, JNIHandles::resolve_non_null(stackStream));
- objArrayOop ca = objArrayOop(JNIHandles::resolve_non_null(classes));
- objArrayHandle classes_array_h(THREAD, ca);
-
- // frames array is null when only getting caller reference
- objArrayOop fa = objArrayOop(JNIHandles::resolve(frames));
+
+ // frames array is a Class<?>[] array when only getting caller reference,
+ // and a StackFrameInfo[] array (or derivative) otherwise. It should never
+ // be null.
+ objArrayOop fa = objArrayOop(JNIHandles::resolve_non_null(frames));
objArrayHandle frames_array_h(THREAD, fa);
int limit = start_index + frame_count;
- if (classes_array_h->length() < limit) {
+ if (frames_array_h->length() < limit) {
THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "not enough space in buffers", NULL);
}
Handle result = StackWalk::walk(stackStream_h, mode, skip_frames, frame_count,
- start_index, classes_array_h,
- frames_array_h, CHECK_NULL);
+ start_index, frames_array_h, CHECK_NULL);
return JNIHandles::make_local(env, result());
JVM_END
JVM_ENTRY(jint, JVM_MoreStackWalk(JNIEnv *env, jobject stackStream, jlong mode, jlong anchor,
jint frame_count, jint start_index,
- jobjectArray classes,
jobjectArray frames))
JVMWrapper("JVM_MoreStackWalk");
JavaThread* jt = (JavaThread*) THREAD;
- objArrayOop ca = objArrayOop(JNIHandles::resolve_non_null(classes));
- objArrayHandle classes_array_h(THREAD, ca);
-
- // frames array is null when only getting caller reference
- objArrayOop fa = objArrayOop(JNIHandles::resolve(frames));
+
+ // frames array is a Class<?>[] array when only getting caller reference,
+ // and a StackFrameInfo[] array (or derivative) otherwise. It should never
+ // be null.
+ objArrayOop fa = objArrayOop(JNIHandles::resolve_non_null(frames));
objArrayHandle frames_array_h(THREAD, fa);
int limit = start_index+frame_count;
- if (classes_array_h->length() < limit) {
+ if (frames_array_h->length() < limit) {
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "not enough space in buffers");
}
Handle stackStream_h(THREAD, JNIHandles::resolve_non_null(stackStream));
return StackWalk::moreFrames(stackStream_h, mode, anchor, frame_count,
- start_index, classes_array_h,
- frames_array_h, THREAD);
+ start_index, frames_array_h, THREAD);
JVM_END
-JVM_ENTRY(void, JVM_FillStackFrames(JNIEnv *env, jclass stackStream,
- jint start_index,
- jobjectArray frames,
- jint from_index, jint to_index))
- JVMWrapper("JVM_FillStackFrames");
- if (TraceStackWalk) {
- tty->print("JVM_FillStackFrames() start_index=%d from_index=%d to_index=%d\n",
- start_index, from_index, to_index);
- }
-
- JavaThread* jt = (JavaThread*) THREAD;
-
- objArrayOop fa = objArrayOop(JNIHandles::resolve_non_null(frames));
- objArrayHandle frames_array_h(THREAD, fa);
-
- if (frames_array_h->length() < to_index) {
- THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "array length not matched");
- }
-
- for (int i = from_index; i < to_index; i++) {
- Handle stackFrame(THREAD, frames_array_h->obj_at(i));
- java_lang_StackFrameInfo::fill_methodInfo(stackFrame, CHECK);
- }
-JVM_END
-
-JVM_ENTRY(void, JVM_SetMethodInfo(JNIEnv *env, jobject frame))
- JVMWrapper("JVM_SetMethodInfo");
- Handle stackFrame(THREAD, JNIHandles::resolve(frame));
- java_lang_StackFrameInfo::fill_methodInfo(stackFrame, THREAD);
+JVM_ENTRY(void, JVM_ToStackTraceElement(JNIEnv *env, jobject frame, jobject stack))
+ JVMWrapper("JVM_ToStackTraceElement");
+ Handle stack_frame_info(THREAD, JNIHandles::resolve_non_null(frame));
+ Handle stack_trace_element(THREAD, JNIHandles::resolve_non_null(stack));
+ java_lang_StackFrameInfo::to_stack_trace_element(stack_frame_info, stack_trace_element, THREAD);
JVM_END
// java.lang.Object ///////////////////////////////////////////////
@@ -1818,9 +1789,6 @@
// Ensure class is linked
k->link_class(CHECK_NULL);
- // 4496456 We need to filter out java.lang.Throwable.backtrace
- bool skip_backtrace = false;
-
// Allocate result
int num_fields;
@@ -1831,11 +1799,6 @@
}
} else {
num_fields = k->java_fields_count();
-
- if (k() == SystemDictionary::Throwable_klass()) {
- num_fields--;
- skip_backtrace = true;
- }
}
objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), num_fields, CHECK_NULL);
@@ -1844,12 +1807,6 @@
int out_idx = 0;
fieldDescriptor fd;
for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
- if (skip_backtrace) {
- // 4496456 skip java.lang.Throwable.backtrace
- int offset = fs.offset();
- if (offset == java_lang_Throwable::get_backtrace_offset()) continue;
- }
-
if (!publicOnly || fs.access_flags().is_public()) {
fd.reinitialize(k(), fs.index());
oop field = Reflection::new_field(&fd, CHECK_NULL);
--- a/hotspot/src/share/vm/prims/jvm.h Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvm.h Thu Apr 28 23:08:17 2016 -0700
@@ -209,7 +209,6 @@
*/
enum {
JVM_STACKWALK_FILL_CLASS_REFS_ONLY = 0x2,
- JVM_STACKWALK_FILTER_FILL_IN_STACK_TRACE = 0x10,
JVM_STACKWALK_SHOW_HIDDEN_FRAMES = 0x20,
JVM_STACKWALK_FILL_LIVE_STACK_FRAMES = 0x100
};
@@ -217,23 +216,15 @@
JNIEXPORT jobject JNICALL
JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mode,
jint skip_frames, jint frame_count, jint start_index,
- jobjectArray classes,
jobjectArray frames);
JNIEXPORT jint JNICALL
JVM_MoreStackWalk(JNIEnv *env, jobject stackStream, jlong mode, jlong anchor,
jint frame_count, jint start_index,
- jobjectArray classes,
jobjectArray frames);
JNIEXPORT void JNICALL
-JVM_FillStackFrames(JNIEnv* env, jclass cls,
- jint start_index,
- jobjectArray frames,
- jint from_index, jint toIndex);
-
-JNIEXPORT void JNICALL
-JVM_SetMethodInfo(JNIEnv* env, jobject frame);
+JVM_ToStackTraceElement(JNIEnv* env, jobject frame, jobject stackElement);
/*
* java.lang.Thread
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1354,7 +1354,7 @@
ResultTypeFinder rtf(signature);
TosState fr_tos = as_TosState(rtf.type());
if (fr_tos != tos) {
- if (tos != itos || (fr_tos != btos && fr_tos != ctos && fr_tos != stos)) {
+ if (tos != itos || (fr_tos != btos && fr_tos != ztos && fr_tos != ctos && fr_tos != stos)) {
return JVMTI_ERROR_TYPE_MISMATCH;
}
}
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1702,7 +1702,7 @@
address location, KlassHandle field_klass, Handle object, jfieldID field,
char sig_type, jvalue *value) {
- if (sig_type == 'I' || sig_type == 'Z' || sig_type == 'C' || sig_type == 'S') {
+ if (sig_type == 'I' || sig_type == 'Z' || sig_type == 'B' || sig_type == 'C' || sig_type == 'S') {
// 'I' instructions are used for byte, char, short and int.
// determine which it really is, and convert
fieldDescriptor fd;
@@ -2260,7 +2260,7 @@
if (env->is_enabled(JVMTI_EVENT_VM_OBJECT_ALLOC)) {
EVT_TRACE(JVMTI_EVENT_VM_OBJECT_ALLOC, ("JVMTI [%s] Evt vmobject alloc sent %s",
JvmtiTrace::safe_get_thread_name(thread),
- object==NULL? "NULL" : java_lang_Class::as_Klass(object)->external_name()));
+ object==NULL? "NULL" : object->klass()->external_name()));
JvmtiVMObjectAllocEventMark jem(thread, h());
JvmtiJavaThreadEventTransition jet(thread);
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1443,8 +1443,9 @@
return JVMTI_ERROR_INTERNAL;
}
- // Update the version number of the constant pool
+ // Update the version number of the constant pools (may keep scratch_cp)
merge_cp->increment_and_save_version(old_cp->version());
+ scratch_cp->increment_and_save_version(old_cp->version());
ResourceMark rm(THREAD);
_index_map_count = 0;
@@ -3911,6 +3912,11 @@
method->set_constants(scratch_class->constants());
}
+ // NOTE: this doesn't work because you can redefine the same class in two
+ // threads, each getting their own constant pool data appended to the
+ // original constant pool. In order for the new methods to work when they
+ // become old methods, they need to keep their updated copy of the constant pool.
+
{
// walk all previous versions of the klass
InstanceKlass *ik = (InstanceKlass *)the_class();
--- a/hotspot/src/share/vm/prims/nativeLookup.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/prims/nativeLookup.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -25,8 +25,8 @@
#ifndef SHARE_VM_PRIMS_NATIVELOOKUP_HPP
#define SHARE_VM_PRIMS_NATIVELOOKUP_HPP
+#include "memory/allocation.hpp"
#include "runtime/handles.hpp"
-#include "utilities/top.hpp"
// NativeLookup provides an interface for finding DLL entry points for
// Java native functions.
--- a/hotspot/src/share/vm/prims/stackwalk.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/prims/stackwalk.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -37,22 +37,22 @@
#include "utilities/globalDefinitions.hpp"
// setup and cleanup actions
-void StackWalkAnchor::setup_magic_on_entry(objArrayHandle classes_array) {
- classes_array->obj_at_put(magic_pos, _thread->threadObj());
+void StackWalkAnchor::setup_magic_on_entry(objArrayHandle frames_array) {
+ frames_array->obj_at_put(magic_pos, _thread->threadObj());
_anchor = address_value();
- assert(check_magic(classes_array), "invalid magic");
+ assert(check_magic(frames_array), "invalid magic");
}
-bool StackWalkAnchor::check_magic(objArrayHandle classes_array) {
- oop m1 = classes_array->obj_at(magic_pos);
+bool StackWalkAnchor::check_magic(objArrayHandle frames_array) {
+ oop m1 = frames_array->obj_at(magic_pos);
jlong m2 = _anchor;
if (m1 == _thread->threadObj() && m2 == address_value()) return true;
return false;
}
-bool StackWalkAnchor::cleanup_magic_on_exit(objArrayHandle classes_array) {
- bool ok = check_magic(classes_array);
- classes_array->obj_at_put(magic_pos, NULL);
+bool StackWalkAnchor::cleanup_magic_on_exit(objArrayHandle frames_array) {
+ bool ok = check_magic(frames_array);
+ frames_array->obj_at_put(magic_pos, NULL);
_anchor = 0L;
return ok;
}
@@ -62,18 +62,18 @@
// Parameters:
// thread Current Java thread.
// magic Magic value used for each stack walking
-// classes_array User-supplied buffers. The 0th element is reserved
+// frames_array User-supplied buffers. The 0th element is reserved
// to this StackWalkAnchor to use
//
StackWalkAnchor* StackWalkAnchor::from_current(JavaThread* thread, jlong magic,
- objArrayHandle classes_array)
+ objArrayHandle frames_array)
{
assert(thread != NULL && thread->is_Java_thread(), "");
- oop m1 = classes_array->obj_at(magic_pos);
+ oop m1 = frames_array->obj_at(magic_pos);
if (m1 != thread->threadObj()) return NULL;
if (magic == 0L) return NULL;
StackWalkAnchor* anchor = (StackWalkAnchor*) (intptr_t) magic;
- if (!anchor->is_valid_in(thread, classes_array)) return NULL;
+ if (!anchor->is_valid_in(thread, frames_array)) return NULL;
return anchor;
}
@@ -88,24 +88,24 @@
// vfst vFrameStream.
// max_nframes Maximum number of frames to be filled.
// start_index Start index to the user-supplied buffers.
-// classes_array Buffer to store classes in, starting at start_index.
-// frames_array Buffer to store StackFrame in, starting at start_index.
-// NULL if not used.
+// frames_array Buffer to store Class or StackFrame in, starting at start_index.
+// frames array is a Class<?>[] array when only getting caller
+// reference, and a StackFrameInfo[] array (or derivative)
+// otherwise. It should never be null.
// end_index End index to the user-supplied buffers with unpacked frames.
//
// Returns the number of frames whose information was transferred into the buffers.
//
int StackWalk::fill_in_frames(jlong mode, vframeStream& vfst,
int max_nframes, int start_index,
- objArrayHandle classes_array,
objArrayHandle frames_array,
int& end_index, TRAPS) {
if (TraceStackWalk) {
tty->print_cr("fill_in_frames limit=%d start=%d frames length=%d",
- max_nframes, start_index, classes_array->length());
+ max_nframes, start_index, frames_array->length());
}
assert(max_nframes > 0, "invalid max_nframes");
- assert(start_index + max_nframes <= classes_array->length(), "oob");
+ assert(start_index + max_nframes <= frames_array->length(), "oob");
int frames_decoded = 0;
for (; !vfst.at_end(); vfst.next()) {
@@ -129,14 +129,18 @@
tty->print_cr(" bci=%d", bci);
}
- classes_array->obj_at_put(index, method->method_holder()->java_mirror());
// fill in StackFrameInfo and initialize MemberName
if (live_frame_info(mode)) {
+ assert (use_frames_array(mode), "Bad mode for get live frame");
Handle stackFrame(frames_array->obj_at(index));
fill_live_stackframe(stackFrame, method, bci, vfst.java_frame(), CHECK_0);
} else if (need_method_info(mode)) {
+ assert (use_frames_array(mode), "Bad mode for get stack frame");
Handle stackFrame(frames_array->obj_at(index));
fill_stackframe(stackFrame, method, bci);
+ } else {
+ assert (use_frames_array(mode) == false, "Bad mode for get caller class");
+ frames_array->obj_at_put(index, method->method_holder()->java_mirror());
}
if (++frames_decoded >= max_nframes) break;
}
@@ -279,15 +283,15 @@
// skip_frames Number of frames to be skipped.
// frame_count Number of frames to be traversed.
// start_index Start index to the user-supplied buffers.
-// classes_array Buffer to store classes in, starting at start_index.
// frames_array Buffer to store StackFrame in, starting at start_index.
-// NULL if not used.
+// frames array is a Class<?>[] array when only getting caller
+// reference, and a StackFrameInfo[] array (or derivative)
+// otherwise. It should never be null.
//
// Returns Object returned from AbstractStackWalker::doStackWalk call.
//
oop StackWalk::walk(Handle stackStream, jlong mode,
int skip_frames, int frame_count, int start_index,
- objArrayHandle classes_array,
objArrayHandle frames_array,
TRAPS) {
JavaThread* jt = (JavaThread*)THREAD;
@@ -296,10 +300,8 @@
mode, skip_frames, frame_count);
}
- if (need_method_info(mode)) {
- if (frames_array.is_null()) {
- THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL);
- }
+ if (frames_array.is_null()) {
+ THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL);
}
Klass* stackWalker_klass = SystemDictionary::StackWalker_klass();
@@ -313,48 +315,17 @@
vframeStream& vfst = anchor.vframe_stream();
{
- // Skip all methods from AbstractStackWalker and StackWalk (enclosing method)
- if (!fill_in_stacktrace(mode)) {
- while (!vfst.at_end()) {
- InstanceKlass* ik = vfst.method()->method_holder();
- if (ik != stackWalker_klass &&
- ik != abstractStackWalker_klass && ik->super() != abstractStackWalker_klass) {
- break;
- }
-
- if (TraceStackWalk) {
- tty->print(" skip "); vfst.method()->print_short_name(); tty->print("\n");
- }
- vfst.next();
+ while (!vfst.at_end()) {
+ InstanceKlass* ik = vfst.method()->method_holder();
+ if (ik != stackWalker_klass &&
+ ik != abstractStackWalker_klass && ik->super() != abstractStackWalker_klass) {
+ break;
}
- }
- // For exceptions, skip Throwable::fillInStackTrace and <init> methods
- // of the exception class and superclasses
- if (fill_in_stacktrace(mode)) {
- bool skip_to_fillInStackTrace = false;
- bool skip_throwableInit_check = false;
- while (!vfst.at_end() && !skip_throwableInit_check) {
- InstanceKlass* ik = vfst.method()->method_holder();
- Method* method = vfst.method();
- if (!skip_to_fillInStackTrace) {
- if (ik == SystemDictionary::Throwable_klass() &&
- method->name() == vmSymbols::fillInStackTrace_name()) {
- // this frame will be skipped
- skip_to_fillInStackTrace = true;
- }
- } else if (!(ik->is_subclass_of(SystemDictionary::Throwable_klass()) &&
- method->name() == vmSymbols::object_initializer_name())) {
- // there are none or we've seen them all - either way stop checking
- skip_throwableInit_check = true;
- break;
- }
-
- if (TraceStackWalk) {
- tty->print("stack walk: skip "); vfst.method()->print_short_name(); tty->print("\n");
- }
- vfst.next();
+ if (TraceStackWalk) {
+ tty->print(" skip "); vfst.method()->print_short_name(); tty->print("\n");
}
+ vfst.next();
}
// stack frame has been traversed individually and resume stack walk
@@ -372,7 +343,7 @@
int end_index = start_index;
int numFrames = 0;
if (!vfst.at_end()) {
- numFrames = fill_in_frames(mode, vfst, frame_count, start_index, classes_array,
+ numFrames = fill_in_frames(mode, vfst, frame_count, start_index,
frames_array, end_index, CHECK_NULL);
if (numFrames < 1) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "stack walk: decode failed", NULL);
@@ -392,12 +363,12 @@
args.push_int(end_index);
// Link the thread and vframe stream into the callee-visible object
- anchor.setup_magic_on_entry(classes_array);
+ anchor.setup_magic_on_entry(frames_array);
JavaCalls::call(&result, m_doStackWalk, &args, THREAD);
// Do this before anything else happens, to disable any lingering stream objects
- bool ok = anchor.cleanup_magic_on_exit(classes_array);
+ bool ok = anchor.cleanup_magic_on_exit(frames_array);
// Throw pending exception if we must
(void) (CHECK_NULL);
@@ -419,31 +390,28 @@
// magic Must be valid value to continue the stack walk
// frame_count Number of frames to be decoded.
// start_index Start index to the user-supplied buffers.
-// classes_array Buffer to store classes in, starting at start_index.
// frames_array Buffer to store StackFrame in, starting at start_index.
-// NULL if not used.
//
// Returns the end index of frame filled in the buffer.
//
jint StackWalk::moreFrames(Handle stackStream, jlong mode, jlong magic,
int frame_count, int start_index,
- objArrayHandle classes_array,
objArrayHandle frames_array,
TRAPS)
{
JavaThread* jt = (JavaThread*)THREAD;
- StackWalkAnchor* existing_anchor = StackWalkAnchor::from_current(jt, magic, classes_array);
+ StackWalkAnchor* existing_anchor = StackWalkAnchor::from_current(jt, magic, frames_array);
if (existing_anchor == NULL) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: corrupted buffers", 0L);
}
- if ((need_method_info(mode) || live_frame_info(mode)) && frames_array.is_null()) {
+ if (frames_array.is_null()) {
THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", 0L);
}
if (TraceStackWalk) {
tty->print_cr("StackWalk::moreFrames frame_count %d existing_anchor " PTR_FORMAT " start %d frames %d",
- frame_count, p2i(existing_anchor), start_index, classes_array->length());
+ frame_count, p2i(existing_anchor), start_index, frames_array->length());
}
int end_index = start_index;
if (frame_count <= 0) {
@@ -451,14 +419,14 @@
}
int count = frame_count + start_index;
- assert (classes_array->length() >= count, "not enough space in buffers");
+ assert (frames_array->length() >= count, "not enough space in buffers");
StackWalkAnchor& anchor = (*existing_anchor);
vframeStream& vfst = anchor.vframe_stream();
if (!vfst.at_end()) {
vfst.next(); // this was the last frame decoded in the previous batch
if (!vfst.at_end()) {
- int n = fill_in_frames(mode, vfst, frame_count, start_index, classes_array,
+ int n = fill_in_frames(mode, vfst, frame_count, start_index,
frames_array, end_index, CHECK_0);
if (n < 1) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: later decode failed", 0L);
--- a/hotspot/src/share/vm/prims/stackwalk.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/prims/stackwalk.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -45,12 +45,12 @@
vframeStream& vframe_stream() { return _vfst; }
JavaThread* thread() { return _thread; }
- void setup_magic_on_entry(objArrayHandle classes_array);
- bool check_magic(objArrayHandle classes_array);
- bool cleanup_magic_on_exit(objArrayHandle classes_array);
+ void setup_magic_on_entry(objArrayHandle frames_array);
+ bool check_magic(objArrayHandle frames_array);
+ bool cleanup_magic_on_exit(objArrayHandle frames_array);
- bool is_valid_in(Thread* thread, objArrayHandle classes_array) {
- return (_thread == thread && check_magic(classes_array));
+ bool is_valid_in(Thread* thread, objArrayHandle frames_array) {
+ return (_thread == thread && check_magic(frames_array));
}
jlong address_value() {
@@ -64,7 +64,6 @@
private:
static int fill_in_frames(jlong mode, vframeStream& vfst,
int max_nframes, int start_index,
- objArrayHandle classes_array,
objArrayHandle frames_array,
int& end_index, TRAPS);
@@ -82,20 +81,18 @@
static inline bool live_frame_info(int mode) {
return (mode & JVM_STACKWALK_FILL_LIVE_STACK_FRAMES) != 0;
}
- static inline bool fill_in_stacktrace(int mode) {
- return (mode & JVM_STACKWALK_FILTER_FILL_IN_STACK_TRACE) != 0;
- }
public:
+ static inline bool use_frames_array(int mode) {
+ return (mode & JVM_STACKWALK_FILL_CLASS_REFS_ONLY) == 0;
+ }
static oop walk(Handle stackStream, jlong mode,
int skip_frames, int frame_count, int start_index,
- objArrayHandle classes_array,
objArrayHandle frames_array,
TRAPS);
static jint moreFrames(Handle stackStream, jlong mode, jlong magic,
int frame_count, int start_index,
- objArrayHandle classes_array,
objArrayHandle frames_array,
TRAPS);
};
--- a/hotspot/src/share/vm/prims/unsafe.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/prims/unsafe.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -133,13 +133,22 @@
///// Data in the Java heap.
+#define truncate_jboolean(x) ((x) & 1)
+#define truncate_jbyte(x) (x)
+#define truncate_jshort(x) (x)
+#define truncate_jchar(x) (x)
+#define truncate_jint(x) (x)
+#define truncate_jlong(x) (x)
+#define truncate_jfloat(x) (x)
+#define truncate_jdouble(x) (x)
+
#define GET_FIELD(obj, offset, type_name, v) \
oop p = JNIHandles::resolve(obj); \
type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset)
#define SET_FIELD(obj, offset, type_name, x) \
oop p = JNIHandles::resolve(obj); \
- *(type_name*)index_oop_from_field_offset_long(p, offset) = x
+ *(type_name*)index_oop_from_field_offset_long(p, offset) = truncate_##type_name(x)
#define GET_FIELD_VOLATILE(obj, offset, type_name, v) \
oop p = JNIHandles::resolve(obj); \
@@ -150,7 +159,7 @@
#define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
oop p = JNIHandles::resolve(obj); \
- OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), x);
+ OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), truncate_##type_name(x));
// Get/SetObject must be special-cased, since it works with handles.
--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -407,7 +407,9 @@
{ NULL, NULL}
};
+// NOTE: A compatibility request will be necessary for each alias to be removed.
static AliasedLoggingFlag const aliased_logging_flags[] = {
+ { "PrintCompressedOopsMode", LogLevel::Info, true, LOG_TAGS(gc, heap, coops) },
{ "TraceBiasedLocking", LogLevel::Info, true, LOG_TAGS(biasedlocking) },
{ "TraceClassLoading", LogLevel::Info, true, LOG_TAGS(classload) },
{ "TraceClassLoadingPreorder", LogLevel::Debug, true, LOG_TAGS(classload, preorder) },
@@ -696,7 +698,7 @@
assert(total_len > 0, "empty sysclasspath not allowed");
// Copy the _items to a single string.
- char* cp = NEW_C_HEAP_ARRAY(char, total_len, mtInternal);
+ char* cp = NEW_C_HEAP_ARRAY(char, total_len, mtArguments);
char* cp_tmp = cp;
for (i = 0; i < _bcp_nitems; ++i) {
if (_items[i] != NULL) {
@@ -717,7 +719,7 @@
assert(str != NULL, "just checking");
if (path == NULL) {
size_t len = strlen(str) + 1;
- cp = NEW_C_HEAP_ARRAY(char, len, mtInternal);
+ cp = NEW_C_HEAP_ARRAY(char, len, mtArguments);
memcpy(cp, str, len); // copy the trailing null
} else {
const char separator = *os::path_separator();
@@ -726,7 +728,7 @@
size_t len = old_len + str_len + 2;
if (prepend) {
- cp = NEW_C_HEAP_ARRAY(char, len, mtInternal);
+ cp = NEW_C_HEAP_ARRAY(char, len, mtArguments);
char* cp_tmp = cp;
memcpy(cp_tmp, str, str_len);
cp_tmp += str_len;
@@ -734,7 +736,7 @@
memcpy(++cp_tmp, path, old_len + 1); // copy the trailing null
FREE_C_HEAP_ARRAY(char, path);
} else {
- cp = REALLOC_C_HEAP_ARRAY(char, path, len, mtInternal);
+ cp = REALLOC_C_HEAP_ARRAY(char, path, len, mtArguments);
char* cp_tmp = cp + old_len;
*cp_tmp = separator;
memcpy(++cp_tmp, str, str_len + 1); // copy the trailing null
@@ -756,7 +758,7 @@
/* Scan the directory for jars/zips, appending them to path. */
struct dirent *entry;
- char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory), mtInternal);
+ char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory), mtArguments);
while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL) {
const char* name = entry->d_name;
const char* ext = name + strlen(name) - 4;
@@ -764,7 +766,7 @@
(os::file_name_strcmp(ext, ".jar") == 0 ||
os::file_name_strcmp(ext, ".zip") == 0);
if (isJarOrZip) {
- char* jarpath = NEW_C_HEAP_ARRAY(char, directory_len + 2 + strlen(name), mtInternal);
+ char* jarpath = NEW_C_HEAP_ARRAY(char, directory_len + 2 + strlen(name), mtArguments);
sprintf(jarpath, "%s%s%s", directory, dir_sep, name);
path = add_to_path(path, jarpath, false);
FREE_C_HEAP_ARRAY(char, jarpath);
@@ -941,7 +943,7 @@
} else if (new_len == 0) {
value = old_value;
} else {
- char* buf = NEW_C_HEAP_ARRAY(char, old_len + 1 + new_len + 1, mtInternal);
+ char* buf = NEW_C_HEAP_ARRAY(char, old_len + 1 + new_len + 1, mtArguments);
// each new setting adds another LINE to the switch:
sprintf(buf, "%s\n%s", old_value, new_value);
value = buf;
@@ -1132,9 +1134,9 @@
// expand the array and add arg to the last element
if (*bldarray == NULL) {
- *bldarray = NEW_C_HEAP_ARRAY(char*, new_count, mtInternal);
+ *bldarray = NEW_C_HEAP_ARRAY(char*, new_count, mtArguments);
} else {
- *bldarray = REALLOC_C_HEAP_ARRAY(char*, *bldarray, new_count, mtInternal);
+ *bldarray = REALLOC_C_HEAP_ARRAY(char*, *bldarray, new_count, mtArguments);
}
(*bldarray)[*count] = os::strdup_check_oom(arg);
*count = new_count;
@@ -1398,7 +1400,7 @@
// property have a value, thus extract it and save to the
// allocated string
size_t key_len = eq - prop;
- char* tmp_key = AllocateHeap(key_len + 1, mtInternal);
+ char* tmp_key = AllocateHeap(key_len + 1, mtArguments);
strncpy(tmp_key, prop, key_len);
tmp_key[key_len] = '\0';
@@ -1420,7 +1422,7 @@
} else {
if (strcmp(key, "sun.java.command") == 0) {
char *old_java_command = _java_command;
- _java_command = os::strdup_check_oom(value, mtInternal);
+ _java_command = os::strdup_check_oom(value, mtArguments);
if (old_java_command != NULL) {
os::free(old_java_command);
}
@@ -1428,7 +1430,7 @@
const char* old_java_vendor_url_bug = _java_vendor_url_bug;
// save it in _java_vendor_url_bug, so JVM fatal error handler can access
// its value without going through the property list or making a Java call.
- _java_vendor_url_bug = os::strdup_check_oom(value, mtInternal);
+ _java_vendor_url_bug = os::strdup_check_oom(value, mtArguments);
if (old_java_vendor_url_bug != DEFAULT_VENDOR_URL_BUG) {
assert(old_java_vendor_url_bug != NULL, "_java_vendor_url_bug is NULL");
os::free((void *)old_java_vendor_url_bug);
@@ -1456,7 +1458,7 @@
if (old_value != NULL) {
buf_len += strlen(old_value) + 1;
}
- char* new_value = AllocateHeap(buf_len, mtInternal);
+ char* new_value = AllocateHeap(buf_len, mtArguments);
if (new_value == NULL) {
return false;
}
@@ -2093,8 +2095,8 @@
}
#if INCLUDE_ALL_GCS
- if (G1ConcRefinementThreads == 0) {
- FLAG_SET_DEFAULT(G1ConcRefinementThreads, ParallelGCThreads);
+ if (FLAG_IS_DEFAULT(G1ConcRefinementThreads)) {
+ FLAG_SET_ERGO(uint, G1ConcRefinementThreads, ParallelGCThreads);
}
#endif
@@ -2184,15 +2186,11 @@
if (!FLAG_IS_DEFAULT(HeapBaseMinAddress)) {
if (HeapBaseMinAddress < DefaultHeapBaseMinAddress) {
// matches compressed oops printing flags
- if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) {
- jio_fprintf(defaultStream::error_stream(),
- "HeapBaseMinAddress must be at least " SIZE_FORMAT
- " (" SIZE_FORMAT "G) which is greater than value given "
- SIZE_FORMAT "\n",
- DefaultHeapBaseMinAddress,
- DefaultHeapBaseMinAddress/G,
- HeapBaseMinAddress);
- }
+ log_debug(gc, heap, coops)("HeapBaseMinAddress must be at least " SIZE_FORMAT
+ " (" SIZE_FORMAT "G) which is greater than value given " SIZE_FORMAT,
+ DefaultHeapBaseMinAddress,
+ DefaultHeapBaseMinAddress/G,
+ HeapBaseMinAddress);
FLAG_SET_ERGO(size_t, HeapBaseMinAddress, DefaultHeapBaseMinAddress);
}
}
@@ -2854,13 +2852,13 @@
if (tail != NULL) {
const char* pos = strchr(tail, ':');
size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
- char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1, mtInternal), tail, len);
+ char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
name[len] = '\0';
char *options = NULL;
if(pos != NULL) {
size_t len2 = strlen(pos+1) + 1; // options start after ':'. Final zero must be copied.
- options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2, mtInternal), pos+1, len2);
+ options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2, mtArguments), pos+1, len2);
}
#if !INCLUDE_JVMTI
if (strcmp(name, "jdwp") == 0) {
@@ -2877,12 +2875,12 @@
if(tail != NULL) {
const char* pos = strchr(tail, '=');
size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
- char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1, mtInternal), tail, len);
+ char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
name[len] = '\0';
char *options = NULL;
if(pos != NULL) {
- options = os::strdup_check_oom(pos + 1, mtInternal);
+ options = os::strdup_check_oom(pos + 1, mtArguments);
}
#if !INCLUDE_JVMTI
if (valid_jdwp_agent(name, is_absolute_path)) {
@@ -2901,7 +2899,7 @@
return JNI_ERR;
#else
if (tail != NULL) {
- char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1, mtInternal), tail);
+ char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1, mtArguments), tail);
add_init_agent("instrument", options, false);
// java agents need module java.instrument. Also -addmods ALL-SYSTEM because
// the java agent is in the unmamed module of the application class loader
@@ -3203,7 +3201,7 @@
size_t len = strlen(patch_dirs[x]);
if (len != 0) { // Ignore empty strings.
len += 11; // file_sep + "java.base" + null terminator.
- char* dir = NEW_C_HEAP_ARRAY(char, len, mtInternal);
+ char* dir = NEW_C_HEAP_ARRAY(char, len, mtArguments);
jio_snprintf(dir, len, "%s%cjava.base", patch_dirs[x], file_sep);
// See if Xpatch module path exists.
@@ -3509,7 +3507,7 @@
src ++;
}
- char* copy = os::strdup_check_oom(src, mtInternal);
+ char* copy = os::strdup_check_oom(src, mtArguments);
// trim all trailing empty paths
for (char* tail = copy + strlen(copy) - 1; tail >= copy && *tail == separator; tail--) {
@@ -3533,7 +3531,7 @@
if (dir == NULL) return false;
struct dirent *entry;
- char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory), mtInternal);
+ char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory), mtArguments);
bool hasJarFile = false;
while (!hasJarFile && (entry = os::readdir(dir, (dirent *) dbuf)) != NULL) {
const char* name = entry->d_name;
@@ -3559,7 +3557,7 @@
}
path = end;
} else {
- char* dirpath = NEW_C_HEAP_ARRAY(char, tmp_end - path + 1, mtInternal);
+ char* dirpath = NEW_C_HEAP_ARRAY(char, tmp_end - path + 1, mtArguments);
memcpy(dirpath, path, tmp_end - path);
dirpath[tmp_end - path] = '\0';
if (has_jar_files(dirpath)) {
@@ -3731,7 +3729,7 @@
jint set_args(GrowableArray<JavaVMOption>* options) {
_is_set = true;
JavaVMOption* options_arr = NEW_C_HEAP_ARRAY_RETURN_NULL(
- JavaVMOption, options->length(), mtInternal);
+ JavaVMOption, options->length(), mtArguments);
if (options_arr == NULL) {
return JNI_ENOMEM;
}
@@ -3786,7 +3784,7 @@
assert(vm_options_file_pos != -1, "vm_options_file_pos should be set");
int length = args->nOptions + args_to_insert->nOptions - 1;
- GrowableArray<JavaVMOption> *options = new (ResourceObj::C_HEAP, mtInternal)
+ GrowableArray<JavaVMOption> *options = new (ResourceObj::C_HEAP, mtArguments)
GrowableArray<JavaVMOption>(length, true); // Construct new option array
for (int i = 0; i < args->nOptions; i++) {
if (i == vm_options_file_pos) {
@@ -3863,7 +3861,7 @@
// '+ 1' for NULL termination even with max bytes
size_t bytes_alloc = stbuf.st_size + 1;
- char *buf = NEW_C_HEAP_ARRAY_RETURN_NULL(char, bytes_alloc, mtInternal);
+ char *buf = NEW_C_HEAP_ARRAY_RETURN_NULL(char, bytes_alloc, mtArguments);
if (NULL == buf) {
jio_fprintf(defaultStream::error_stream(),
"Could not allocate read buffer for options file parse\n");
@@ -3900,7 +3898,7 @@
}
jint Arguments::parse_options_buffer(const char* name, char* buffer, const size_t buf_len, ScopedVMInitArgs* vm_args) {
- GrowableArray<JavaVMOption> *options = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JavaVMOption>(2, true); // Construct option array
+ GrowableArray<JavaVMOption> *options = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<JavaVMOption>(2, true); // Construct option array
// some pointers to help with parsing
char *buffer_end = buffer + buf_len;
@@ -4004,13 +4002,13 @@
size_t jvm_path_len = strlen(jvm_path);
size_t file_sep_len = strlen(os::file_separator());
const size_t len = jvm_path_len + file_sep_len + 20;
- shared_archive_path = NEW_C_HEAP_ARRAY(char, len, mtInternal);
+ shared_archive_path = NEW_C_HEAP_ARRAY(char, len, mtArguments);
if (shared_archive_path != NULL) {
jio_snprintf(shared_archive_path, len, "%s%sclasses.jsa",
jvm_path, os::file_separator());
}
} else {
- shared_archive_path = os::strdup_check_oom(SharedArchiveFile, mtInternal);
+ shared_archive_path = os::strdup_check_oom(SharedArchiveFile, mtArguments);
}
return shared_archive_path;
}
--- a/hotspot/src/share/vm/runtime/arguments.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -31,7 +31,6 @@
#include "runtime/os.hpp"
#include "runtime/perfData.hpp"
#include "utilities/debug.hpp"
-#include "utilities/top.hpp"
// Arguments parses the command line and recognizes options
@@ -48,7 +47,7 @@
// PathString is used as the underlying value container for a
// SystemProperty and for the string that represents the system
// boot class path, Arguments::_system_boot_class_path.
-class PathString : public CHeapObj<mtInternal> {
+class PathString : public CHeapObj<mtArguments> {
protected:
char* _value;
public:
@@ -58,7 +57,7 @@
if (_value != NULL) {
FreeHeap(_value);
}
- _value = AllocateHeap(strlen(value)+1, mtInternal);
+ _value = AllocateHeap(strlen(value)+1, mtArguments);
assert(_value != NULL, "Unable to allocate space for new path value");
if (_value != NULL) {
strcpy(_value, value);
@@ -77,7 +76,7 @@
if (_value != NULL) {
len += strlen(_value);
}
- sp = AllocateHeap(len+2, mtInternal);
+ sp = AllocateHeap(len+2, mtArguments);
assert(sp != NULL, "Unable to allocate space for new append path value");
if (sp != NULL) {
if (_value != NULL) {
@@ -98,7 +97,7 @@
if (value == NULL) {
_value = NULL;
} else {
- _value = AllocateHeap(strlen(value)+1, mtInternal);
+ _value = AllocateHeap(strlen(value)+1, mtArguments);
strcpy(_value, value);
}
}
@@ -144,7 +143,7 @@
if (key == NULL) {
_key = NULL;
} else {
- _key = AllocateHeap(strlen(key)+1, mtInternal);
+ _key = AllocateHeap(strlen(key)+1, mtArguments);
strcpy(_key, key);
}
_next = NULL;
@@ -155,7 +154,7 @@
// For use by -agentlib, -agentpath and -Xrun
-class AgentLibrary : public CHeapObj<mtInternal> {
+class AgentLibrary : public CHeapObj<mtArguments> {
friend class AgentLibraryList;
public:
// Is this library valid or not. Don't rely on os_lib == NULL as statically
@@ -190,12 +189,12 @@
// Constructor
AgentLibrary(const char* name, const char* options, bool is_absolute_path, void* os_lib) {
- _name = AllocateHeap(strlen(name)+1, mtInternal);
+ _name = AllocateHeap(strlen(name)+1, mtArguments);
strcpy(_name, name);
if (options == NULL) {
_options = NULL;
} else {
- _options = AllocateHeap(strlen(options)+1, mtInternal);
+ _options = AllocateHeap(strlen(options)+1, mtArguments);
strcpy(_options, options);
}
_is_absolute_path = is_absolute_path;
--- a/hotspot/src/share/vm/runtime/basicLock.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/basicLock.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -27,7 +27,6 @@
#include "oops/markOop.hpp"
#include "runtime/handles.hpp"
-#include "utilities/top.hpp"
class BasicLock VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -226,7 +226,7 @@
// Check the ranges of all flags that have them or print them out and exit if requested
void CommandLineFlagConstraintList::init(void) {
- _constraints = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<CommandLineFlagConstraint*>(INITIAL_CONSTRAINTS_SIZE, true);
+ _constraints = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<CommandLineFlagConstraint*>(INITIAL_CONSTRAINTS_SIZE, true);
emit_constraint_no(NULL RUNTIME_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -48,7 +48,7 @@
typedef Flag::Error (*CommandLineFlagConstraintFunc_size_t)(size_t value, bool verbose);
typedef Flag::Error (*CommandLineFlagConstraintFunc_double)(double value, bool verbose);
-class CommandLineFlagConstraint : public CHeapObj<mtInternal> {
+class CommandLineFlagConstraint : public CHeapObj<mtArguments> {
public:
// During VM initialization, constraint validation will be done order of ConstraintType.
enum ConstraintType {
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -457,6 +457,51 @@
}
}
+static Flag::Error CMSReservedAreaConstraintFunc(const char* name, size_t value, bool verbose) {
+#if INCLUDE_ALL_GCS
+ if (UseConcMarkSweepGC) {
+ ConcurrentMarkSweepGeneration* cms = (ConcurrentMarkSweepGeneration*)GenCollectedHeap::heap()->old_gen();
+ const size_t ergo_max = cms->cmsSpace()->max_flag_size_for_task_size();
+ if (value > ergo_max) {
+ CommandLineError::print(verbose,
+ "%s (" SIZE_FORMAT ") must be "
+ "less than or equal to ergonomic maximum (" SIZE_FORMAT ") "
+ "which is based on the maximum size of the old generation of the Java heap\n",
+ name, value, ergo_max);
+ return Flag::VIOLATES_CONSTRAINT;
+ }
+ }
+#endif
+
+ return Flag::SUCCESS;
+}
+
+Flag::Error CMSRescanMultipleConstraintFunc(size_t value, bool verbose) {
+ Flag::Error status = CMSReservedAreaConstraintFunc("CMSRescanMultiple", value, verbose);
+
+#if INCLUDE_ALL_GCS
+ if (status == Flag::SUCCESS && UseConcMarkSweepGC) {
+ // CMSParRemarkTask::do_dirty_card_rescan_tasks requires CompactibleFreeListSpace::rescan_task_size()
+ // to be aligned to CardTableModRefBS::card_size * BitsPerWord.
+ // Note that rescan_task_size() will be aligned if CMSRescanMultiple is a multiple of 'HeapWordSize'
+ // because rescan_task_size() is CardTableModRefBS::card_size / HeapWordSize * BitsPerWord.
+ if (value % HeapWordSize != 0) {
+ CommandLineError::print(verbose,
+ "CMSRescanMultiple (" SIZE_FORMAT ") must be "
+ "a multiple of " SIZE_FORMAT "\n",
+ value, HeapWordSize);
+ status = Flag::VIOLATES_CONSTRAINT;
+ }
+ }
+#endif
+
+ return status;
+}
+
+Flag::Error CMSConcMarkMultipleConstraintFunc(size_t value, bool verbose) {
+ return CMSReservedAreaConstraintFunc("CMSConcMarkMultiple", value, verbose);
+}
+
Flag::Error CMSPrecleanDenominatorConstraintFunc(uintx value, bool verbose) {
#if INCLUDE_ALL_GCS
if (UseConcMarkSweepGC && (value <= CMSPrecleanNumerator)) {
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -60,6 +60,8 @@
Flag::Error CMSOldPLABMinConstraintFunc(size_t value, bool verbose);
Flag::Error CMSOldPLABMaxConstraintFunc(size_t value, bool verbose);
Flag::Error MarkStackSizeConstraintFunc(size_t value, bool verbose);
+Flag::Error CMSRescanMultipleConstraintFunc(size_t value, bool verbose);
+Flag::Error CMSConcMarkMultipleConstraintFunc(size_t value, bool verbose);
Flag::Error CMSPrecleanDenominatorConstraintFunc(uintx value, bool verbose);
Flag::Error CMSPrecleanNumeratorConstraintFunc(uintx value, bool verbose);
Flag::Error CMSSamplingGrainConstraintFunc(uintx value, bool verbose);
--- a/hotspot/src/share/vm/runtime/commandLineFlagRangeList.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagRangeList.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -292,7 +292,7 @@
// Check the ranges of all flags that have them
void CommandLineFlagRangeList::init(void) {
- _ranges = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<CommandLineFlagRange*>(INITIAL_RANGES_SIZE, true);
+ _ranges = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<CommandLineFlagRange*>(INITIAL_RANGES_SIZE, true);
emit_range_no(NULL RUNTIME_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
EMIT_RANGE_PD_DEVELOPER_FLAG,
--- a/hotspot/src/share/vm/runtime/commandLineFlagRangeList.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagRangeList.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -44,7 +44,7 @@
static void print(bool verbose, const char* msg, ...);
};
-class CommandLineFlagRange : public CHeapObj<mtInternal> {
+class CommandLineFlagRange : public CHeapObj<mtArguments> {
private:
const char* _name;
public:
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -896,13 +896,25 @@
break;
}
- case T_SHORT: case T_CHAR: // 2 bytes
+ case T_SHORT:
assert(value->type() == T_INT, "Agreement.");
val = value->get_int();
obj->short_at_put(index, (jshort)*((jint*)&val));
break;
- case T_BOOLEAN: case T_BYTE: // 1 byte
+ case T_CHAR:
+ assert(value->type() == T_INT, "Agreement.");
+ val = value->get_int();
+ obj->char_at_put(index, (jchar)*((jint*)&val));
+ break;
+
+ case T_BYTE:
+ assert(value->type() == T_INT, "Agreement.");
+ val = value->get_int();
+ obj->byte_at_put(index, (jbyte)*((jint*)&val));
+ break;
+
+ case T_BOOLEAN:
assert(value->type() == T_INT, "Agreement.");
val = value->get_int();
obj->bool_at_put(index, (jboolean)*((jint*)&val));
@@ -1017,13 +1029,25 @@
break;
}
- case T_SHORT: case T_CHAR: // 2 bytes
+ case T_SHORT:
assert(value->type() == T_INT, "Agreement.");
val = value->get_int();
obj->short_field_put(offset, (jshort)*((jint*)&val));
break;
- case T_BOOLEAN: case T_BYTE: // 1 byte
+ case T_CHAR:
+ assert(value->type() == T_INT, "Agreement.");
+ val = value->get_int();
+ obj->char_field_put(offset, (jchar)*((jint*)&val));
+ break;
+
+ case T_BYTE:
+ assert(value->type() == T_INT, "Agreement.");
+ val = value->get_int();
+ obj->byte_field_put(offset, (jbyte)*((jint*)&val));
+ break;
+
+ case T_BOOLEAN:
assert(value->type() == T_INT, "Agreement.");
val = value->get_int();
obj->bool_field_put(offset, (jboolean)*((jint*)&val));
--- a/hotspot/src/share/vm/runtime/frame.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/frame.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -29,7 +29,6 @@
#include "runtime/basicLock.hpp"
#include "runtime/monitorChunk.hpp"
#include "runtime/registerMap.hpp"
-#include "utilities/top.hpp"
#ifdef TARGET_ARCH_zero
# include "stack_zero.hpp"
#endif
--- a/hotspot/src/share/vm/runtime/globals.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/globals.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -35,7 +35,6 @@
#include "trace/tracing.hpp"
#include "utilities/macros.hpp"
#include "utilities/ostream.hpp"
-#include "utilities/top.hpp"
#if INCLUDE_ALL_GCS
#include "gc/g1/g1_globals.hpp"
#endif // INCLUDE_ALL_GCS
@@ -1293,7 +1292,7 @@
const size_t length = Flag::numFlags - 1;
// Sort
- Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
+ Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtArguments);
for (size_t i = 0; i < length; i++) {
array[i] = &flagTable[i];
}
@@ -1327,7 +1326,7 @@
const size_t length = Flag::numFlags - 1;
// Sort
- Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
+ Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtArguments);
for (size_t i = 0; i < length; i++) {
array[i] = &flagTable[i];
}
--- a/hotspot/src/share/vm/runtime/globals.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -641,9 +641,6 @@
"region.") \
range(1, max_uintx) \
\
- diagnostic(bool, PrintCompressedOopsMode, false, \
- "Print compressed oops base address and encoding mode") \
- \
lp64_product(intx, ObjectAlignmentInBytes, 8, \
"Default object alignment in bytes, 8 is minimum") \
range(8, 256) \
@@ -688,9 +685,6 @@
"Use large page memory in metaspace. " \
"Only used if UseLargePages is enabled.") \
\
- develop(bool, TracePageSizes, false, \
- "Trace page size selection and usage") \
- \
product(bool, UseNUMA, false, \
"Use NUMA if available") \
\
@@ -1809,13 +1803,17 @@
"enough work per iteration") \
range(0, max_intx) \
\
+ /* 4096 = CardTableModRefBS::card_size_in_words * BitsPerWord */ \
product(size_t, CMSRescanMultiple, 32, \
"Size (in cards) of CMS parallel rescan task") \
- range(1, max_uintx) \
- \
+ range(1, SIZE_MAX / 4096) \
+ constraint(CMSRescanMultipleConstraintFunc,AfterMemoryInit) \
+ \
+ /* 4096 = CardTableModRefBS::card_size_in_words * BitsPerWord */ \
product(size_t, CMSConcMarkMultiple, 32, \
"Size (in cards) of CMS concurrent MT marking task") \
- range(1, max_uintx) \
+ range(1, SIZE_MAX / 4096) \
+ constraint(CMSConcMarkMultipleConstraintFunc,AfterMemoryInit) \
\
product(bool, CMSAbortSemantics, false, \
"Whether abort-on-overflow semantics is implemented") \
@@ -2954,9 +2952,6 @@
develop(bool, TraceStackWalk, false, \
"Trace stack walking") \
\
- product(bool, MemberNameInStackFrame, true, \
- "Use MemberName in StackFrame") \
- \
/* notice: the max range value here is max_jint, not max_intx */ \
/* because of overflow issue */ \
NOT_EMBEDDED(diagnostic(intx, GuaranteedSafepointInterval, 1000, \
--- a/hotspot/src/share/vm/runtime/globals_extension.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/globals_extension.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -27,7 +27,19 @@
#include "runtime/globals.hpp"
#include "utilities/macros.hpp"
-#include "utilities/top.hpp"
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
+#include "gc/g1/g1_globals.hpp"
+#endif
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci_globals.hpp"
+#endif
+#ifdef COMPILER1
+#include "c1/c1_globals.hpp"
+#endif
+#ifdef COMPILER2
+#include "opto/c2_globals.hpp"
+#endif
// Construct enum of Flag_<cmdline-arg> constants.
--- a/hotspot/src/share/vm/runtime/init.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/init.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -25,7 +25,7 @@
#ifndef SHARE_VM_RUNTIME_INIT_HPP
#define SHARE_VM_RUNTIME_INIT_HPP
-#include "utilities/top.hpp"
+#include "utilities/globalDefinitions.hpp"
// init_globals replaces C++ global objects so we can use the standard linker
// to link Delta (which is at least twice as fast as using the GNU C++ linker).
--- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -35,7 +35,6 @@
#include "runtime/vmThread.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/preserveException.hpp"
-#include "utilities/top.hpp"
// Wrapper for all entry points to the virtual machine.
// The HandleMarkCleaner is a faster version of HandleMark.
--- a/hotspot/src/share/vm/runtime/javaCalls.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/javaCalls.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -29,7 +29,7 @@
#include "oops/method.hpp"
#include "runtime/handles.hpp"
#include "runtime/javaFrameAnchor.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/thread.hpp"
#include "runtime/vmThread.hpp"
#ifdef TARGET_ARCH_x86
# include "jniTypes_x86.hpp"
--- a/hotspot/src/share/vm/runtime/jniHandles.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/jniHandles.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -25,8 +25,8 @@
#ifndef SHARE_VM_RUNTIME_JNIHANDLES_HPP
#define SHARE_VM_RUNTIME_JNIHANDLES_HPP
+#include "memory/allocation.hpp"
#include "runtime/handles.hpp"
-#include "utilities/top.hpp"
class JNIHandleBlock;
--- a/hotspot/src/share/vm/runtime/os.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/os.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -33,6 +33,7 @@
#include "gc/shared/vmGCOperations.hpp"
#include "interpreter/interpreter.hpp"
#include "logging/log.hpp"
+#include "logging/logStream.inline.hpp"
#include "memory/allocation.inline.hpp"
#ifdef ASSERT
#include "memory/guardedMemory.hpp"
@@ -1494,31 +1495,63 @@
return errno_to_string(e, true);
}
-#ifndef PRODUCT
-void os::trace_page_sizes(const char* str, const size_t* page_sizes, int count)
-{
- if (TracePageSizes) {
- tty->print("%s: ", str);
+void os::trace_page_sizes(const char* str, const size_t* page_sizes, int count) {
+ LogTarget(Info, pagesize) log;
+ if (log.is_enabled()) {
+ LogStreamCHeap out(log);
+
+ out.print("%s: ", str);
for (int i = 0; i < count; ++i) {
- tty->print(" " SIZE_FORMAT, page_sizes[i]);
+ out.print(" " SIZE_FORMAT, page_sizes[i]);
}
- tty->cr();
+ out.cr();
}
}
-void os::trace_page_sizes(const char* str, const size_t region_min_size,
- const size_t region_max_size, const size_t page_size,
- const char* base, const size_t size)
-{
- if (TracePageSizes) {
- tty->print_cr("%s: min=" SIZE_FORMAT " max=" SIZE_FORMAT
- " pg_sz=" SIZE_FORMAT " base=" PTR_FORMAT
- " size=" SIZE_FORMAT,
- str, region_min_size, region_max_size,
- page_size, p2i(base), size);
- }
+#define trace_page_size_params(size) byte_size_in_exact_unit(size), exact_unit_for_byte_size(size)
+
+void os::trace_page_sizes(const char* str,
+ const size_t region_min_size,
+ const size_t region_max_size,
+ const size_t page_size,
+ const char* base,
+ const size_t size) {
+
+ log_info(pagesize)("%s: "
+ " min=" SIZE_FORMAT "%s"
+ " max=" SIZE_FORMAT "%s"
+ " base=" PTR_FORMAT
+ " page_size=" SIZE_FORMAT "%s"
+ " size=" SIZE_FORMAT "%s",
+ str,
+ trace_page_size_params(region_min_size),
+ trace_page_size_params(region_max_size),
+ p2i(base),
+ trace_page_size_params(page_size),
+ trace_page_size_params(size));
}
-#endif // #ifndef PRODUCT
+
+void os::trace_page_sizes_for_requested_size(const char* str,
+ const size_t requested_size,
+ const size_t page_size,
+ const size_t alignment,
+ const char* base,
+ const size_t size) {
+
+ log_info(pagesize)("%s:"
+ " req_size=" SIZE_FORMAT "%s"
+ " base=" PTR_FORMAT
+ " page_size=" SIZE_FORMAT "%s"
+ " alignment=" SIZE_FORMAT "%s"
+ " size=" SIZE_FORMAT "%s",
+ str,
+ trace_page_size_params(requested_size),
+ p2i(base),
+ trace_page_size_params(page_size),
+ trace_page_size_params(alignment),
+ trace_page_size_params(size));
+}
+
// This is the working definition of a server class machine:
// >= 2 physical CPU's and >=2GB of memory, with some fuzz
--- a/hotspot/src/share/vm/runtime/os.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/os.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -28,7 +28,6 @@
#include "jvmtifiles/jvmti.h"
#include "runtime/extendedPC.hpp"
#include "runtime/handles.hpp"
-#include "utilities/top.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "jvm_linux.h"
# include <setjmp.h>
@@ -286,18 +285,24 @@
return _page_sizes[0];
}
- // Methods for tracing page sizes returned by the above method; enabled by
- // TracePageSizes. The region_{min,max}_size parameters should be the values
+ // Methods for tracing page sizes returned by the above method.
+ // The region_{min,max}_size parameters should be the values
// passed to page_size_for_region() and page_size should be the result of that
// call. The (optional) base and size parameters should come from the
// ReservedSpace base() and size() methods.
- static void trace_page_sizes(const char* str, const size_t* page_sizes,
- int count) PRODUCT_RETURN;
- static void trace_page_sizes(const char* str, const size_t region_min_size,
+ static void trace_page_sizes(const char* str, const size_t* page_sizes, int count);
+ static void trace_page_sizes(const char* str,
+ const size_t region_min_size,
const size_t region_max_size,
const size_t page_size,
- const char* base = NULL,
- const size_t size = 0) PRODUCT_RETURN;
+ const char* base,
+ const size_t size);
+ static void trace_page_sizes_for_requested_size(const char* str,
+ const size_t requested_size,
+ const size_t page_size,
+ const size_t alignment,
+ const char* base,
+ const size_t size);
static int vm_allocation_granularity();
static char* reserve_memory(size_t bytes, char* addr = 0,
@@ -515,6 +520,9 @@
static int ftruncate(int fd, jlong length);
static int fsync(int fd);
static int available(int fd, jlong *bytes);
+ static int fileno(FILE* fp);
+
+ static int compare_file_modified_times(const char* file1, const char* file2);
//File i/o operations
--- a/hotspot/src/share/vm/runtime/osThread.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/osThread.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -29,7 +29,6 @@
#include "runtime/handles.hpp"
#include "runtime/javaFrameAnchor.hpp"
#include "runtime/objectMonitor.hpp"
-#include "utilities/top.hpp"
// The OSThread class holds OS-specific thread information. It is equivalent
// to the sys_thread_t structure of the classic JVM implementation.
--- a/hotspot/src/share/vm/runtime/reflection.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/reflection.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -1025,7 +1025,7 @@
static void narrow(jvalue* value, BasicType narrow_type, TRAPS) {
switch (narrow_type) {
case T_BOOLEAN:
- value->z = (jboolean)value->i;
+ value->z = (jboolean) (value->i & 1);
return;
case T_BYTE:
value->b = (jbyte)value->i;
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -38,6 +38,7 @@
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "logging/log.hpp"
+#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.inline.hpp"
#include "oops/klass.hpp"
@@ -1788,7 +1789,7 @@
IRT_LEAF(void, SharedRuntime::fixup_callers_callsite(Method* method, address caller_pc))
Method* moop(method);
- address entry_point = moop->from_compiled_entry();
+ address entry_point = moop->from_compiled_entry_no_trampoline();
// It's possible that deoptimization can occur at a call site which hasn't
// been resolved yet, in which case this function will be called from
@@ -2351,12 +2352,15 @@
public:
AdapterHandlerTable()
- : BasicHashtable<mtCode>(293, sizeof(AdapterHandlerEntry)) { }
+ : BasicHashtable<mtCode>(293, (DumpSharedSpaces ? sizeof(CDSAdapterHandlerEntry) : sizeof(AdapterHandlerEntry))) { }
// Create a new entry suitable for insertion in the table
AdapterHandlerEntry* new_entry(AdapterFingerPrint* fingerprint, address i2c_entry, address c2i_entry, address c2i_unverified_entry) {
AdapterHandlerEntry* entry = (AdapterHandlerEntry*)BasicHashtable<mtCode>::new_entry(fingerprint->compute_hash());
entry->init(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
+ if (DumpSharedSpaces) {
+ ((CDSAdapterHandlerEntry*)entry)->init();
+ }
return entry;
}
@@ -2519,6 +2523,28 @@
}
AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(const methodHandle& method) {
+ AdapterHandlerEntry* entry = get_adapter0(method);
+ if (method->is_shared()) {
+ MutexLocker mu(AdapterHandlerLibrary_lock);
+ if (method->adapter() == NULL) {
+ method->update_adapter_trampoline(entry);
+ }
+ address trampoline = method->from_compiled_entry();
+ if (*(int*)trampoline == 0) {
+ CodeBuffer buffer(trampoline, (int)SharedRuntime::trampoline_size());
+ MacroAssembler _masm(&buffer);
+ SharedRuntime::generate_trampoline(&_masm, entry->get_c2i_entry());
+
+ if (PrintInterpreter) {
+ Disassembler::decode(buffer.insts_begin(), buffer.insts_end());
+ }
+ }
+ }
+
+ return entry;
+}
+
+AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter0(const methodHandle& method) {
// Use customized signature handler. Need to lock around updates to
// the AdapterHandlerTable (it is not safe for concurrent readers
// and a single writer: this could be fixed if it becomes a
@@ -2535,7 +2561,9 @@
// make sure data structure is initialized
initialize();
- if (CodeCacheExtensions::skip_compiler_support()) {
+ // during dump time, always generate adapters, even if the
+ // compiler has been turned off.
+ if (!DumpSharedSpaces && CodeCacheExtensions::skip_compiler_support()) {
// adapters are useless and should not be used, including the
// abstract_method_handler. However, some callers check that
// an adapter was installed.
@@ -3017,6 +3045,17 @@
}
+#if INCLUDE_CDS
+
+void CDSAdapterHandlerEntry::init() {
+ assert(DumpSharedSpaces, "used during dump time only");
+ _c2i_entry_trampoline = (address)MetaspaceShared::misc_data_space_alloc(SharedRuntime::trampoline_size());
+ _adapter_trampoline = (AdapterHandlerEntry**)MetaspaceShared::misc_data_space_alloc(sizeof(AdapterHandlerEntry*));
+};
+
+#endif // INCLUDE_CDS
+
+
#ifndef PRODUCT
void AdapterHandlerLibrary::print_statistics() {
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -398,6 +398,10 @@
static void convert_ints_to_longints(int i2l_argcnt, int& in_args_count,
BasicType*& in_sig_bt, VMRegPair*& in_regs);
+ static size_t trampoline_size();
+
+ static void generate_trampoline(MacroAssembler *masm, address destination);
+
// Generate I2C and C2I adapters. These adapters are simple argument marshalling
// blobs. Unlike adapters in the tiger and earlier releases the code in these
// blobs does not create a new frame and are therefore virtually invisible
@@ -680,6 +684,17 @@
void print_adapter_on(outputStream* st) const;
};
+class CDSAdapterHandlerEntry: public AdapterHandlerEntry {
+ address _c2i_entry_trampoline; // allocated from shared spaces "MC" region
+ AdapterHandlerEntry** _adapter_trampoline; // allocated from shared spaces "MD" region
+
+public:
+ address get_c2i_entry_trampoline() const { return _c2i_entry_trampoline; }
+ AdapterHandlerEntry** get_adapter_trampoline() const { return _adapter_trampoline; }
+ void init() NOT_CDS_RETURN;
+};
+
+
class AdapterHandlerLibrary: public AllStatic {
private:
static BufferBlob* _buffer; // the temporary code buffer in CodeCache
@@ -687,6 +702,7 @@
static AdapterHandlerEntry* _abstract_method_handler;
static BufferBlob* buffer_blob();
static void initialize();
+ static AdapterHandlerEntry* get_adapter0(const methodHandle& method);
public:
--- a/hotspot/src/share/vm/runtime/signature.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/signature.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -27,7 +27,6 @@
#include "memory/allocation.hpp"
#include "oops/method.hpp"
-#include "utilities/top.hpp"
// SignatureIterators iterate over a Java signature (or parts of it).
// (Syntax according to: "The Java Virtual Machine Specification" by
--- a/hotspot/src/share/vm/runtime/stackValue.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/stackValue.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -27,7 +27,6 @@
#include "code/location.hpp"
#include "runtime/handles.hpp"
-#include "utilities/top.hpp"
class StackValue : public ResourceObj {
private:
--- a/hotspot/src/share/vm/runtime/stubRoutines.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -30,7 +30,6 @@
#include "runtime/frame.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/stubCodeGenerator.hpp"
-#include "utilities/top.hpp"
// StubRoutines provides entry points to assembly routines used by
// compiled code and the run-time system. Platform-specific entry
--- a/hotspot/src/share/vm/runtime/synchronizer.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/synchronizer.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -29,8 +29,6 @@
#include "runtime/basicLock.hpp"
#include "runtime/handles.hpp"
#include "runtime/perfData.hpp"
-#include "utilities/top.hpp"
-
class ObjectMonitor;
--- a/hotspot/src/share/vm/runtime/task.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/task.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -25,7 +25,8 @@
#ifndef SHARE_VM_RUNTIME_TASK_HPP
#define SHARE_VM_RUNTIME_TASK_HPP
-#include "utilities/top.hpp"
+#include "memory/allocation.hpp"
+#include "runtime/timer.hpp"
// A PeriodicTask has the sole purpose of executing its task
// function with regular intervals.
--- a/hotspot/src/share/vm/runtime/thread.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -818,13 +818,17 @@
// Thread::print_on_error() is called by fatal error handler. Don't use
// any lock or allocate memory.
void Thread::print_on_error(outputStream* st, char* buf, int buflen) const {
- if (is_VM_thread()) st->print("VMThread");
- else if (is_Compiler_thread()) st->print("CompilerThread");
- else if (is_Java_thread()) st->print("JavaThread");
- else if (is_GC_task_thread()) st->print("GCTaskThread");
- else if (is_Watcher_thread()) st->print("WatcherThread");
- else if (is_ConcurrentGC_thread()) st->print("ConcurrentGCThread");
- else st->print("Thread");
+ assert(!(is_Compiler_thread() || is_Java_thread()), "Can't call name() here if it allocates");
+
+ if (is_VM_thread()) { st->print("VMThread"); }
+ else if (is_GC_task_thread()) { st->print("GCTaskThread"); }
+ else if (is_Watcher_thread()) { st->print("WatcherThread"); }
+ else if (is_ConcurrentGC_thread()) { st->print("ConcurrentGCThread"); }
+ else { st->print("Thread"); }
+
+ if (is_Named_thread()) {
+ st->print(" \"%s\"", name());
+ }
st->print(" [stack: " PTR_FORMAT "," PTR_FORMAT "]",
p2i(stack_end()), p2i(stack_base()));
@@ -4498,6 +4502,36 @@
st->flush();
}
+void Threads::print_on_error(Thread* this_thread, outputStream* st, Thread* current, char* buf,
+ int buflen, bool* found_current) {
+ if (this_thread != NULL) {
+ bool is_current = (current == this_thread);
+ *found_current = *found_current || is_current;
+ st->print("%s", is_current ? "=>" : " ");
+
+ st->print(PTR_FORMAT, p2i(this_thread));
+ st->print(" ");
+ this_thread->print_on_error(st, buf, buflen);
+ st->cr();
+ }
+}
+
+class PrintOnErrorClosure : public ThreadClosure {
+ outputStream* _st;
+ Thread* _current;
+ char* _buf;
+ int _buflen;
+ bool* _found_current;
+ public:
+ PrintOnErrorClosure(outputStream* st, Thread* current, char* buf,
+ int buflen, bool* found_current) :
+ _st(st), _current(current), _buf(buf), _buflen(buflen), _found_current(found_current) {}
+
+ virtual void do_thread(Thread* thread) {
+ Threads::print_on_error(thread, _st, _current, _buf, _buflen, _found_current);
+ }
+};
+
// Threads::print_on_error() is called by fatal error handler. It's possible
// that VM is not at safepoint and/or current thread is inside signal handler.
// Don't print stack trace, as the stack may not be walkable. Don't allocate
@@ -4507,40 +4541,17 @@
bool found_current = false;
st->print_cr("Java Threads: ( => current thread )");
ALL_JAVA_THREADS(thread) {
- bool is_current = (current == thread);
- found_current = found_current || is_current;
-
- st->print("%s", is_current ? "=>" : " ");
-
- st->print(PTR_FORMAT, p2i(thread));
- st->print(" ");
- thread->print_on_error(st, buf, buflen);
- st->cr();
+ print_on_error(thread, st, current, buf, buflen, &found_current);
}
st->cr();
st->print_cr("Other Threads:");
- if (VMThread::vm_thread()) {
- bool is_current = (current == VMThread::vm_thread());
- found_current = found_current || is_current;
- st->print("%s", current == VMThread::vm_thread() ? "=>" : " ");
-
- st->print(PTR_FORMAT, p2i(VMThread::vm_thread()));
- st->print(" ");
- VMThread::vm_thread()->print_on_error(st, buf, buflen);
- st->cr();
- }
- WatcherThread* wt = WatcherThread::watcher_thread();
- if (wt != NULL) {
- bool is_current = (current == wt);
- found_current = found_current || is_current;
- st->print("%s", is_current ? "=>" : " ");
-
- st->print(PTR_FORMAT, p2i(wt));
- st->print(" ");
- wt->print_on_error(st, buf, buflen);
- st->cr();
- }
+ print_on_error(VMThread::vm_thread(), st, current, buf, buflen, &found_current);
+ print_on_error(WatcherThread::watcher_thread(), st, current, buf, buflen, &found_current);
+
+ PrintOnErrorClosure print_closure(st, current, buf, buflen, &found_current);
+ Universe::heap()->gc_threads_do(&print_closure);
+
if (!found_current) {
st->cr();
st->print("=>" PTR_FORMAT " (exited) ", p2i(current));
--- a/hotspot/src/share/vm/runtime/thread.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/thread.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -46,7 +46,6 @@
#include "trace/traceMacros.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/macros.hpp"
-#include "utilities/top.hpp"
#if INCLUDE_ALL_GCS
#include "gc/g1/dirtyCardQueue.hpp"
#include "gc/g1/satbMarkQueue.hpp"
@@ -2157,6 +2156,8 @@
print_on(tty, print_stacks, internal_format, false /* no concurrent lock printed */);
}
static void print_on_error(outputStream* st, Thread* current, char* buf, int buflen);
+ static void print_on_error(Thread* this_thread, outputStream* st, Thread* current, char* buf,
+ int buflen, bool* found_current);
static void print_threads_compiling(outputStream* st, char* buf, int buflen);
// Get Java threads that are waiting to enter a monitor. If doLock
--- a/hotspot/src/share/vm/runtime/threadLocalStorage.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/threadLocalStorage.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -25,7 +25,7 @@
#ifndef SHARE_VM_RUNTIME_THREADLOCALSTORAGE_HPP
#define SHARE_VM_RUNTIME_THREADLOCALSTORAGE_HPP
-#include "utilities/top.hpp"
+#include "memory/allocation.hpp"
// forward-decl as we can't have an include cycle
class Thread;
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -400,7 +400,6 @@
nonproduct_nonstatic_field(Method, _compiled_invocation_count, int) \
volatile_nonstatic_field(Method, _code, nmethod*) \
nonstatic_field(Method, _i2i_entry, address) \
- nonstatic_field(Method, _adapter, AdapterHandlerEntry*) \
volatile_nonstatic_field(Method, _from_compiled_entry, address) \
volatile_nonstatic_field(Method, _from_interpreted_entry, address) \
volatile_nonstatic_field(ConstMethod, _fingerprint, uint64_t) \
--- a/hotspot/src/share/vm/runtime/vmThread.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/vmThread.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -26,7 +26,7 @@
#define SHARE_VM_RUNTIME_VMTHREAD_HPP
#include "runtime/perfData.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/thread.hpp"
#include "runtime/vm_operations.hpp"
//
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -29,7 +29,6 @@
#include "memory/allocation.hpp"
#include "oops/oop.hpp"
#include "runtime/thread.hpp"
-#include "utilities/top.hpp"
#include "code/codeCache.hpp"
// The following classes are used for operations
--- a/hotspot/src/share/vm/runtime/vm_version.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/vm_version.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "code/codeCacheExtensions.hpp"
+#include "logging/log.hpp"
#include "memory/universe.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/arguments.hpp"
@@ -274,12 +275,12 @@
void VM_Version_init() {
VM_Version::initialize();
-#ifndef PRODUCT
- if (PrintMiscellaneous && Verbose) {
- char buf[512];
- os::print_cpu_info(tty, buf, sizeof(buf));
+ if (log_is_enabled(Info, os, cpu)) {
+ char buf[1024];
+ ResourceMark rm;
+ outputStream* log = Log(os, cpu)::info_stream();
+ os::print_cpu_info(log, buf, sizeof(buf));
}
-#endif
}
unsigned int Abstract_VM_Version::nof_parallel_worker_threads(
--- a/hotspot/src/share/vm/services/nmtCommon.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/services/nmtCommon.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -41,6 +41,7 @@
"Test",
"Tracing",
"Logging",
+ "Arguments",
"Unknown"
};
--- a/hotspot/src/share/vm/utilities/accessFlags.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/accessFlags.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -25,8 +25,9 @@
#ifndef SHARE_VM_UTILITIES_ACCESSFLAGS_HPP
#define SHARE_VM_UTILITIES_ACCESSFLAGS_HPP
+#include "memory/allocation.hpp"
#include "prims/jvm.h"
-#include "utilities/top.hpp"
+#include "utilities/macros.hpp"
// AccessFlags is an abstraction over Java access flags.
--- a/hotspot/src/share/vm/utilities/bitMap.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/bitMap.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -68,6 +68,10 @@
}
}
+void BitMap::pretouch() {
+ os::pretouch_memory(word_addr(0), word_addr(size()));
+}
+
void BitMap::set_range_within_word(idx_t beg, idx_t end) {
// With a valid range (beg <= end), this test ensures that end != 0, as
// required by inverted_bit_mask_for_range. Also avoids an unnecessary write.
--- a/hotspot/src/share/vm/utilities/bitMap.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/bitMap.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
#define SHARE_VM_UTILITIES_BITMAP_HPP
#include "memory/allocation.hpp"
-#include "utilities/top.hpp"
// Forward decl;
class BitMapClosure;
@@ -135,10 +134,18 @@
// use the same value for "in_resource_area".)
void resize(idx_t size_in_bits, bool in_resource_area = true);
+ // Pretouch the entire range of memory this BitMap covers.
+ void pretouch();
+
// Accessing
idx_t size() const { return _size; }
+ idx_t size_in_bytes() const { return size_in_words() * BytesPerWord; }
idx_t size_in_words() const {
- return word_index(size() + BitsPerWord - 1);
+ return calc_size_in_words(size());
+ }
+
+ static idx_t calc_size_in_words(size_t size_in_bits) {
+ return word_index(size_in_bits + BitsPerWord - 1);
}
bool at(idx_t index) const {
--- a/hotspot/src/share/vm/utilities/constantTag.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/constantTag.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "utilities/constantTag.hpp"
+#include "utilities/ostream.hpp"
#ifndef PRODUCT
--- a/hotspot/src/share/vm/utilities/constantTag.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/constantTag.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -25,8 +25,8 @@
#ifndef SHARE_VM_UTILITIES_CONSTANTTAG_HPP
#define SHARE_VM_UTILITIES_CONSTANTTAG_HPP
+#include "memory/allocation.hpp"
#include "prims/jvm.h"
-#include "utilities/top.hpp"
// constant tags in Java .class files
--- a/hotspot/src/share/vm/utilities/debug.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/debug.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -52,7 +52,6 @@
#include "utilities/defaultStream.hpp"
#include "utilities/events.hpp"
#include "utilities/macros.hpp"
-#include "utilities/top.hpp"
#include "utilities/vmError.hpp"
#if INCLUDE_TRACE
--- a/hotspot/src/share/vm/utilities/events.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/events.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -28,7 +28,6 @@
#include "memory/allocation.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/thread.hpp"
-#include "utilities/top.hpp"
#include "utilities/vmError.hpp"
// Events and EventMark provide interfaces to log events taking place in the vm.
--- a/hotspot/src/share/vm/utilities/exceptions.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/exceptions.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -47,7 +47,6 @@
// Forward declarations to be independent of the include structure.
-// This allows us to have exceptions.hpp included in top.hpp.
class Thread;
class Handle;
--- a/hotspot/src/share/vm/utilities/globalDefinitions.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -25,7 +25,6 @@
#include "precompiled.hpp"
#include "runtime/os.hpp"
#include "utilities/globalDefinitions.hpp"
-#include "utilities/top.hpp"
// Basic error support
@@ -374,39 +373,89 @@
#ifndef PRODUCT
// For unit testing only
-class GlobalDefinitions {
+class TestGlobalDefinitions {
+private:
+
+ static void test_clamp_address_in_page() {
+ intptr_t page_sizes[] = { os::vm_page_size(), 4096, 8192, 65536, 2*1024*1024 };
+ const int num_page_sizes = sizeof(page_sizes) / sizeof(page_sizes[0]);
+
+ for (int i = 0; i < num_page_sizes; i++) {
+ intptr_t page_size = page_sizes[i];
+
+ address a_page = (address)(10*page_size);
+
+ // Check that address within page is returned as is
+ assert(clamp_address_in_page(a_page, a_page, page_size) == a_page, "incorrect");
+ assert(clamp_address_in_page(a_page + 128, a_page, page_size) == a_page + 128, "incorrect");
+ assert(clamp_address_in_page(a_page + page_size - 1, a_page, page_size) == a_page + page_size - 1, "incorrect");
+
+ // Check that address above page returns start of next page
+ assert(clamp_address_in_page(a_page + page_size, a_page, page_size) == a_page + page_size, "incorrect");
+ assert(clamp_address_in_page(a_page + page_size + 1, a_page, page_size) == a_page + page_size, "incorrect");
+ assert(clamp_address_in_page(a_page + page_size*5 + 1, a_page, page_size) == a_page + page_size, "incorrect");
+
+ // Check that address below page returns start of page
+ assert(clamp_address_in_page(a_page - 1, a_page, page_size) == a_page, "incorrect");
+ assert(clamp_address_in_page(a_page - 2*page_size - 1, a_page, page_size) == a_page, "incorrect");
+ assert(clamp_address_in_page(a_page - 5*page_size - 1, a_page, page_size) == a_page, "incorrect");
+ }
+ }
+
+ static void test_exact_unit_for_byte_size() {
+ assert(strcmp(exact_unit_for_byte_size(0), "B") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(1), "B") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(K - 1), "B") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(K), "K") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(K + 1), "B") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(M - 1), "B") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(M), "M") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(M + 1), "B") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(M + K), "K") == 0, "incorrect");
+#ifdef LP64
+ assert(strcmp(exact_unit_for_byte_size(G - 1), "B") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(G), "G") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(G + 1), "B") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(G + K), "K") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(G + M), "M") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(G + M + K), "K") == 0, "incorrect");
+#endif
+ }
+
+ static void test_byte_size_in_exact_unit() {
+ assert(byte_size_in_exact_unit(0) == 0, "incorrect");
+ assert(byte_size_in_exact_unit(1) == 1, "incorrect");
+ assert(byte_size_in_exact_unit(K - 1) == K - 1, "incorrect");
+ assert(byte_size_in_exact_unit(K) == 1, "incorrect");
+ assert(byte_size_in_exact_unit(K + 1) == K + 1, "incorrect");
+ assert(byte_size_in_exact_unit(M - 1) == M - 1, "incorrect");
+ assert(byte_size_in_exact_unit(M) == 1, "incorrect");
+ assert(byte_size_in_exact_unit(M + 1) == M + 1, "incorrect");
+ assert(byte_size_in_exact_unit(M + K) == K + 1, "incorrect");
+#ifdef LP64
+ assert(byte_size_in_exact_unit(G - 1) == G - 1, "incorrect");
+ assert(byte_size_in_exact_unit(G) == 1, "incorrect");
+ assert(byte_size_in_exact_unit(G + 1) == G + 1, "incorrect");
+ assert(byte_size_in_exact_unit(G + K) == M + 1, "incorrect");
+ assert(byte_size_in_exact_unit(G + M) == K + 1, "incorrect");
+ assert(byte_size_in_exact_unit(G + M + K) == M + K + 1, "incorrect");
+#endif
+ }
+
+ static void test_exact_units() {
+ test_exact_unit_for_byte_size();
+ test_byte_size_in_exact_unit();
+ }
+
public:
- static void test_globals();
+ static void test() {
+ test_clamp_address_in_page();
+ test_exact_units();
+ }
};
-void GlobalDefinitions::test_globals() {
- intptr_t page_sizes[] = { os::vm_page_size(), 4096, 8192, 65536, 2*1024*1024 };
- const int num_page_sizes = sizeof(page_sizes) / sizeof(page_sizes[0]);
-
- for (int i = 0; i < num_page_sizes; i++) {
- intptr_t page_size = page_sizes[i];
-
- address a_page = (address)(10*page_size);
-
- // Check that address within page is returned as is
- assert(clamp_address_in_page(a_page, a_page, page_size) == a_page, "incorrect");
- assert(clamp_address_in_page(a_page + 128, a_page, page_size) == a_page + 128, "incorrect");
- assert(clamp_address_in_page(a_page + page_size - 1, a_page, page_size) == a_page + page_size - 1, "incorrect");
-
- // Check that address above page returns start of next page
- assert(clamp_address_in_page(a_page + page_size, a_page, page_size) == a_page + page_size, "incorrect");
- assert(clamp_address_in_page(a_page + page_size + 1, a_page, page_size) == a_page + page_size, "incorrect");
- assert(clamp_address_in_page(a_page + page_size*5 + 1, a_page, page_size) == a_page + page_size, "incorrect");
-
- // Check that address below page returns start of page
- assert(clamp_address_in_page(a_page - 1, a_page, page_size) == a_page, "incorrect");
- assert(clamp_address_in_page(a_page - 2*page_size - 1, a_page, page_size) == a_page, "incorrect");
- assert(clamp_address_in_page(a_page - 5*page_size - 1, a_page, page_size) == a_page, "incorrect");
- }
-}
-
-void GlobalDefinitions_test() {
- GlobalDefinitions::test_globals();
+void TestGlobalDefinitions_test() {
+ TestGlobalDefinitions::test();
}
#endif // PRODUCT
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -199,9 +199,6 @@
const size_t G = M*K;
const size_t HWperKB = K / sizeof(HeapWord);
-const jint min_jint = (jint)1 << (sizeof(jint)*BitsPerByte-1); // 0x80000000 == smallest jint
-const jint max_jint = (juint)min_jint - 1; // 0x7FFFFFFF == largest jint
-
// Constants for converting from a base unit to milli-base units. For
// example from seconds to milliseconds and microseconds
@@ -243,6 +240,36 @@
}
}
+inline const char* exact_unit_for_byte_size(size_t s) {
+#ifdef _LP64
+ if (s >= G && (s % G) == 0) {
+ return "G";
+ }
+#endif
+ if (s >= M && (s % M) == 0) {
+ return "M";
+ }
+ if (s >= K && (s % K) == 0) {
+ return "K";
+ }
+ return "B";
+}
+
+inline size_t byte_size_in_exact_unit(size_t s) {
+#ifdef _LP64
+ if (s >= G && (s % G) == 0) {
+ return s / G;
+ }
+#endif
+ if (s >= M && (s % M) == 0) {
+ return s / M;
+ }
+ if (s >= K && (s % K) == 0) {
+ return s / K;
+ }
+ return s;
+}
+
//----------------------------------------------------------------------------------------------------
// VM type definitions
@@ -328,7 +355,7 @@
// so far from the middle of the road that it is likely to be problematic in
// many C++ compilers.
//
-#define CAST_TO_FN_PTR(func_type, value) ((func_type)(castable_address(value)))
+#define CAST_TO_FN_PTR(func_type, value) (reinterpret_cast<func_type>(value))
#define CAST_FROM_FN_PTR(new_type, func_ptr) ((new_type)((address_word)(func_ptr)))
// Unsigned byte types for os and stream.hpp
@@ -351,6 +378,14 @@
typedef jint s4;
typedef jlong s8;
+const jbyte min_jbyte = -(1 << 7); // smallest jbyte
+const jbyte max_jbyte = (1 << 7) - 1; // largest jbyte
+const jshort min_jshort = -(1 << 15); // smallest jshort
+const jshort max_jshort = (1 << 15) - 1; // largest jshort
+
+const jint min_jint = (jint)1 << (sizeof(jint)*BitsPerByte-1); // 0x80000000 == smallest jint
+const jint max_jint = (juint)min_jint - 1; // 0x7FFFFFFF == largest jint
+
//----------------------------------------------------------------------------------------------------
// JVM spec restrictions
@@ -816,14 +851,15 @@
enum TosState { // describes the tos cache contents
btos = 0, // byte, bool tos cached
- ctos = 1, // char tos cached
- stos = 2, // short tos cached
- itos = 3, // int tos cached
- ltos = 4, // long tos cached
- ftos = 5, // float tos cached
- dtos = 6, // double tos cached
- atos = 7, // object cached
- vtos = 8, // tos not cached
+ ztos = 1, // byte, bool tos cached
+ ctos = 2, // char tos cached
+ stos = 3, // short tos cached
+ itos = 4, // int tos cached
+ ltos = 5, // long tos cached
+ ftos = 6, // float tos cached
+ dtos = 7, // double tos cached
+ atos = 8, // object cached
+ vtos = 9, // tos not cached
number_of_states,
ilgl // illegal state: should not occur
};
@@ -832,7 +868,7 @@
inline TosState as_TosState(BasicType type) {
switch (type) {
case T_BYTE : return btos;
- case T_BOOLEAN: return btos; // FIXME: Add ztos
+ case T_BOOLEAN: return ztos;
case T_CHAR : return ctos;
case T_SHORT : return stos;
case T_INT : return itos;
@@ -848,8 +884,8 @@
inline BasicType as_BasicType(TosState state) {
switch (state) {
- //case ztos: return T_BOOLEAN;//FIXME
case btos : return T_BYTE;
+ case ztos : return T_BOOLEAN;
case ctos : return T_CHAR;
case stos : return T_SHORT;
case itos : return T_INT;
--- a/hotspot/src/share/vm/utilities/growableArray.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/growableArray.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -29,7 +29,6 @@
#include "memory/allocation.inline.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
-#include "utilities/top.hpp"
// A growable array.
--- a/hotspot/src/share/vm/utilities/internalVMTests.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -50,7 +50,7 @@
run_unit_test(TestMetaspaceAux_test);
run_unit_test(TestMetachunk_test);
run_unit_test(TestVirtualSpaceNode_test);
- run_unit_test(GlobalDefinitions_test);
+ run_unit_test(TestGlobalDefinitions_test);
run_unit_test(GCTimer_test);
run_unit_test(arrayOopDesc_test);
run_unit_test(CollectedHeap_test);
@@ -67,6 +67,7 @@
run_unit_test(Test_linked_list);
run_unit_test(TestChunkedList_test);
run_unit_test(JSON_test);
+ run_unit_test(Test_log_tag_combinations_limit);
run_unit_test(Test_logtarget);
run_unit_test(Test_logstream);
run_unit_test(Test_loghandle);
@@ -77,6 +78,9 @@
run_unit_test(Test_log_prefix);
run_unit_test(Test_log_big);
run_unit_test(Test_logtagset_duplicates);
+ run_unit_test(Test_log_file_startup_rotation);
+ run_unit_test(Test_log_file_startup_truncation);
+ run_unit_test(Test_invalid_log_file);
run_unit_test(DirectivesParser_test);
run_unit_test(Test_TempNewSymbol);
#if INCLUDE_VM_STRUCTS
--- a/hotspot/src/share/vm/utilities/ostream.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/ostream.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -31,7 +31,6 @@
#include "utilities/defaultStream.hpp"
#include "utilities/macros.hpp"
#include "utilities/ostream.hpp"
-#include "utilities/top.hpp"
#include "utilities/xmlstream.hpp"
extern "C" void jio_print(const char* s); // Declarationtion of jvm method
--- a/hotspot/src/share/vm/utilities/pair.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/pair.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -26,7 +26,6 @@
#define SHARE_VM_UTILITIES_PAIR_HPP
#include "memory/allocation.hpp"
-#include "utilities/top.hpp"
template<typename T, typename V, typename ALLOC_BASE = ResourceObj>
class Pair : public ALLOC_BASE {
--- a/hotspot/src/share/vm/utilities/preserveException.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/preserveException.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -26,7 +26,7 @@
#define SHARE_VM_UTILITIES_PRESERVEEXCEPTION_HPP
#include "runtime/handles.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/thread.hpp"
// This file provides more support for exception handling; see also exceptions.hpp
class PreserveExceptionMark {
--- a/hotspot/src/share/vm/utilities/resourceHash.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/resourceHash.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -26,7 +26,6 @@
#define SHARE_VM_UTILITIES_RESOURCEHASH_HPP
#include "memory/allocation.hpp"
-#include "utilities/top.hpp"
template<typename K> struct ResourceHashtableFns {
typedef unsigned (*hash_fn)(K const&);
--- a/hotspot/src/share/vm/utilities/top.hpp Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 1997, 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.
- *
- */
-
-#ifndef SHARE_VM_UTILITIES_TOP_HPP
-#define SHARE_VM_UTILITIES_TOP_HPP
-
-#include "oops/oopsHierarchy.hpp"
-#include "runtime/globals.hpp"
-#include "utilities/debug.hpp"
-#include "utilities/exceptions.hpp"
-#include "utilities/globalDefinitions.hpp"
-#include "utilities/macros.hpp"
-#include "utilities/ostream.hpp"
-#include "utilities/sizes.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc/g1/g1_globals.hpp"
-#endif // INCLUDE_ALL_GCS
-#ifdef COMPILER1
-#include "c1/c1_globals.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/c2_globals.hpp"
-#endif
-#if INCLUDE_JVMCI
-#include "jvmci/jvmci_globals.hpp"
-#endif
-
-// THIS FILE IS INTESIONALLY LEFT EMPTY
-// IT IS USED TO MINIMIZE THE NUMBER OF DEPENDENCIES IN includeDB
-
-#endif // SHARE_VM_UTILITIES_TOP_HPP
--- a/hotspot/src/share/vm/utilities/utf8.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/utf8.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -26,7 +26,6 @@
#define SHARE_VM_UTILITIES_UTF8_HPP
#include "memory/allocation.hpp"
-#include "utilities/top.hpp"
// Low-level interface for UTF8 strings
--- a/hotspot/src/share/vm/utilities/vmError.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -43,7 +43,6 @@
#include "utilities/defaultStream.hpp"
#include "utilities/errorReporter.hpp"
#include "utilities/events.hpp"
-#include "utilities/top.hpp"
#include "utilities/vmError.hpp"
// List of environment variables that should be reported in error log file.
--- a/hotspot/test/TEST.ROOT Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/TEST.ROOT Thu Apr 28 23:08:17 2016 -0700
@@ -30,6 +30,10 @@
keys=cte_test jcmd nmt regression gc stress
groups=TEST.groups [closed/TEST.groups]
+
+# Source files for classes that will be used at the beginning of each test suite run,
+# to determine additional characteristics of the system for use with the @requires tag.
+requires.extraPropDefns = ../../test/jtreg-ext/requires/VMProps.java
requires.properties=sun.arch.data.model
# Tests using jtreg 4.2 b01 features
--- a/hotspot/test/TEST.groups Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/TEST.groups Thu Apr 28 23:08:17 2016 -0700
@@ -338,6 +338,7 @@
sanity/ExecuteInternalVMTests.java \
gc/ \
-gc/g1/ \
+ -gc/stress \
-gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java \
-gc/cms/TestMBeanCMS.java \
-gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java
@@ -346,7 +347,7 @@
sanity/ExecuteInternalVMTests.java
hotspot_fast_gc_gcold = \
- stress/gc/TestGCOld.java
+ gc/stress/TestGCOld.java
hotspot_fast_runtime = \
runtime/ \
@@ -387,7 +388,8 @@
:hotspot_fast_compiler_2 \
:hotspot_fast_compiler_3 \
:hotspot_fast_compiler_closed \
- :hotspot_fast_gc \
+ :hotspot_fast_gc_1 \
+ :hotspot_fast_gc_2 \
:hotspot_fast_gc_closed \
:hotspot_fast_gc_gcold \
:hotspot_fast_runtime \
--- a/hotspot/test/gc/TestHumongousReferenceObject.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/gc/TestHumongousReferenceObject.java Thu Apr 28 23:08:17 2016 -0700
@@ -27,26 +27,26 @@
* @test
* @summary Test that verifies that iteration over large, plain Java objects, that potentially cross region boundaries on G1, with references in them works.
* @requires vm.gc == "null"
- * @bug 8151499
+ * @bug 8151499 8153734
* @modules java.base/jdk.internal.vm.annotation
- * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx1g -XX:+UseParallelGC -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
- * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx1g -XX:+UseG1GC -XX:G1HeapRegionSize=1M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
- * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx1g -XX:+UseG1GC -XX:G1HeapRegionSize=2M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
- * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx1g -XX:+UseG1GC -XX:G1HeapRegionSize=4M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
- * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx1g -XX:+UseG1GC -XX:G1HeapRegionSize=8M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
+ * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx128m -XX:+UseParallelGC -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
+ * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx128m -XX:+UseG1GC -XX:G1HeapRegionSize=1M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
+ * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx128m -XX:+UseG1GC -XX:G1HeapRegionSize=2M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
+ * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx128m -XX:+UseG1GC -XX:G1HeapRegionSize=4M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
+ * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx128m -XX:+UseG1GC -XX:G1HeapRegionSize=8M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
*/
public class TestHumongousReferenceObject {
/*
Due to 300 fields with 8K @Contended padding around each field, it takes 2.4M bytes per instance.
With small G1 regions, it is bound to cross regions. G1 should properly (card) mark the object nevertheless.
- With 1G heap, it is enough to allocate ~400 of these objects to provoke at least one GC.
+ With 128M heap, it is enough to allocate ~100 of these objects to provoke at least one GC.
*/
static volatile Object instance;
public static void main(String[] args) {
- for (int c = 0; c < 400; c++) {
+ for (int c = 0; c < 100; c++) {
instance = new TestHumongousReferenceObject();
}
}
--- a/hotspot/test/gc/arguments/TestG1ConcRefinementThreads.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/gc/arguments/TestG1ConcRefinementThreads.java Thu Apr 28 23:08:17 2016 -0700
@@ -38,7 +38,7 @@
public class TestG1ConcRefinementThreads {
- static final int AUTO_SELECT_THREADS_COUNT = 0;
+ static final int AUTO_SELECT_THREADS_COUNT = -1;
static final int PASSED_THREADS_COUNT = 11;
public static void main(String args[]) throws Exception {
@@ -49,8 +49,8 @@
// zero setting case
runG1ConcRefinementThreadsTest(
- new String[]{"-XX:G1ConcRefinementThreads=0"}, // automatically selected
- AUTO_SELECT_THREADS_COUNT /* set to zero */);
+ new String[]{"-XX:G1ConcRefinementThreads=0"},
+ 0);
// non-zero sestting case
runG1ConcRefinementThreadsTest(
@@ -77,7 +77,7 @@
private static void checkG1ConcRefinementThreadsConsistency(String output, int expectedValue) {
int actualValue = getIntValue("G1ConcRefinementThreads", output);
- if (expectedValue == 0) {
+ if (expectedValue == AUTO_SELECT_THREADS_COUNT) {
// If expectedValue is automatically selected, set it same as ParallelGCThreads.
expectedValue = getIntValue("ParallelGCThreads", output);
}
--- a/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java Thu Apr 28 23:08:17 2016 -0700
@@ -168,6 +168,11 @@
long maxHeapSize = getMax();
int gcTries = (shrinkHeapInSteps ? GC_TRIES : 1);
+ // Initial checks. This also links up everything in these helper methods,
+ // in case it brings more garbage.
+ forceGC(gcTries);
+ verifyRatio(minRatio, maxRatio);
+
// commit 0.5 of total heap size to have enough space
// to both shink and expand
while (getCommitted() < maxHeapSize / 2) {
@@ -215,7 +220,6 @@
if (previouslyCommitted <= getCommitted()) {
throw new RuntimeException("Heap was not shrinked.");
}
-
}
public static void forceGC(int gcTries) {
--- a/hotspot/test/gc/g1/Test2GbHeap.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/gc/g1/Test2GbHeap.java Thu Apr 28 23:08:17 2016 -0700
@@ -25,6 +25,9 @@
* @test Test2GbHeap
* @bug 8031686
* @summary Regression test to ensure we can start G1 with 2gb heap.
+ * Skip test on 32 bit Windows: it typically does not support the many and large virtual memory reservations needed.
+ * @requires (vm.gc == "G1" | vm.gc == "null")
+ * @requires !((sun.arch.data.model == "32") & (os.family == "windows"))
* @key gc
* @key regression
* @library /testlibrary
@@ -48,17 +51,6 @@
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(testArguments.toArray(new String[0]));
OutputAnalyzer output = new OutputAnalyzer(pb.start());
-
- // Avoid failing test for setups not supported.
- if (output.getOutput().contains("Could not reserve enough space for 2097152KB object heap")) {
- // Will fail on machines with too little memory (and Windows 32-bit VM), ignore such failures.
- output.shouldHaveExitValue(1);
- } else if (output.getOutput().contains("-XX:+UseG1GC not supported in this VM")) {
- // G1 is not supported on embedded, ignore such failures.
- output.shouldHaveExitValue(1);
- } else {
- // Normally everything should be fine.
- output.shouldHaveExitValue(0);
- }
+ output.shouldHaveExitValue(0);
}
}
--- a/hotspot/test/gc/g1/TestLargePageUseForAuxMemory.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/gc/g1/TestLargePageUseForAuxMemory.java Thu Apr 28 23:08:17 2016 -0700
@@ -36,6 +36,8 @@
*/
import java.lang.Math;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import jdk.test.lib.*;
import jdk.test.lib.Asserts;
@@ -47,14 +49,29 @@
static long smallPageSize;
static long allocGranularity;
+ static void checkSize(OutputAnalyzer output, long expectedSize, String pattern) {
+ String pageSizeStr = output.firstMatch(pattern, 1);
+
+ if (pageSizeStr == null) {
+ output.reportDiagnosticSummary();
+ throw new RuntimeException("Match from '" + pattern + "' got 'null' expected: " + expectedSize);
+ }
+
+ long size = parseMemoryString(pageSizeStr);
+ if (size != expectedSize) {
+ output.reportDiagnosticSummary();
+ throw new RuntimeException("Match from '" + pattern + "' got " + size + " expected: " + expectedSize);
+ }
+ }
+
static void checkSmallTables(OutputAnalyzer output, long expectedPageSize) throws Exception {
- output.shouldContain("G1 'Block offset table': pg_sz=" + expectedPageSize);
- output.shouldContain("G1 'Card counts table': pg_sz=" + expectedPageSize);
+ checkSize(output, expectedPageSize, "Block Offset Table: .*page_size=([^ ]+)");
+ checkSize(output, expectedPageSize, "Card Counts Table: .*page_size=([^ ]+)");
}
static void checkBitmaps(OutputAnalyzer output, long expectedPageSize) throws Exception {
- output.shouldContain("G1 'Prev Bitmap': pg_sz=" + expectedPageSize);
- output.shouldContain("G1 'Next Bitmap': pg_sz=" + expectedPageSize);
+ checkSize(output, expectedPageSize, "Prev Bitmap: .*page_size=([^ ]+)");
+ checkSize(output, expectedPageSize, "Next Bitmap: .*page_size=([^ ]+)");
}
static void testVM(String what, long heapsize, boolean cardsShouldUseLargePages, boolean bitmapShouldUseLargePages) throws Exception {
@@ -66,7 +83,7 @@
"-XX:G1HeapRegionSize=" + HEAP_REGION_SIZE,
"-Xms" + heapsize,
"-Xmx" + heapsize,
- "-XX:+TracePageSizes",
+ "-Xlog:pagesize",
"-XX:+UseLargePages",
"-XX:+IgnoreUnrecognizedVMOptions", // there is no ObjectAlignmentInBytes in 32 bit builds
"-XX:ObjectAlignmentInBytes=8",
@@ -82,7 +99,7 @@
"-XX:G1HeapRegionSize=" + HEAP_REGION_SIZE,
"-Xms" + heapsize,
"-Xmx" + heapsize,
- "-XX:+TracePageSizes",
+ "-Xlog:pagesize",
"-XX:-UseLargePages",
"-XX:+IgnoreUnrecognizedVMOptions", // there is no ObjectAlignmentInBytes in 32 bit builds
"-XX:ObjectAlignmentInBytes=8",
@@ -108,11 +125,6 @@
}
public static void main(String[] args) throws Exception {
- if (!Platform.isDebugBuild()) {
- System.out.println("Skip tests on non-debug builds because the required option TracePageSizes is a debug-only option.");
- return;
- }
-
// Size that a single card covers.
final int cardSize = 512;
WhiteBox wb = WhiteBox.getWhiteBox();
@@ -159,4 +171,24 @@
testVM("case5: only bitmap uses large pages (extra slack)", heapSizeForBitmapUsingLargePages + heapSizeDiffForBitmap, false, true);
testVM("case6: nothing uses large pages (barely not)", heapSizeForBitmapUsingLargePages - heapSizeDiffForBitmap, false, false);
}
+
+ public static long parseMemoryString(String value) {
+ long multiplier = 1;
+
+ if (value.endsWith("B")) {
+ multiplier = 1;
+ } else if (value.endsWith("K")) {
+ multiplier = 1024;
+ } else if (value.endsWith("M")) {
+ multiplier = 1024 * 1024;
+ } else if (value.endsWith("G")) {
+ multiplier = 1024 * 1024 * 1024;
+ } else {
+ throw new IllegalArgumentException("Expected memory string '" + value + "'to end with either of: B, K, M, G");
+ }
+
+ long longValue = Long.parseUnsignedLong(value.substring(0, value.length() - 1));
+
+ return longValue * multiplier;
+ }
}
--- a/hotspot/test/gc/g1/humongousObjects/TestHumongousThreshold.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/gc/g1/humongousObjects/TestHumongousThreshold.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015,2016 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -70,7 +70,7 @@
private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
private static final int REGION_SIZE = WHITE_BOX.g1RegionSize();
private static final int MAX_CONTINUOUS_SIZE_CHECK = 129;
- private static final int NON_HUMONGOUS_DIVIDER = 10;
+ private static final int NON_HUMONGOUS_STEPS = 10;
/**
* The method allocates byte[] with specified size and checks that:
@@ -84,7 +84,7 @@
* @return allocated byte array
*/
- private static byte[] allocateAndCheck(int arraySize, boolean expectedHumongous) {
+ private static void allocateAndCheck(int arraySize, boolean expectedHumongous) {
byte[] storage = new byte[arraySize];
long objectSize = WHITE_BOX.getObjectSize(storage);
boolean shouldBeHumongous = objectSize > (REGION_SIZE / 2);
@@ -98,7 +98,6 @@
"Object should be allocated as " + (shouldBeHumongous ? "humongous"
: "non-humongous") + " but it wasn't; Allocation size = " + arraySize + "; Object size = "
+ objectSize + "; region size = " + REGION_SIZE);
- return storage;
}
public static void main(String[] args) {
@@ -108,7 +107,7 @@
int maxByteArrayNonHumongousSize = (REGION_SIZE / 2) - byteArrayMemoryOverhead;
// Increment for non-humongous testing
- int nonHumongousStep = maxByteArrayNonHumongousSize / NON_HUMONGOUS_DIVIDER;
+ int nonHumongousStep = maxByteArrayNonHumongousSize / NON_HUMONGOUS_STEPS;
// Maximum byte[] that takes one region
int maxByteArrayOneRegionSize = REGION_SIZE - byteArrayMemoryOverhead;
@@ -131,10 +130,10 @@
allocateAndCheck(i, false);
}
- // Testing allocations with byte[] with length from 0 to nonHumongousStep * NON_HUMONGOUS_DIVIDER
+ // Testing allocations with byte[] with length from 0 to nonHumongousStep * NON_HUMONGOUS_STEPS
System.out.format("Testing allocations with byte[] with length from 0 to %d with step %d%n",
- nonHumongousStep * NON_HUMONGOUS_DIVIDER, nonHumongousStep);
- for (int i = 0; i < NON_HUMONGOUS_DIVIDER; ++i) {
+ nonHumongousStep * NON_HUMONGOUS_STEPS, nonHumongousStep);
+ for (int i = 0; i < NON_HUMONGOUS_STEPS; ++i) {
allocateAndCheck(i * nonHumongousStep, false);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/plab/TestPLABEvacuationFailure.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /*
+ * @test TestPLABEvacuationFailure
+ * @bug 8148376
+ * @summary Checks PLAB statistics on evacuation failure
+ * @requires vm.gc=="G1" | vm.gc=="null"
+ * @library /testlibrary /
+ * @modules java.management
+ * @build gc.g1.plab.lib.LogParser
+ * gc.g1.plab.lib.AppPLABEvacuationFailure
+ * @run main gc.g1.plab.TestPLABEvacuationFailure
+ */
+package gc.g1.plab;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.Utils;
+
+import gc.g1.plab.lib.LogParser;
+import gc.g1.plab.lib.AppPLABEvacuationFailure;
+import gc.g1.plab.lib.PlabInfo;
+
+/**
+ * The test runs the AppPLABEvacuationFailure application to provoke a number of
+ * Evacuation Failures, parses GC log and analyzes PLAB statistics. The test checks
+ * that both fields 'failure_waste' and 'failure_used' for Evacuation Failure statistic
+ * are non zero, and zero for other statistics.
+ */
+public class TestPLABEvacuationFailure {
+
+ /* PLAB statistics fields which are checked.
+ * Test expects to find 0 in this fields in survivor statistics.
+ * Expects to find 0 in old statistics for GC when evacuation failure
+ * did not happen. And expects to find not 0 in old statistics in case when
+ * GC causes to evacuation failure.
+ */
+ private static final List<String> FAILURE_STAT_FIELDS = new ArrayList<>(Arrays.asList(
+ "failure used",
+ "failure wasted"));
+
+ private static final String[] COMMON_OPTIONS = {
+ "-Xlog:gc=debug,gc+plab=debug,gc+phases=trace",
+ "-XX:+UseG1GC",
+ "-XX:InitiatingHeapOccupancyPercent=100",
+ "-XX:-G1UseAdaptiveIHOP",
+ "-XX:G1HeapRegionSize=1m"};
+
+ private static final Pattern GC_ID_PATTERN = Pattern.compile("GC\\((\\d+)\\)");
+ private static List<Long> evacuationFailureIDs;
+ private static LogParser logParser;
+ private static String appPlabEvacFailureOutput;
+
+ public static void main(String[] args) throws Throwable {
+ // ParallelGCBufferWastePct, PLAB Size, ParallelGCBufferWastePct, MaxHeapSize, is plab fixed.
+ runTest(10, 1024, 3, 16, true);
+ runTest(15, 2048, 4, 256, true);
+ runTest(20, 65536, 7, 128, false);
+ runTest(25, 1024, 3, 16, true);
+ runTest(30, 16384, 7, 256, false);
+ runTest(10, 65536, 4, 32, false);
+ }
+
+ private static void runTest(int wastePct, int plabSize, int parGCThreads, int heapSize, boolean plabIsFixed) throws Throwable {
+ System.out.println("Test case details:");
+ System.out.println(" Heap size : " + heapSize + "M");
+ System.out.println(" Initial PLAB size : " + plabSize);
+ System.out.println(" Parallel GC buffer waste pct : " + wastePct);
+ System.out.println(" Parallel GC threads : " + parGCThreads);
+ System.out.println(" PLAB size is fixed: " + (plabIsFixed ? "yes" : "no"));
+ // Set up test GC and PLAB options
+ List<String> testOptions = new ArrayList<>();
+ Collections.addAll(testOptions, COMMON_OPTIONS);
+ Collections.addAll(testOptions, Utils.getTestJavaOpts());
+ Collections.addAll(testOptions,
+ "-XX:ParallelGCThreads=" + parGCThreads,
+ "-XX:ParallelGCBufferWastePct=" + wastePct,
+ "-XX:OldPLABSize=" + plabSize,
+ "-XX:YoungPLABSize=" + plabSize,
+ "-XX:" + (plabIsFixed ? "-" : "+") + "ResizePLAB",
+ "-XX:MaxHeapSize=" + heapSize + "m");
+ testOptions.add(AppPLABEvacuationFailure.class.getName());
+ OutputAnalyzer out = ProcessTools.executeTestJvm(testOptions.toArray(new String[testOptions.size()]));
+
+ appPlabEvacFailureOutput = out.getOutput();
+ if (out.getExitValue() != 0) {
+ System.out.println(appPlabEvacFailureOutput);
+ throw new RuntimeException("Expect exit code 0.");
+ }
+ // Get list of GC ID on evacuation failure
+ evacuationFailureIDs = getGcIdPlabEvacFailures(out);
+ logParser = new LogParser(appPlabEvacFailureOutput);
+ checkResults();
+ }
+
+ private static void checkResults() {
+
+ if (evacuationFailureIDs.isEmpty()) {
+ System.out.println(appPlabEvacFailureOutput);
+ throw new RuntimeException("AppPLABEvacuationFailure did not reach Evacuation Failure.");
+ }
+
+ Map<Long, PlabInfo> valuesToCheck = getNonEvacFailureSurvivorStats();
+ checkValuesIsZero(valuesToCheck, "Expect that SURVIVOR PLAB failure statistics should be 0 when no evacuation failure");
+
+ valuesToCheck = getNonEvacFailureOldStats();
+ checkValuesIsZero(valuesToCheck, "Expect that OLD PLAB failure statistics should be 0 when no evacuation failure");
+
+ valuesToCheck = getEvacFailureSurvivorStats();
+ checkValuesIsZero(valuesToCheck, "Expect that failure statistics should be 0 in SURVIVOR PLAB statistics at evacuation failure");
+
+ valuesToCheck = getEvacFailureOldStats();
+ checkValuesIsNotZero(valuesToCheck, "Expect that failure statistics should not be 0 in OLD PLAB statistics at evacuation failure");
+ }
+
+ /**
+ * Checks logItems for non-zero values. Throws RuntimeException if found.
+ *
+ * @param logItems
+ * @param errorMessage
+ */
+ private static void checkValuesIsZero(Map<Long, PlabInfo> logItems, String errorMessage) {
+ checkValues(logItems, errorMessage, true);
+ }
+
+ /**
+ * Checks logItems for zero values. Throws RuntimeException if found.
+ *
+ * @param logItems
+ * @param errorMessage
+ */
+ private static void checkValuesIsNotZero(Map<Long, PlabInfo> logItems, String errorMessage) {
+ checkValues(logItems, errorMessage, false);
+ }
+
+ private static void checkValues(Map<Long, PlabInfo> logItems, String errorMessage, boolean expectZero) {
+ logItems.entrySet()
+ .forEach(item -> item.getValue()
+ .values()
+ .forEach(items -> {
+ if (expectZero != (items == 0)) {
+ System.out.println(appPlabEvacFailureOutput);
+ throw new RuntimeException(errorMessage);
+ }
+ })
+ );
+ }
+
+ /**
+ * For tracking PLAB statistics for specified PLAB type - survivor and old
+ */
+ private static Map<Long, PlabInfo> getNonEvacFailureSurvivorStats() {
+ return logParser.getExcludedSpecifiedStats(evacuationFailureIDs, LogParser.ReportType.SURVIVOR_STATS, FAILURE_STAT_FIELDS);
+ }
+
+ private static Map<Long, PlabInfo> getNonEvacFailureOldStats() {
+ return logParser.getExcludedSpecifiedStats(evacuationFailureIDs, LogParser.ReportType.OLD_STATS, FAILURE_STAT_FIELDS);
+ }
+
+ private static Map<Long, PlabInfo> getEvacFailureSurvivorStats() {
+ return logParser.getSpecifiedStats(evacuationFailureIDs, LogParser.ReportType.SURVIVOR_STATS, FAILURE_STAT_FIELDS);
+ }
+
+ private static Map<Long, PlabInfo> getEvacFailureOldStats() {
+ return logParser.getSpecifiedStats(evacuationFailureIDs, LogParser.ReportType.OLD_STATS, FAILURE_STAT_FIELDS);
+ }
+
+ private static List<Long> getGcIdPlabEvacFailures(OutputAnalyzer out) {
+ return out.asLines().stream()
+ .filter(line -> line.contains("Evacuation Failure"))
+ .map(line -> LogParser.getGcIdFromLine(line, GC_ID_PATTERN))
+ .collect(Collectors.toList());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/plab/lib/AppPLABEvacuationFailure.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package gc.g1.plab.lib;
+
+import java.util.ArrayList;
+
+/**
+ * Application that provokes Evacuation Failure
+ */
+public class AppPLABEvacuationFailure {
+
+ public static final int CHUNK = 10000;
+ public static ArrayList<Object> arr = new ArrayList<>();
+
+ public static void main(String[] args) {
+ System.gc();
+ // First attempt.
+ try {
+ while (true) {
+ arr.add(new byte[CHUNK]);
+ }
+ } catch (OutOfMemoryError oome) {
+ arr.clear();
+ }
+ // Second attempt.
+ try {
+ while (true) {
+ arr.add(new byte[CHUNK]);
+ }
+ } catch (OutOfMemoryError oome) {
+ arr.clear();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/TestGCOld.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,417 @@
+/*
+* 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 TestGCOld
+ * @key gc
+ * @key stress
+ * @requires vm.gc=="null"
+ * @summary Stress the GC by trying to make old objects more likely to be garbage than young objects.
+ * @run main/othervm -Xmx384M -XX:+UseSerialGC TestGCOld 50 1 20 10 10000
+ * @run main/othervm -Xmx384M -XX:+UseParallelGC TestGCOld 50 1 20 10 10000
+ * @run main/othervm -Xmx384M -XX:+UseParallelGC -XX:-UseParallelOldGC TestGCOld 50 1 20 10 10000
+ * @run main/othervm -Xmx384M -XX:+UseConcMarkSweepGC TestGCOld 50 1 20 10 10000
+ * @run main/othervm -Xmx384M -XX:+UseG1GC TestGCOld 50 1 20 10 10000
+ */
+
+import java.text.*;
+import java.util.Random;
+
+class TreeNode {
+ public TreeNode left, right;
+ public int val; // will always be the height of the tree
+}
+
+
+/* Args:
+ live-data-size: in megabytes (approximate, will be rounded down).
+ work: units of mutator non-allocation work per byte allocated,
+ (in unspecified units. This will affect the promotion rate
+ printed at the end of the run: more mutator work per step implies
+ fewer steps per second implies fewer bytes promoted per second.)
+ short/long ratio: ratio of short-lived bytes allocated to long-lived
+ bytes allocated.
+ pointer mutation rate: number of pointer mutations per step.
+ steps: number of steps to do.
+*/
+
+public class TestGCOld {
+
+ // Command-line parameters.
+
+ private static int size, workUnits, promoteRate, ptrMutRate, steps;
+
+ // Constants.
+
+ private static final int MEG = 1000000;
+ private static final int INSIGNIFICANT = 999; // this many bytes don't matter
+ private static final int BYTES_PER_WORD = 4;
+ private static final int BYTES_PER_NODE = 20; // bytes per TreeNode
+ private static final int WORDS_DEAD = 100; // size of young garbage object
+
+ private final static int treeHeight = 14;
+ private final static long treeSize = heightToBytes(treeHeight);
+
+ private static final String msg1
+ = "Usage: java TestGCOld <size> <work> <ratio> <mutation> <steps>";
+ private static final String msg2
+ = " where <size> is the live storage in megabytes";
+ private static final String msg3
+ = " <work> is the mutator work per step (arbitrary units)";
+ private static final String msg4
+ = " <ratio> is the ratio of short-lived to long-lived allocation";
+ private static final String msg5
+ = " <mutation> is the mutations per step";
+ private static final String msg6
+ = " <steps> is the number of steps";
+
+ // Counters (and global variables that discourage optimization)
+
+ private static long youngBytes = 0; // total young bytes allocated
+ private static long nodes = 0; // total tree nodes allocated
+ private static long actuallyMut = 0; // pointer mutations in old trees
+ private static long mutatorSum = 0; // checksum to discourage optimization
+ public static int[] aexport; // exported array to discourage opt
+
+ // Global variables.
+
+ private static TreeNode[] trees;
+ private static int where = 0; // roving index into trees
+ private static Random rnd = new Random();
+
+ // Returns the height of the given tree.
+
+ private static int height (TreeNode t) {
+ if (t == null) {
+ return 0;
+ }
+ else {
+ return 1 + Math.max (height (t.left), height (t.right));
+ }
+ }
+
+ // Returns the length of the shortest path in the given tree.
+
+ private static int shortestPath (TreeNode t) {
+ if (t == null) {
+ return 0;
+ }
+ else {
+ return 1 + Math.min (shortestPath (t.left), shortestPath (t.right));
+ }
+ }
+
+ // Returns the number of nodes in a balanced tree of the given height.
+
+ private static long heightToNodes (int h) {
+ if (h == 0) {
+ return 0;
+ }
+ else {
+ long n = 1;
+ while (h > 1) {
+ n = n + n;
+ h = h - 1;
+ }
+ return n + n - 1;
+ }
+ }
+
+ // Returns the number of bytes in a balanced tree of the given height.
+
+ private static long heightToBytes (int h) {
+ return BYTES_PER_NODE * heightToNodes (h);
+ }
+
+ // Returns the height of the largest balanced tree
+ // that has no more than the given number of nodes.
+
+ private static int nodesToHeight (long nodes) {
+ int h = 1;
+ long n = 1;
+ while (n + n - 1 <= nodes) {
+ n = n + n;
+ h = h + 1;
+ }
+ return h - 1;
+ }
+
+ // Returns the height of the largest balanced tree
+ // that occupies no more than the given number of bytes.
+
+ private static int bytesToHeight (long bytes) {
+ return nodesToHeight (bytes / BYTES_PER_NODE);
+ }
+
+ // Returns a newly allocated balanced binary tree of height h.
+
+ private static TreeNode makeTree(int h) {
+ if (h == 0) return null;
+ else {
+ TreeNode res = new TreeNode();
+ nodes++;
+ res.left = makeTree(h-1);
+ res.right = makeTree(h-1);
+ res.val = h;
+ return res;
+ }
+ }
+
+ // Allocates approximately size megabytes of trees and stores
+ // them into a global array.
+
+ private static void init() {
+ int ntrees = (int) ((size * MEG) / treeSize);
+ trees = new TreeNode[ntrees];
+
+ System.err.println("Allocating " + ntrees + " trees.");
+ System.err.println(" (" + (ntrees * treeSize) + " bytes)");
+ for (int i = 0; i < ntrees; i++) {
+ trees[i] = makeTree(treeHeight);
+ // doYoungGenAlloc(promoteRate*ntrees*treeSize, WORDS_DEAD);
+ }
+ System.err.println(" (" + nodes + " nodes)");
+
+ /* Allow any in-progress GC to catch up... */
+ // try { Thread.sleep(20000); } catch (InterruptedException x) {}
+ }
+
+ // Confirms that all trees are balanced and have the correct height.
+
+ private static void checkTrees() {
+ int ntrees = trees.length;
+ for (int i = 0; i < ntrees; i++) {
+ TreeNode t = trees[i];
+ int h1 = height(t);
+ int h2 = shortestPath(t);
+ if ((h1 != treeHeight) || (h2 != treeHeight)) {
+ System.err.println("*****BUG: " + h1 + " " + h2);
+ }
+ }
+ }
+
+ // Called only by replaceTree (below) and by itself.
+
+ private static void replaceTreeWork(TreeNode full, TreeNode partial, boolean dir) {
+ boolean canGoLeft = full.left != null && full.left.val > partial.val;
+ boolean canGoRight = full.right != null && full.right.val > partial.val;
+ if (canGoLeft && canGoRight) {
+ if (dir)
+ replaceTreeWork(full.left, partial, !dir);
+ else
+ replaceTreeWork(full.right, partial, !dir);
+ } else if (!canGoLeft && !canGoRight) {
+ if (dir)
+ full.left = partial;
+ else
+ full.right = partial;
+ } else if (!canGoLeft) {
+ full.left = partial;
+ } else {
+ full.right = partial;
+ }
+ }
+
+ // Given a balanced tree full and a smaller balanced tree partial,
+ // replaces an appropriate subtree of full by partial, taking care
+ // to preserve the shape of the full tree.
+
+ private static void replaceTree(TreeNode full, TreeNode partial) {
+ boolean dir = (partial.val % 2) == 0;
+ actuallyMut++;
+ replaceTreeWork(full, partial, dir);
+ }
+
+ // Allocates approximately n bytes of long-lived storage,
+ // replacing oldest existing long-lived storage.
+
+ private static void oldGenAlloc(long n) {
+ int full = (int) (n / treeSize);
+ long partial = n % treeSize;
+ // System.out.println("In oldGenAlloc, doing " + full + " full trees "
+ // + "and one partial tree of size " + partial);
+ for (int i = 0; i < full; i++) {
+ trees[where++] = makeTree(treeHeight);
+ if (where == trees.length) where = 0;
+ }
+ while (partial > INSIGNIFICANT) {
+ int h = bytesToHeight(partial);
+ TreeNode newTree = makeTree(h);
+ replaceTree(trees[where++], newTree);
+ if (where == trees.length) where = 0;
+ partial = partial - heightToBytes(h);
+ }
+ }
+
+ // Interchanges two randomly selected subtrees (of same size and depth).
+
+ private static void oldGenSwapSubtrees() {
+ // Randomly pick:
+ // * two tree indices
+ // * A depth
+ // * A path to that depth.
+ int index1 = rnd.nextInt(trees.length);
+ int index2 = rnd.nextInt(trees.length);
+ int depth = rnd.nextInt(treeHeight);
+ int path = rnd.nextInt();
+ TreeNode tn1 = trees[index1];
+ TreeNode tn2 = trees[index2];
+ for (int i = 0; i < depth; i++) {
+ if ((path & 1) == 0) {
+ tn1 = tn1.left;
+ tn2 = tn2.left;
+ } else {
+ tn1 = tn1.right;
+ tn2 = tn2.right;
+ }
+ path >>= 1;
+ }
+ TreeNode tmp;
+ if ((path & 1) == 0) {
+ tmp = tn1.left;
+ tn1.left = tn2.left;
+ tn2.left = tmp;
+ } else {
+ tmp = tn1.right;
+ tn1.right = tn2.right;
+ tn2.right = tmp;
+ }
+ actuallyMut += 2;
+ }
+
+ // Update "n" old-generation pointers.
+
+ private static void oldGenMut(long n) {
+ for (int i = 0; i < n/2; i++) {
+ oldGenSwapSubtrees();
+ }
+ }
+
+ // Does the amount of mutator work appropriate for n bytes of young-gen
+ // garbage allocation.
+
+ private static void doMutWork(long n) {
+ int sum = 0;
+ long limit = workUnits*n/10;
+ for (long k = 0; k < limit; k++) sum++;
+ // We don't want dead code elimination to eliminate the loop above.
+ mutatorSum = mutatorSum + sum;
+ }
+
+ // Allocate n bytes of young-gen garbage, in units of "nwords"
+ // words.
+
+ private static void doYoungGenAlloc(long n, int nwords) {
+ final int nbytes = nwords*BYTES_PER_WORD;
+ int allocated = 0;
+ while (allocated < n) {
+ aexport = new int[nwords];
+ /* System.err.println("Step"); */
+ allocated += nbytes;
+ }
+ youngBytes = youngBytes + allocated;
+ }
+
+ // Allocate "n" bytes of young-gen data; and do the
+ // corresponding amount of old-gen allocation and pointer
+ // mutation.
+
+ // oldGenAlloc may perform some mutations, so this code
+ // takes those mutations into account.
+
+ private static void doStep(long n) {
+ long mutations = actuallyMut;
+
+ doYoungGenAlloc(n, WORDS_DEAD);
+ doMutWork(n);
+ oldGenAlloc(n / promoteRate);
+ oldGenMut(Math.max(0L, (mutations + ptrMutRate) - actuallyMut));
+ }
+
+ public static void main(String[] args) {
+ if (args.length != 5) {
+ System.err.println(msg1);
+ System.err.println(msg2);
+ System.err.println(msg3);
+ System.err.println(msg4);
+ System.err.println(msg5);
+ System.err.println(msg6);
+ return;
+ }
+
+ size = Integer.parseInt(args[0]);
+ workUnits = Integer.parseInt(args[1]);
+ promoteRate = Integer.parseInt(args[2]);
+ ptrMutRate = Integer.parseInt(args[3]);
+ steps = Integer.parseInt(args[4]);
+
+ System.out.println(size + " megabytes of live storage");
+ System.out.println(workUnits + " work units per step");
+ System.out.println("promotion ratio is 1:" + promoteRate);
+ System.out.println("pointer mutation rate is " + ptrMutRate);
+ System.out.println(steps + " steps");
+
+ init();
+// checkTrees();
+ youngBytes = 0;
+ nodes = 0;
+
+ System.err.println("Initialization complete...");
+
+ long start = System.currentTimeMillis();
+
+ for (int step = 0; step < steps; step++) {
+ doStep(MEG);
+ }
+
+ long end = System.currentTimeMillis();
+ float secs = ((float)(end-start))/1000.0F;
+
+// checkTrees();
+
+ NumberFormat nf = NumberFormat.getInstance();
+ nf.setMaximumFractionDigits(1);
+ System.out.println("\nTook " + nf.format(secs) + " sec in steady state.");
+ nf.setMaximumFractionDigits(2);
+ System.out.println("Allocated " + steps + " Mb of young gen garbage"
+ + " (= " + nf.format(((float)steps)/secs) +
+ " Mb/sec)");
+ System.out.println(" (actually allocated " +
+ nf.format(((float) youngBytes)/MEG) + " megabytes)");
+ float promoted = ((float)steps) / (float)promoteRate;
+ System.out.println("Promoted " + promoted +
+ " Mb (= " + nf.format(promoted/secs) + " Mb/sec)");
+ System.out.println(" (actually promoted " +
+ nf.format(((float) (nodes * BYTES_PER_NODE))/MEG) +
+ " megabytes)");
+ if (ptrMutRate != 0) {
+ System.out.println("Mutated " + actuallyMut +
+ " pointers (= " +
+ nf.format(actuallyMut/secs) + " ptrs/sec)");
+
+ }
+ // This output serves mainly to discourage optimization.
+ System.out.println("Checksum = " + (mutatorSum + aexport.length));
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/TestMultiThreadStressRSet.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import sun.hotspot.WhiteBox;
+
+/*
+ * @test TestMultiThreadStressRSet.java
+ * @key stress
+ * @requires vm.gc=="G1" | vm.gc=="null"
+ * @requires os.maxMemory > 2G
+ *
+ * @summary Stress G1 Remembered Set using multiple threads
+ * @library /test/lib /testlibrary
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+UseG1GC -XX:G1SummarizeRSetStatsPeriod=1 -Xlog:gc
+ * -Xmx500m -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestMultiThreadStressRSet 10 4
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+UseG1GC -XX:G1SummarizeRSetStatsPeriod=100 -Xlog:gc
+ * -Xmx1G -XX:G1HeapRegionSize=8m -XX:MaxGCPauseMillis=1000 TestMultiThreadStressRSet 60 16
+ *
+ * @run main/othervm/timeout=700 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+UseG1GC -XX:G1SummarizeRSetStatsPeriod=100 -Xlog:gc
+ * -Xmx500m -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestMultiThreadStressRSet 600 32
+ */
+public class TestMultiThreadStressRSet {
+
+ private static final Random RND = new Random(2015 * 2016);
+ private static final WhiteBox WB = WhiteBox.getWhiteBox();
+ private static final int REF_SIZE = WB.getHeapOopSize();
+ private static final int REGION_SIZE = WB.g1RegionSize();
+
+ // How many regions to use for the storage
+ private static final int STORAGE_REGIONS = 20;
+
+ // Size a single obj in the storage
+ private static final int OBJ_SIZE = 1024;
+
+ // How many regions of young/old gen to use in the BUFFER
+ private static final int BUFFER_YOUNG_REGIONS = 60;
+ private static final int BUFFER_OLD_REGIONS = 40;
+
+ // Total number of objects in the storage.
+ private final int N;
+
+ // The storage of byte[]
+ private final List<Object> STORAGE;
+
+ // Where references to the Storage will be stored
+ private final List<Object[]> BUFFER;
+
+ // The length of a buffer element.
+ // RSet deals with "cards" (areas of 512 bytes), not with single refs
+ // So, to affect the RSet the BUFFER refs should be allocated in different
+ // memory cards.
+ private final int BUF_ARR_LEN = 100 * (512 / REF_SIZE);
+
+ // Total number of objects in the young/old buffers
+ private final int YOUNG;
+ private final int OLD;
+
+ // To cause Remembered Sets change their coarse level the test uses a window
+ // within STORAGE. All the BUFFER elements refer to only STORAGE objects
+ // from the current window. The window is defined by a range.
+ // The first element has got the index: 'windowStart',
+ // the last one: 'windowStart + windowSize - 1'
+ // The window is shifting periodically.
+ private int windowStart;
+ private final int windowSize;
+
+ // Counter of created worker threads
+ private int counter = 0;
+
+ private volatile String errorMessage = null;
+ private volatile boolean isEnough = false;
+
+ public static void main(String args[]) {
+ if (args.length != 2) {
+ throw new IllegalArgumentException("TEST BUG: wrong arg count " + args.length);
+ }
+ long time = Long.parseLong(args[0]);
+ int threads = Integer.parseInt(args[1]);
+ new TestMultiThreadStressRSet().test(time * 1000, threads);
+ }
+
+ /**
+ * Initiates test parameters, fills out the STORAGE and BUFFER.
+ */
+ public TestMultiThreadStressRSet() {
+
+ N = (REGION_SIZE - 1) * STORAGE_REGIONS / OBJ_SIZE + 1;
+ STORAGE = new ArrayList<>(N);
+ int bytes = OBJ_SIZE - 20;
+ for (int i = 0; i < N - 1; i++) {
+ STORAGE.add(new byte[bytes]);
+ }
+ STORAGE.add(new byte[REGION_SIZE / 2 + 100]); // humongous
+ windowStart = 0;
+ windowSize = REGION_SIZE / OBJ_SIZE;
+
+ BUFFER = new ArrayList<>();
+ int sizeOfBufferObject = 20 + REF_SIZE * BUF_ARR_LEN;
+ OLD = REGION_SIZE * BUFFER_OLD_REGIONS / sizeOfBufferObject;
+ YOUNG = REGION_SIZE * BUFFER_YOUNG_REGIONS / sizeOfBufferObject;
+ for (int i = 0; i < OLD + YOUNG; i++) {
+ BUFFER.add(new Object[BUF_ARR_LEN]);
+ }
+ }
+
+ /**
+ * Does the testing. Steps:
+ * <ul>
+ * <li> starts the Shifter thread
+ * <li> during the given time starts new Worker threads, keeping the number
+ * of live thread under limit.
+ * <li> stops the Shifter thread
+ * </ul>
+ *
+ * @param timeInMillis how long to stress
+ * @param maxThreads the maximum number of Worker thread working together.
+ */
+ public void test(long timeInMillis, int maxThreads) {
+ if (timeInMillis <= 0 || maxThreads <= 0) {
+ throw new IllegalArgumentException("TEST BUG: be positive!");
+ }
+ System.out.println("%% Time to work: " + timeInMillis / 1000 + "s");
+ System.out.println("%% Number of threads: " + maxThreads);
+ long finish = System.currentTimeMillis() + timeInMillis;
+ Shifter shift = new Shifter(this, 1000, (int) (windowSize * 0.9));
+ shift.start();
+ for (int i = 0; i < maxThreads; i++) {
+ new Worker(this, 100).start();
+ }
+ try {
+ while (System.currentTimeMillis() < finish && errorMessage == null) {
+ Thread.sleep(100);
+ }
+ } catch (Throwable t) {
+ printAllStackTraces(System.err);
+ t.printStackTrace(System.err);
+ this.errorMessage = t.getMessage();
+ } finally {
+ isEnough = true;
+ }
+ System.out.println("%% Total work cycles: " + counter);
+ if (errorMessage != null) {
+ throw new RuntimeException(errorMessage);
+ }
+ }
+
+ /**
+ * Returns an element from from the BUFFER (an object array) to keep
+ * references to the storage.
+ *
+ * @return an Object[] from buffer.
+ */
+ private Object[] getFromBuffer() {
+ int index = counter % (OLD + YOUNG);
+ synchronized (BUFFER) {
+ if (index < OLD) {
+ if (counter % 100 == (counter / 100) % 100) {
+ // need to generate garbage in the old gen to provoke mixed GC
+ return replaceInBuffer(index);
+ } else {
+ return BUFFER.get(index);
+ }
+ } else {
+ return replaceInBuffer(index);
+ }
+ }
+ }
+
+ private Object[] replaceInBuffer(int index) {
+ Object[] objs = new Object[BUF_ARR_LEN];
+ BUFFER.set(index, objs);
+ return objs;
+ }
+
+ /**
+ * Returns a random object from the current window within the storage.
+ * A storage element with index from windowStart to windowStart+windowSize.
+ *
+ * @return a random element from the current window within the storage.
+ */
+ private Object getRandomObject() {
+ int index = (windowStart + RND.nextInt(windowSize)) % N;
+ return STORAGE.get(index);
+ }
+
+ private static void printAllStackTraces(PrintStream ps) {
+ Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
+ for (Thread t : traces.keySet()) {
+ ps.println(t.toString() + " " + t.getState());
+ for (StackTraceElement traceElement : traces.get(t)) {
+ ps.println("\tat " + traceElement);
+ }
+ }
+ }
+
+ /**
+ * Thread to create a number of references from BUFFER to STORAGE.
+ */
+ private static class Worker extends Thread {
+
+ final TestMultiThreadStressRSet boss;
+ final int refs; // number of refs to OldGen
+
+ /**
+ * @param boss the tests
+ * @param refsToOldGen how many references to the OldGen to create
+ */
+ Worker(TestMultiThreadStressRSet boss, int refsToOldGen) {
+ this.boss = boss;
+ this.refs = refsToOldGen;
+ }
+
+ @Override
+ public void run() {
+ try {
+ while (!boss.isEnough) {
+ Object[] objs = boss.getFromBuffer();
+ int step = objs.length / refs;
+ for (int i = 0; i < refs; i += step) {
+ objs[i] = boss.getRandomObject();
+ }
+ boss.counter++;
+ }
+ } catch (Throwable t) {
+ t.printStackTrace(System.out);
+ boss.errorMessage = t.getMessage();
+ }
+ }
+ }
+
+ /**
+ * Periodically shifts the current STORAGE window, removing references
+ * in BUFFER that refer to objects outside the window.
+ */
+ private static class Shifter extends Thread {
+
+ final TestMultiThreadStressRSet boss;
+ final int sleepTime;
+ final int shift;
+
+ Shifter(TestMultiThreadStressRSet boss, int sleepTime, int shift) {
+ this.boss = boss;
+ this.sleepTime = sleepTime;
+ this.shift = shift;
+ }
+
+ @Override
+ public void run() {
+ try {
+ while (!boss.isEnough) {
+ Thread.sleep(sleepTime);
+ boss.windowStart += shift;
+ for (int i = 0; i < boss.OLD; i++) {
+ Object[] objs = boss.BUFFER.get(i);
+ for (int j = 0; j < objs.length; j++) {
+ objs[j] = null;
+ }
+ }
+ if (!WB.g1InConcurrentMark()) {
+ System.out.println("%% start CMC");
+ WB.g1StartConcMarkCycle();
+ } else {
+ System.out.println("%% CMC is already in progress");
+ }
+ }
+ } catch (Throwable t) {
+ t.printStackTrace(System.out);
+ boss.errorMessage = t.getMessage();
+ }
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/TestStressIHOPMultiThread.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /*
+ * @test TestStressIHOPMultiThread
+ * @bug 8148397
+ * @key stress
+ * @summary Stress test for IHOP
+ * @requires vm.gc=="G1" | vm.gc=="null"
+ * @run main/othervm/timeout=200 -Xmx128m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
+ * -XX:+UseG1GC -XX:G1HeapRegionSize=1m -XX:+G1UseAdaptiveIHOP
+ * -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread1.log
+ * -Dtimeout=2 -DheapUsageMinBound=30 -DheapUsageMaxBound=80
+ * -Dthreads=2 TestStressIHOPMultiThread
+ * @run main/othervm/timeout=200 -Xmx256m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
+ * -XX:+UseG1GC -XX:G1HeapRegionSize=2m -XX:+G1UseAdaptiveIHOP
+ * -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread2.log
+ * -Dtimeout=2 -DheapUsageMinBound=60 -DheapUsageMaxBound=90
+ * -Dthreads=3 TestStressIHOPMultiThread
+ * @run main/othervm/timeout=200 -Xmx256m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
+ * -XX:+UseG1GC -XX:G1HeapRegionSize=4m -XX:-G1UseAdaptiveIHOP
+ * -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread3.log
+ * -Dtimeout=2 -DheapUsageMinBound=40 -DheapUsageMaxBound=90
+ * -Dthreads=5 TestStressIHOPMultiThread
+ * @run main/othervm/timeout=200 -Xmx128m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
+ * -XX:+UseG1GC -XX:G1HeapRegionSize=8m -XX:+G1UseAdaptiveIHOP
+ * -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread4.log
+ * -Dtimeout=2 -DheapUsageMinBound=20 -DheapUsageMaxBound=90
+ * -Dthreads=10 TestStressIHOPMultiThread
+ * @run main/othervm/timeout=200 -Xmx512m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
+ * -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:+G1UseAdaptiveIHOP
+ * -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread5.log
+ * -Dtimeout=2 -DheapUsageMinBound=20 -DheapUsageMaxBound=90
+ * -Dthreads=17 TestStressIHOPMultiThread
+ */
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Stress test for Adaptive IHOP. Starts a number of threads that fill and free
+ * specified amount of memory. Tests work with enabled IHOP logging.
+ *
+ */
+public class TestStressIHOPMultiThread {
+
+ public final static List<Object> GARBAGE = new LinkedList<>();
+
+ private final long HEAP_SIZE;
+ // Amount of memory to be allocated before iterations start
+ private final long HEAP_PREALLOC_SIZE;
+ // Amount of memory to be allocated and freed during iterations
+ private final long HEAP_ALLOC_SIZE;
+ private final int CHUNK_SIZE = 100000;
+
+ private final int TIMEOUT;
+ private final int THREADS;
+ private final int HEAP_LOW_BOUND;
+ private final int HEAP_HIGH_BOUND;
+
+ private volatile boolean running = true;
+ private final List<AllocationThread> threads;
+
+ public static void main(String[] args) throws InterruptedException {
+ new TestStressIHOPMultiThread().start();
+
+ }
+
+ TestStressIHOPMultiThread() {
+
+ TIMEOUT = Integer.getInteger("timeout") * 60;
+ THREADS = Integer.getInteger("threads");
+ HEAP_LOW_BOUND = Integer.getInteger("heapUsageMinBound");
+ HEAP_HIGH_BOUND = Integer.getInteger("heapUsageMaxBound");
+ HEAP_SIZE = Runtime.getRuntime().maxMemory();
+
+ HEAP_PREALLOC_SIZE = HEAP_SIZE * HEAP_LOW_BOUND / 100;
+ HEAP_ALLOC_SIZE = HEAP_SIZE * (HEAP_HIGH_BOUND - HEAP_LOW_BOUND) / 100;
+
+ threads = new ArrayList<>(THREADS);
+ }
+
+ public void start() throws InterruptedException {
+ fill();
+ createThreads();
+ waitForStress();
+ stressDone();
+ waitForFinish();
+ }
+
+ /**
+ * Fills HEAP_PREALLOC_SIZE bytes of garbage.
+ */
+ private void fill() {
+ long allocated = 0;
+ while (allocated < HEAP_PREALLOC_SIZE) {
+ GARBAGE.add(new byte[CHUNK_SIZE]);
+ allocated += CHUNK_SIZE;
+ }
+ }
+
+ /**
+ * Creates a number of threads which will fill and free amount of memory.
+ */
+ private void createThreads() {
+ for (int i = 0; i < THREADS; ++i) {
+ System.out.println("Create thread " + i);
+ AllocationThread thread =new TestStressIHOPMultiThread.AllocationThread(i, HEAP_ALLOC_SIZE / THREADS);
+ // Put reference to thread garbage into common garbage for avoiding possible optimization.
+ GARBAGE.add(thread.getList());
+ threads.add(thread);
+ }
+ threads.forEach(t -> t.start());
+ }
+
+ /**
+ * Wait each thread for finishing
+ */
+ private void waitForFinish() {
+ threads.forEach(thread -> {
+ thread.silentJoin();
+ });
+ }
+
+ private boolean isRunning() {
+ return running;
+ }
+
+ private void stressDone() {
+ running = false;
+ }
+
+ private void waitForStress() throws InterruptedException {
+ Thread.sleep(TIMEOUT * 1000);
+ }
+
+ private class AllocationThread extends Thread {
+
+ private final List<Object> garbage;
+
+ private final long amountOfGarbage;
+ private final int threadId;
+
+ public AllocationThread(int id, long amount) {
+ super("Thread " + id);
+ threadId = id;
+ amountOfGarbage = amount;
+ garbage = new LinkedList<>();
+ }
+
+ /**
+ * Returns list of garbage.
+ * @return List with thread garbage.
+ */
+ public List<Object> getList(){
+ return garbage;
+ }
+
+ @Override
+ public void run() {
+ System.out.println("Start the thread " + threadId);
+ while (TestStressIHOPMultiThread.this.isRunning()) {
+ allocate(amountOfGarbage);
+ free();
+ }
+ }
+
+ private void silentJoin() {
+ System.out.println("Join the thread " + threadId);
+ try {
+ join();
+ } catch (InterruptedException ie) {
+ throw new RuntimeException(ie);
+ }
+ }
+
+ /**
+ * Allocates thread local garbage
+ */
+ private void allocate(long amount) {
+ long allocated = 0;
+ while (allocated < amount && TestStressIHOPMultiThread.this.isRunning()) {
+ garbage.add(new byte[CHUNK_SIZE]);
+ allocated += CHUNK_SIZE;
+ }
+ }
+
+ /**
+ * Frees thread local garbage
+ */
+ private void free() {
+ garbage.clear();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/TestStressRSetCoarsening.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.concurrent.TimeoutException;
+import sun.hotspot.WhiteBox;
+
+/*
+ * @test TestStressRSetCoarsening.java
+ * @key stress
+ * @bug 8146984 8147087
+ * @requires vm.gc=="G1" | vm.gc=="null"
+ * @requires os.maxMemory > 3G
+ *
+ * @summary Stress G1 Remembered Set by creating a lot of cross region links
+ * @modules java.base/jdk.internal.misc
+ * @library /testlibrary /test/lib
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm/timeout=300
+ * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+UseG1GC -Xlog:gc* -XX:MaxGCPauseMillis=1000
+ * -Xmx500m -XX:G1HeapRegionSize=1m TestStressRSetCoarsening 1 0 300
+ * @run main/othervm/timeout=300
+ * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+UseG1GC -Xlog:gc* -XX:MaxGCPauseMillis=1000
+ * -Xmx500m -XX:G1HeapRegionSize=8m TestStressRSetCoarsening 1 10 300
+ * @run main/othervm/timeout=300
+ * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+UseG1GC -Xlog:gc* -XX:MaxGCPauseMillis=1000
+ * -Xmx500m -XX:G1HeapRegionSize=32m TestStressRSetCoarsening 42 10 300
+ * @run main/othervm/timeout=300
+ * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+UseG1GC -Xlog:gc* -XX:MaxGCPauseMillis=1000
+ * -Xmx500m -XX:G1HeapRegionSize=1m TestStressRSetCoarsening 2 0 300
+ * @run main/othervm/timeout=1800
+ * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+UseG1GC -Xlog:gc* -XX:MaxGCPauseMillis=1000
+ * -Xmx1G -XX:G1HeapRegionSize=1m TestStressRSetCoarsening 500 0 1800
+ * @run main/othervm/timeout=1800
+ * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+UseG1GC -Xlog:gc* -XX:MaxGCPauseMillis=1000
+ * -Xmx1G -XX:G1HeapRegionSize=1m TestStressRSetCoarsening 10 10 1800
+ */
+
+/**
+ * What the test does.
+ * Preparation stage:
+ * Fill out ~90% of the heap with objects, each object is an object array.
+ * If we want to allocate K objects per region, we calculate N to meet:
+ * sizeOf(Object[N]) ~= regionSize / K
+ * Stress stage:
+ * No more allocation, so no more GC.
+ * We will perform a number of iterations. On each iteration i,
+ * for each pair of regions Rx and Ry we will set c[i] references
+ * from Rx to Ry. If c[i] less than c[i-1] at the end of iteration
+ * concurrent mark cycle will be initiated (to recalculate remembered sets).
+ * As the result RSet will be growing up and down, up and down many times.
+ *
+ * The test expects: no crash and no timeouts.
+ *
+ * Test Parameters:
+ * args[0] - number of objects per Heap Region (1 - means humongous)
+ * args[1] - number of regions to refresh to provoke GC at the end of cycle.
+ * (0 - means no GC, i.e. no reading from RSet)
+ * args[2] - timeout in seconds (to stop execution to avoid jtreg timeout)
+ */
+public class TestStressRSetCoarsening {
+
+ public static void main(String... args) throws InterruptedException {
+ if (args.length != 3) {
+ throw new IllegalArgumentException("Wrong number of arguments " + args.length);
+ }
+ int objectsPerRegion = Integer.parseInt(args[0]); // 1 means humongous
+ int regsToRefresh = Integer.parseInt(args[1]); // 0 means no regions to refresh at the end of cycle
+ int timeout = Integer.parseInt(args[2]); // in seconds, test should stop working eariler
+ new TestStressRSetCoarsening(objectsPerRegion, regsToRefresh, timeout).go();
+ }
+
+ private static final long KB = 1024;
+ private static final long MB = 1024 * KB;
+
+ private static final WhiteBox WB = WhiteBox.getWhiteBox();
+
+ public final Object[][] storage;
+
+ /**
+ * Number of objects per region. This is a test parameter.
+ */
+ public final int K;
+
+ /**
+ * Length of object array: sizeOf(Object[N]) ~= regionSize / K
+ * N will be calculated as function of K.
+ */
+ public final int N;
+
+ /**
+ * How many regions involved into testing.
+ * Will be calculated as heapFractionToAllocate * freeRegionCount.
+ */
+ public final int regionCount;
+
+ /**
+ * How much heap to use.
+ */
+ public final float heapFractionToAllocate = 0.9f;
+
+ /**
+ * How many regions to be refreshed at the end of cycle.
+ * This is a test parameter.
+ */
+ public final int regsToRefresh;
+
+ /**
+ * Initial time.
+ */
+ public final long start;
+
+ /**
+ * Time when the test should stop working.
+ */
+ public final long finishAt;
+
+ /**
+ * Does pre-calculation and allocate necessary objects.
+ *
+ * @param objPerRegions how many objects per G1 heap region
+ */
+ TestStressRSetCoarsening(int objPerRegions, int regsToRefresh, int timeout) {
+ this.K = objPerRegions;
+ this.regsToRefresh = regsToRefresh;
+ this.start = System.currentTimeMillis();
+ this.finishAt = start + timeout * 900; // 10% ahead of jtreg timeout
+
+ long regionSize = WB.g1RegionSize();
+
+ // How many free regions
+ Runtime rt = Runtime.getRuntime();
+ long used = rt.totalMemory() - rt.freeMemory();
+ long totalFree = rt.maxMemory() - used;
+ regionCount = (int) ((totalFree / regionSize) * heapFractionToAllocate);
+ long toAllocate = regionCount * regionSize;
+ System.out.println("%% Test parameters");
+ System.out.println("%% Objects per region : " + K);
+ System.out.println("%% Heap fraction to allocate : " + (int) (heapFractionToAllocate * 100) + "%");
+ System.out.println("%% Regions to refresh to provoke GC: " + regsToRefresh);
+
+ System.out.println("%% Memory");
+ System.out.println("%% used : " + used / MB + "M");
+ System.out.println("%% available : " + totalFree / MB + "M");
+ System.out.println("%% to allocate : " + toAllocate / MB + "M");
+ System.out.println("%% (in regs) : " + regionCount);
+ System.out.println("%% G1 Region Size: " + regionSize / MB + "M");
+
+ int refSize = WB.getHeapOopSize();
+
+ // Calculate N: K*sizeOf(Object[N]) ~= regionSize
+ // sizeOf(Object[N]) ~= (N+4)*refSize
+ // ==>
+ // N = regionSize / K / refSize - 4;
+ int n = (int) ((regionSize / K) / refSize) - 5; // best guess
+ long objSize = WB.getObjectSize(new Object[n]);
+ while (K*objSize > regionSize) { // adjust to avoid OOME
+ n = n - 1;
+ objSize = WB.getObjectSize(new Object[n]);
+ }
+ N = n;
+
+ /*
+ * --------------
+ * region0 storage[0] = new Object[N]
+ * ...
+ * storage[K-1] = new Object[N]
+ * ---------------
+ * region1 storage[K] = new Object[N]
+ * ...
+ * storage[2*K - 1] = new Object[N]
+ * --------------
+ * ...
+ * --------------
+ * regionX storage[X*K] = new Object[N]
+ * ...
+ * storage[(X+1)*K -1] = new Object[N]
+ * where X = HeapFraction * TotalRegions
+ * -------------
+ */
+ System.out.println("%% Objects");
+ System.out.println("%% N (array length) : " + N);
+ System.out.println("%% K (objects in regions): " + K);
+ System.out.println("%% Object size : " + objSize +
+ " (sizeOf(new Object[" + N + "])");
+ System.out.println("%% Reference size : " + refSize);
+
+ storage = new Object[regionCount * K][];
+ for (int i = 0; i < storage.length; i++) {
+ storage[i] = new Object[N];
+ }
+ }
+
+ public void go() throws InterruptedException {
+ // threshold for sparce -> fine
+ final int FINE = WB.getIntxVMFlag("G1RSetSparseRegionEntries").intValue();
+
+ // threshold for fine -> coarse
+ final int COARSE = WB.getIntxVMFlag("G1RSetRegionEntries").intValue();
+
+ // regToRegRefCounts - array of reference counts from region to region
+ // at the the end of iteration.
+ // The number of test iterations is array length - 1.
+ // If c[i] > c[i-1] then during the iteration i more references will
+ // be created.
+ // If c[i] < c[i-1] then some referenes will be cleaned.
+ int[] regToRegRefCounts = {0, FINE / 2, 0, FINE, (FINE + COARSE) / 2, 0,
+ COARSE, COARSE + 10, FINE + 1, FINE / 2, 0};
+
+ // For progress tracking
+ int[] progress = new int[regToRegRefCounts.length];
+ progress[0] = 0;
+ for (int i = 1; i < regToRegRefCounts.length; i++) {
+ progress[i] = progress[i - 1] + Math.abs(regToRegRefCounts[i] - regToRegRefCounts[i - 1]);
+ }
+ try {
+ for (int i = 1; i < regToRegRefCounts.length; i++) {
+ int pre = regToRegRefCounts[i - 1];
+ int cur = regToRegRefCounts[i];
+ float prog = ((float) progress[i - 1] / progress[progress.length - 1]);
+
+ System.out.println("%% step " + i
+ + " out of " + (regToRegRefCounts.length - 1)
+ + " (~" + (int) (100 * prog) + "% done)");
+ System.out.println("%% " + pre + " --> " + cur);
+ for (int to = 0; to < regionCount; to++) {
+ // Select a celebrity object that we will install references to.
+ // The celebrity will be referred from all other regions.
+ // If the number of references after should be less than they
+ // were before, select NULL.
+ Object celebrity = cur > pre ? storage[to * K] : null;
+ for (int from = 0; from < regionCount; from++) {
+ if (to == from) {
+ continue; // no need to refer to itself
+ }
+
+ int step = cur > pre ? +1 : -1;
+ for (int rn = pre; rn != cur; rn += step) {
+ storage[getY(to, from, rn)][getX(to, from, rn)] = celebrity;
+ if (System.currentTimeMillis() > finishAt) {
+ throw new TimeoutException();
+ }
+ }
+ }
+ }
+ if (pre > cur) {
+ // Number of references went down.
+ // Need to provoke recalculation of RSet.
+ WB.g1StartConcMarkCycle();
+ while (WB.g1InConcurrentMark()) {
+ Thread.sleep(1);
+ }
+ }
+
+ // To force the use of rememebered set entries we need to provoke a GC.
+ // To induce some fragmentation, and some mixed GCs, we need
+ // to make a few objects unreachable.
+ for (int toClean = i * regsToRefresh; toClean < (i + 1) * regsToRefresh; toClean++) {
+ int to = toClean % regionCount;
+ // Need to remove all references from all regions to the region 'to'
+ for (int from = 0; from < regionCount; from++) {
+ if (to == from) {
+ continue; // no need to refer to itself
+ }
+ for (int rn = 0; rn <= cur; rn++) {
+ storage[getY(to, from, rn)][getX(to, from, rn)] = null;
+ }
+ }
+ // 'Refresh' storage elements for the region 'to'
+ // After that loop all 'old' objects in the region 'to'
+ // should become unreachable.
+ for (int k = 0; k < K; k++) {
+ storage[(to * K + k) % storage.length] = new Object[N];
+ }
+ }
+ }
+ } catch (TimeoutException e) {
+ System.out.println("%% TIMEOUT!!!");
+ }
+ long now = System.currentTimeMillis();
+ System.out.println("%% Summary");
+ System.out.println("%% Time spent : " + ((now - start) / 1000) + " seconds");
+ System.out.println("%% Free memory left : " + Runtime.getRuntime().freeMemory() / KB + "K");
+ System.out.println("%% Test passed");
+ }
+
+ /**
+ * Returns X index in the Storage of the reference #rn from the region
+ * 'from' to the region 'to'.
+ *
+ * @param to region # to refer to
+ * @param from region # to refer from
+ * @param rn number of reference
+ *
+ * @return X index in the range: [0 ... N-1]
+ */
+ private int getX(int to, int from, int rn) {
+ return (rn * regionCount + to) % N;
+ }
+
+ /**
+ * Returns Y index in the Storage of the reference #rn from the region
+ * 'from' to the region 'to'.
+ *
+ * @param to region # to refer to
+ * @param from region # to refer from
+ * @param rn number of reference
+ *
+ * @return Y index in the range: [0 ... K*regionCount -1]
+ */
+ private int getY(int to, int from, int rn) {
+ return ((rn * regionCount + to) / N + from * K) % (regionCount * K);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/BoolReturn/BoolConstructor.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import jdk.test.lib.Asserts;
+
+public class BoolConstructor {
+
+ boolean field;
+ BoolConstructor(boolean b, boolean expected) {
+ field = b;
+ // System.out.println("b is " + b + " field is " + field);
+ Asserts.assertTrue(field == b, "BoolConstructor argument not converted correctly");
+ Asserts.assertTrue(field == expected, "BoolConstructor argument not stored correctly");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/BoolReturn/NativeSmallIntCallsTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8149170
+ * @summary Test native functions return booleans as 0/1 but differently than java functions
+ * @library /testlibrary
+ * @compile BoolConstructor.java
+ * @run main/native NativeSmallIntCallsTest
+ */
+
+// This test shows that returns from native calls for boolean truncate to JNI_TRUE if value != 0
+// and JNI_FALSE if value returned is 0.
+
+import jdk.test.lib.Asserts;
+
+public class NativeSmallIntCallsTest {
+ static native boolean nativeCastToBoolCallTrue();
+ static native boolean nativeCastToBoolCallFalse();
+ static native boolean nativeCallBoolConstructor(int visible, boolean expected);
+ static {
+ System.loadLibrary("NativeSmallIntCalls");
+ }
+
+ public static void main(java.lang.String[] unused) throws Exception {
+ // Call through jni
+ // JNI makes all results != 0 true for compatibility
+ boolean nativeTrueVal = nativeCastToBoolCallTrue();
+ Asserts.assertTrue(nativeTrueVal, "trueval is false!");
+
+ boolean nativeFalseVal = nativeCastToBoolCallFalse();
+ Asserts.assertTrue(nativeFalseVal, "falseval is false in native!");
+
+ // Call a constructor or method that passes jboolean values into Java from native
+ nativeCallBoolConstructor(1, true);
+ nativeCallBoolConstructor(0x10, true);
+ nativeCallBoolConstructor(0x100, false);
+ nativeCallBoolConstructor(0x1000, false);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/BoolReturn/libNativeSmallIntCalls.c Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <jni.h>
+
+JNIEXPORT void JNICALL
+Java_NativeSmallIntCallsTest_nativeCallBoolConstructor(JNIEnv* env, jobject obj, int visible, int expected) {
+ jclass cls;
+ jmethodID ctor;
+
+ cls = (*env)->FindClass(env, "BoolConstructor");
+ if(NULL == cls) {
+ return;
+ }
+
+ ctor = (*env)->GetMethodID(env, cls, "<init>", "(ZZ)V");
+ if(NULL == ctor) {
+ return;
+ }
+
+ // printf("visible 0x%x expected %d\n", visible, expected);
+
+ (*env)->NewObject(env, cls, ctor, (jboolean) visible, expected);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_NativeSmallIntCallsTest_nativeCastToBoolCallTrue(JNIEnv* env, jobject obj) {
+
+ return 55;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_NativeSmallIntCallsTest_nativeCastToBoolCallFalse(JNIEnv* env, jobject obj) {
+
+ return 44;
+}
+
--- a/hotspot/test/runtime/CompressedOops/CompressedClassPointers.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/runtime/CompressedOops/CompressedClassPointers.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -85,8 +85,7 @@
public static void heapBaseMinAddressTest() throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-XX:HeapBaseMinAddress=1m",
- "-XX:+UnlockDiagnosticVMOptions",
- "-XX:+PrintCompressedOopsMode",
+ "-Xlog:gc+heap+coops=debug",
"-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("HeapBaseMinAddress must be at least");
--- a/hotspot/test/runtime/CompressedOops/UseCompressedOops.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/runtime/CompressedOops/UseCompressedOops.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -169,7 +169,6 @@
ArrayList<String> args = new ArrayList<>();
// Always run with these three:
- args.add("-XX:+UnlockDiagnosticVMOptions");
args.add("-XX:+PrintCompressedOopsMode");
args.add("-Xms32m");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/Throwable/ThrowableIntrospectionSegfault.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8033735
+ * @summary check backtrace field introspection
+ * @library /testlibrary
+ * @run main ThrowableIntrospectionSegfault
+ */
+
+import java.lang.reflect.*;
+
+public class ThrowableIntrospectionSegfault {
+ public static void main(java.lang.String[] unused) {
+ // Construct a throwable object.
+ Throwable throwable = new Throwable();
+ throwable.fillInStackTrace();
+
+ // Retrieve a reflection handle to the private backtrace field.
+ Class class1 = throwable.getClass();
+ Field field;
+ try {
+ field = class1.getDeclaredField("backtrace");
+ }
+ catch (NoSuchFieldException e) {
+ System.err.println("Can't retrieve field handle Throwable.backtrace: " + e.toString());
+ return;
+ }
+ field.setAccessible(true);
+
+ // Retrieve the value of the backtrace field.
+ Object backtrace;
+ try {
+ backtrace = field.get(throwable);
+ }
+ catch (IllegalAccessException e) {
+ System.err.println( "Can't retrieve field value for Throwable.backtrace: " + e.toString());
+ return;
+ }
+
+ try {
+
+ // Retrieve the class of throwable.backtrace[0][0].
+ Class class2 = ((Object[]) ((Object[]) backtrace)[2])[0].getClass();
+
+ // Segfault occurs while executing this line, to retrieve the name of
+ // this class.
+ String class2Name = class2.getName();
+
+ System.err.println("class2Name=" + class2Name);
+ return; // pass! Passes if it doesn't crash.
+ } catch (ClassCastException e) {
+ // Passes if it doesn't crash. Also if the backtrace changes this test might get
+ // ClassCastException and that's ok too.
+ System.out.println("Catch exception " + e);
+ return; // pass! Passes if it doesn't crash.
+ }
+ }
+}
--- a/hotspot/test/runtime/logging/ClassInitializationTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/runtime/logging/ClassInitializationTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -62,6 +62,16 @@
out.shouldContain("[Initialized").shouldContain("without side effects]");
out.shouldHaveExitValue(0);
}
+
+ // (3) classinit should turn off.
+ pb = ProcessTools.createJavaProcessBuilder("-Xlog:classinit=off",
+ "-Xverify:all",
+ "-Xmx64m",
+ "BadMap50");
+ out = new OutputAnalyzer(pb.start());
+ out.shouldNotContain("[classinit]");
+ out.shouldNotContain("Fail over class verification to old verifier for: BadMap50");
+
}
public static class InnerClass {
public static void main(String[] args) throws Exception {
--- a/hotspot/test/runtime/logging/ClassResolutionTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/runtime/logging/ClassResolutionTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -51,7 +51,8 @@
};
public static void main(String... args) throws Exception {
- Thing1Handler.getThingNumber();
+ int x = Thing1Handler.getThingNumber();
+ System.out.println("ThingNumber: "+Integer.toString(x));
}
}
@@ -62,6 +63,7 @@
ClassResolutionTestMain.class.getName());
OutputAnalyzer o = new OutputAnalyzer(pb.start());
o.shouldContain("[classresolve] ClassResolutionTest$ClassResolutionTestMain$Thing1Handler ClassResolutionTest$ClassResolutionTestMain$Thing1");
+ o.shouldContain("[classresolve] resolve JVM_CONSTANT_MethodHandle");
// (2) classresolve should turn off.
pb = ProcessTools.createJavaProcessBuilder("-Xlog:classresolve=debug",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/logging/CompressedOopsTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8149991
+ * @requires (sun.arch.data.model == "64")
+ * @summary -Xlog:gc+heap+coops=info should have output from the code
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.misc
+ * java.management
+ * @build jdk.test.lib.OutputAnalyzer jdk.test.lib.Platform jdk.test.lib.ProcessTools
+ * @run driver CompressedOopsTest
+ */
+
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.Platform;
+import jdk.test.lib.ProcessTools;
+
+public class CompressedOopsTest {
+ static void analyzeOutputOn(ProcessBuilder pb) throws Exception {
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("[gc,heap,coops] Heap address");
+ output.shouldHaveExitValue(0);
+ }
+
+ static void analyzeOutputOff(ProcessBuilder pb) throws Exception {
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("[gc,heap,coops]");
+ output.shouldHaveExitValue(0);
+ }
+
+ public static void main(String[] args) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseCompressedOops",
+ "-Xlog:gc+heap+coops=info",
+ InnerClass.class.getName());
+ analyzeOutputOn(pb);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:+UseCompressedOops",
+ "-XX:+PrintCompressedOopsMode",
+ InnerClass.class.getName());
+ analyzeOutputOn(pb);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:+UseCompressedOops",
+ "-XX:+PrintCompressedOopsMode",
+ "-Xlog:gc+heap+coops=off",
+ InnerClass.class.getName());
+ analyzeOutputOff(pb);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:+UseCompressedOops",
+ "-Xlog:gc+heap+coops=info",
+ "-XX:-PrintCompressedOopsMode",
+ InnerClass.class.getName());
+ analyzeOutputOff(pb);
+ }
+
+ public static class InnerClass {
+ public static void main(String[] args) throws Exception {
+ System.out.println("Compressed Oops (gc+heap+coops) test");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/logging/OsCpuLoggingTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8151939
+ * @summary os+cpu output should contain some os,cpu information
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.misc
+ * java.management
+ * @build jdk.test.lib.OutputAnalyzer jdk.test.lib.ProcessTools
+ * @run driver OsCpuLoggingTest
+ */
+
+import java.io.File;
+import java.util.Map;
+import jdk.test.lib.*;
+
+public class OsCpuLoggingTest {
+
+ static void analyzeOutputForOsLog(OutputAnalyzer output) throws Exception {
+ // Aix has it's own logging
+ if (!Platform.isAix()) {
+ output.shouldContain("SafePoint Polling address");
+ }
+ output.shouldHaveExitValue(0);
+ }
+
+ static void analyzeOutputForOsCpuLog(OutputAnalyzer output) throws Exception {
+ output.shouldContain("CPU:total");
+ output.shouldHaveExitValue(0);
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xlog:os+cpu", "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ analyzeOutputForOsCpuLog(output);
+
+ pb = ProcessTools.createJavaProcessBuilder("-Xlog:os", "-version");
+ output = new OutputAnalyzer(pb.start());
+ analyzeOutputForOsLog(output);
+ }
+}
--- a/hotspot/test/runtime/modules/AccessCheck/ExportAllUnnamed.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/runtime/modules/AccessCheck/ExportAllUnnamed.java Thu Apr 28 23:08:17 2016 -0700
@@ -28,11 +28,12 @@
* @summary Test if package p2 in module m2 is exported to all unnamed,
* then class p1.c1 in an unnamed module can read p2.c2 in module m2.
* @library /testlibrary /test/lib
+ * @modules java.base/jdk.internal.module
* @compile myloaders/MySameClassLoader.java
* @compile p2/c2.java
* @compile p1/c1.java
- * @compile -XaddExports:java.base/jdk.internal.module=ALL-UNNAMED ExportAllUnnamed.java
- * @run main/othervm -XaddExports:java.base/jdk.internal.module=ALL-UNNAMED -Xbootclasspath/a:. ExportAllUnnamed
+ * @build ExportAllUnnamed
+ * @run main/othervm -Xbootclasspath/a:. ExportAllUnnamed
*/
import static jdk.test.lib.Asserts.*;
--- a/hotspot/test/serviceability/logging/TestLogRotation.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/serviceability/logging/TestLogRotation.java Thu Apr 28 23:08:17 2016 -0700
@@ -102,8 +102,10 @@
smallFilesNumber++;
}
}
- if (logs.length != numberOfFiles) {
- throw new Error("There are only " + logs.length + " logs instead " + numberOfFiles);
+ // Expect one more log file since the number-of-files doesn't include the active log file
+ int expectedNumberOfFiles = numberOfFiles + 1;
+ if (logs.length != expectedNumberOfFiles) {
+ throw new Error("There are " + logs.length + " logs instead of the expected " + expectedNumberOfFiles);
}
if (smallFilesNumber > 1) {
throw new Error("There should maximum one log with size < " + logFileSizeK + "K");
--- a/hotspot/test/serviceability/logging/TestQuotedLogOutputs.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/serviceability/logging/TestQuotedLogOutputs.java Thu Apr 28 23:08:17 2016 -0700
@@ -101,7 +101,7 @@
output.shouldHaveExitValue(1);
// Ensure error message was logged
output.shouldMatch("([Mm]issing terminating quote)"
- + "|(Could not open log file '')"
+ + "|(Error opening log file '')"
+ "|(Output name can not be partially quoted)");
}
}
--- a/hotspot/test/serviceability/sa/DeadlockDetectionTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/serviceability/sa/DeadlockDetectionTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -80,6 +80,12 @@
return;
}
+ if (Platform.isOSX()) {
+ // Coredump stackwalking is not implemented for Darwin
+ System.out.println("This test is not expected to work on OS X. Skipping");
+ return;
+ }
+
if (!LingeredApp.isLastModifiedWorking()) {
// Exact behaviour of the test depends on operating system and the test nature,
--- a/hotspot/test/serviceability/tmtools/jstack/JstackThreadTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstack/JstackThreadTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -25,6 +25,8 @@
import jdk.test.lib.JDKToolLauncher;
import jdk.test.lib.OutputAnalyzer;
import jdk.test.lib.ProcessTools;
+import utils.Utils;
+import java.util.concurrent.CountDownLatch;
/*
* @test JstackThreadTest
@@ -32,23 +34,22 @@
* @summary jstack doesn't close quotation marks properly with threads' name greater than 1996 characters
* @library /testlibrary
* @build jdk.test.lib.*
- * @ignore 8153319
* @run main JstackThreadTest
*/
public class JstackThreadTest {
static class NamedThread extends Thread {
- NamedThread(String name) {
+ CountDownLatch latch;
+ NamedThread(String name, CountDownLatch latch) {
+ this.latch = latch;
setName(name);
+
}
@Override
public void run() {
- try {
- Thread.sleep(2000);
- } catch(Exception e){
- e.printStackTrace();
- }
- }
+ latch.countDown();
+ Utils.sleep();
}
+ }
public static void main(String[] args) throws Exception {
StringBuilder sb = new StringBuilder();
@@ -60,8 +61,11 @@
}
private static void testWithName(String name) throws Exception {
+ //parent thread countDown latch
+ CountDownLatch latch = new CountDownLatch(1);
// Start a thread with a long thread name
- NamedThread thread = new NamedThread(name);
+ NamedThread thread = new NamedThread(name, latch);
+ thread.setDaemon(true);
thread.start();
ProcessBuilder processBuilder = new ProcessBuilder();
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jstack");
@@ -69,6 +73,8 @@
launcher.addToolArg(Long.toString(ProcessTools.getProcessId()));
processBuilder.command(launcher.getCommand());
System.out.println(Arrays.toString(processBuilder.command().toArray()).replace(",", ""));
+ // Ensuring that Jstack will always run after NamedThread
+ latch.await();
OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
System.out.println(output.getOutput());
output.shouldContain("\""+ name + "\"");
--- a/hotspot/test/serviceability/tmtools/jstat/GcCapacityTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcCapacityTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -27,13 +27,13 @@
* @test
* @summary Test checks the consistency of the output
* displayed with jstat -gccapacity.
- * @ignore 8149778
* @library /test/lib/share/classes
* @library ../share
* @requires vm.opt.ExplicitGCInvokesConcurrent != true
* @build common.*
* @build utils.*
- * @run main/othervm -XX:+UsePerfData GcCapacityTest
+ * @ignore 8149778
+ * @run main/othervm -XX:+UsePerfData -Xmx128M GcCapacityTest
*/
public class GcCapacityTest {
--- a/hotspot/test/serviceability/tmtools/jstat/GcCauseTest01.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcCauseTest01.java Thu Apr 28 23:08:17 2016 -0700
@@ -34,7 +34,7 @@
* @build common.*
* @build utils.*
*
- * @run main/othervm -XX:+UsePerfData GcCauseTest01
+ * @run main/othervm -XX:+UsePerfData -Xmx128M GcCauseTest01
*/
import utils.*;
--- a/hotspot/test/serviceability/tmtools/jstat/GcCauseTest02.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcCauseTest02.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,7 @@
* @build common.*
* @build utils.*
*
- * @run main/othervm -XX:+UsePerfData -Xms128M -XX:MaxMetaspaceSize=128M GcCauseTest02
+ * @run main/othervm -XX:+UsePerfData -Xmx128M -XX:MaxMetaspaceSize=128M GcCauseTest02
*/
import utils.*;
--- a/hotspot/test/serviceability/tmtools/jstat/GcCauseTest03.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcCauseTest03.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,7 @@
* @build common.*
* @build utils.*
*
- * @run main/othervm -XX:+UsePerfData -Xms128M -XX:MaxMetaspaceSize=128M GcCauseTest03
+ * @run main/othervm -XX:+UsePerfData -Xmx128M -XX:MaxMetaspaceSize=128M GcCauseTest03
*/
import utils.*;
--- a/hotspot/test/serviceability/tmtools/jstat/GcNewTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcNewTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
* @library ../share
* @build common.*
* @build utils.*
- * @run main/othervm -XX:+UsePerfData GcNewTest
+ * @run main/othervm -XX:+UsePerfData -Xmx128M GcNewTest
*/
public class GcNewTest {
--- a/hotspot/test/serviceability/tmtools/jstat/GcTest01.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcTest01.java Thu Apr 28 23:08:17 2016 -0700
@@ -37,7 +37,7 @@
* @build common.*
* @build utils.*
*
- * @run main/othervm -XX:+UsePerfData GcTest01
+ * @run main/othervm -XX:+UsePerfData -Xmx128M GcTest01
*/
import utils.*;
--- a/hotspot/test/serviceability/tmtools/jstat/GcTest02.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcTest02.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,7 @@
* @library ../share
* @build common.*
* @build utils.*
- * @run main/othervm -XX:+UsePerfData -Xms128M -XX:MaxMetaspaceSize=128M GcTest02
+ * @run main/othervm -XX:+UsePerfData -Xmx128M -XX:MaxMetaspaceSize=128M GcTest02
*/
public class GcTest02 {
@@ -58,10 +58,4 @@
// Assert that space has been utilized acordingly
JstatResults.assertSpaceUtilization(measurement2, targetMemoryUsagePercent);
}
-
- private static void assertThat(boolean result, String message) {
- if (!result) {
- throw new RuntimeException(message);
- };
- }
}
--- a/hotspot/test/stress/gc/TestGCOld.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,417 +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 TestGCOld
- * @key gc
- * @key stress
- * @requires vm.gc=="null"
- * @summary Stress the GC by trying to make old objects more likely to be garbage than young objects.
- * @run main/othervm -Xmx384M -XX:+UseSerialGC TestGCOld 50 1 20 10 10000
- * @run main/othervm -Xmx384M -XX:+UseParallelGC TestGCOld 50 1 20 10 10000
- * @run main/othervm -Xmx384M -XX:+UseParallelGC -XX:-UseParallelOldGC TestGCOld 50 1 20 10 10000
- * @run main/othervm -Xmx384M -XX:+UseConcMarkSweepGC TestGCOld 50 1 20 10 10000
- * @run main/othervm -Xmx384M -XX:+UseG1GC TestGCOld 50 1 20 10 10000
- */
-
-import java.text.*;
-import java.util.Random;
-
-class TreeNode {
- public TreeNode left, right;
- public int val; // will always be the height of the tree
-}
-
-
-/* Args:
- live-data-size: in megabytes (approximate, will be rounded down).
- work: units of mutator non-allocation work per byte allocated,
- (in unspecified units. This will affect the promotion rate
- printed at the end of the run: more mutator work per step implies
- fewer steps per second implies fewer bytes promoted per second.)
- short/long ratio: ratio of short-lived bytes allocated to long-lived
- bytes allocated.
- pointer mutation rate: number of pointer mutations per step.
- steps: number of steps to do.
-*/
-
-public class TestGCOld {
-
- // Command-line parameters.
-
- private static int size, workUnits, promoteRate, ptrMutRate, steps;
-
- // Constants.
-
- private static final int MEG = 1000000;
- private static final int INSIGNIFICANT = 999; // this many bytes don't matter
- private static final int BYTES_PER_WORD = 4;
- private static final int BYTES_PER_NODE = 20; // bytes per TreeNode
- private static final int WORDS_DEAD = 100; // size of young garbage object
-
- private final static int treeHeight = 14;
- private final static long treeSize = heightToBytes(treeHeight);
-
- private static final String msg1
- = "Usage: java TestGCOld <size> <work> <ratio> <mutation> <steps>";
- private static final String msg2
- = " where <size> is the live storage in megabytes";
- private static final String msg3
- = " <work> is the mutator work per step (arbitrary units)";
- private static final String msg4
- = " <ratio> is the ratio of short-lived to long-lived allocation";
- private static final String msg5
- = " <mutation> is the mutations per step";
- private static final String msg6
- = " <steps> is the number of steps";
-
- // Counters (and global variables that discourage optimization)
-
- private static long youngBytes = 0; // total young bytes allocated
- private static long nodes = 0; // total tree nodes allocated
- private static long actuallyMut = 0; // pointer mutations in old trees
- private static long mutatorSum = 0; // checksum to discourage optimization
- public static int[] aexport; // exported array to discourage opt
-
- // Global variables.
-
- private static TreeNode[] trees;
- private static int where = 0; // roving index into trees
- private static Random rnd = new Random();
-
- // Returns the height of the given tree.
-
- private static int height (TreeNode t) {
- if (t == null) {
- return 0;
- }
- else {
- return 1 + Math.max (height (t.left), height (t.right));
- }
- }
-
- // Returns the length of the shortest path in the given tree.
-
- private static int shortestPath (TreeNode t) {
- if (t == null) {
- return 0;
- }
- else {
- return 1 + Math.min (shortestPath (t.left), shortestPath (t.right));
- }
- }
-
- // Returns the number of nodes in a balanced tree of the given height.
-
- private static long heightToNodes (int h) {
- if (h == 0) {
- return 0;
- }
- else {
- long n = 1;
- while (h > 1) {
- n = n + n;
- h = h - 1;
- }
- return n + n - 1;
- }
- }
-
- // Returns the number of bytes in a balanced tree of the given height.
-
- private static long heightToBytes (int h) {
- return BYTES_PER_NODE * heightToNodes (h);
- }
-
- // Returns the height of the largest balanced tree
- // that has no more than the given number of nodes.
-
- private static int nodesToHeight (long nodes) {
- int h = 1;
- long n = 1;
- while (n + n - 1 <= nodes) {
- n = n + n;
- h = h + 1;
- }
- return h - 1;
- }
-
- // Returns the height of the largest balanced tree
- // that occupies no more than the given number of bytes.
-
- private static int bytesToHeight (long bytes) {
- return nodesToHeight (bytes / BYTES_PER_NODE);
- }
-
- // Returns a newly allocated balanced binary tree of height h.
-
- private static TreeNode makeTree(int h) {
- if (h == 0) return null;
- else {
- TreeNode res = new TreeNode();
- nodes++;
- res.left = makeTree(h-1);
- res.right = makeTree(h-1);
- res.val = h;
- return res;
- }
- }
-
- // Allocates approximately size megabytes of trees and stores
- // them into a global array.
-
- private static void init() {
- int ntrees = (int) ((size * MEG) / treeSize);
- trees = new TreeNode[ntrees];
-
- System.err.println("Allocating " + ntrees + " trees.");
- System.err.println(" (" + (ntrees * treeSize) + " bytes)");
- for (int i = 0; i < ntrees; i++) {
- trees[i] = makeTree(treeHeight);
- // doYoungGenAlloc(promoteRate*ntrees*treeSize, WORDS_DEAD);
- }
- System.err.println(" (" + nodes + " nodes)");
-
- /* Allow any in-progress GC to catch up... */
- // try { Thread.sleep(20000); } catch (InterruptedException x) {}
- }
-
- // Confirms that all trees are balanced and have the correct height.
-
- private static void checkTrees() {
- int ntrees = trees.length;
- for (int i = 0; i < ntrees; i++) {
- TreeNode t = trees[i];
- int h1 = height(t);
- int h2 = shortestPath(t);
- if ((h1 != treeHeight) || (h2 != treeHeight)) {
- System.err.println("*****BUG: " + h1 + " " + h2);
- }
- }
- }
-
- // Called only by replaceTree (below) and by itself.
-
- private static void replaceTreeWork(TreeNode full, TreeNode partial, boolean dir) {
- boolean canGoLeft = full.left != null && full.left.val > partial.val;
- boolean canGoRight = full.right != null && full.right.val > partial.val;
- if (canGoLeft && canGoRight) {
- if (dir)
- replaceTreeWork(full.left, partial, !dir);
- else
- replaceTreeWork(full.right, partial, !dir);
- } else if (!canGoLeft && !canGoRight) {
- if (dir)
- full.left = partial;
- else
- full.right = partial;
- } else if (!canGoLeft) {
- full.left = partial;
- } else {
- full.right = partial;
- }
- }
-
- // Given a balanced tree full and a smaller balanced tree partial,
- // replaces an appropriate subtree of full by partial, taking care
- // to preserve the shape of the full tree.
-
- private static void replaceTree(TreeNode full, TreeNode partial) {
- boolean dir = (partial.val % 2) == 0;
- actuallyMut++;
- replaceTreeWork(full, partial, dir);
- }
-
- // Allocates approximately n bytes of long-lived storage,
- // replacing oldest existing long-lived storage.
-
- private static void oldGenAlloc(long n) {
- int full = (int) (n / treeSize);
- long partial = n % treeSize;
- // System.out.println("In oldGenAlloc, doing " + full + " full trees "
- // + "and one partial tree of size " + partial);
- for (int i = 0; i < full; i++) {
- trees[where++] = makeTree(treeHeight);
- if (where == trees.length) where = 0;
- }
- while (partial > INSIGNIFICANT) {
- int h = bytesToHeight(partial);
- TreeNode newTree = makeTree(h);
- replaceTree(trees[where++], newTree);
- if (where == trees.length) where = 0;
- partial = partial - heightToBytes(h);
- }
- }
-
- // Interchanges two randomly selected subtrees (of same size and depth).
-
- private static void oldGenSwapSubtrees() {
- // Randomly pick:
- // * two tree indices
- // * A depth
- // * A path to that depth.
- int index1 = rnd.nextInt(trees.length);
- int index2 = rnd.nextInt(trees.length);
- int depth = rnd.nextInt(treeHeight);
- int path = rnd.nextInt();
- TreeNode tn1 = trees[index1];
- TreeNode tn2 = trees[index2];
- for (int i = 0; i < depth; i++) {
- if ((path & 1) == 0) {
- tn1 = tn1.left;
- tn2 = tn2.left;
- } else {
- tn1 = tn1.right;
- tn2 = tn2.right;
- }
- path >>= 1;
- }
- TreeNode tmp;
- if ((path & 1) == 0) {
- tmp = tn1.left;
- tn1.left = tn2.left;
- tn2.left = tmp;
- } else {
- tmp = tn1.right;
- tn1.right = tn2.right;
- tn2.right = tmp;
- }
- actuallyMut += 2;
- }
-
- // Update "n" old-generation pointers.
-
- private static void oldGenMut(long n) {
- for (int i = 0; i < n/2; i++) {
- oldGenSwapSubtrees();
- }
- }
-
- // Does the amount of mutator work appropriate for n bytes of young-gen
- // garbage allocation.
-
- private static void doMutWork(long n) {
- int sum = 0;
- long limit = workUnits*n/10;
- for (long k = 0; k < limit; k++) sum++;
- // We don't want dead code elimination to eliminate the loop above.
- mutatorSum = mutatorSum + sum;
- }
-
- // Allocate n bytes of young-gen garbage, in units of "nwords"
- // words.
-
- private static void doYoungGenAlloc(long n, int nwords) {
- final int nbytes = nwords*BYTES_PER_WORD;
- int allocated = 0;
- while (allocated < n) {
- aexport = new int[nwords];
- /* System.err.println("Step"); */
- allocated += nbytes;
- }
- youngBytes = youngBytes + allocated;
- }
-
- // Allocate "n" bytes of young-gen data; and do the
- // corresponding amount of old-gen allocation and pointer
- // mutation.
-
- // oldGenAlloc may perform some mutations, so this code
- // takes those mutations into account.
-
- private static void doStep(long n) {
- long mutations = actuallyMut;
-
- doYoungGenAlloc(n, WORDS_DEAD);
- doMutWork(n);
- oldGenAlloc(n / promoteRate);
- oldGenMut(Math.max(0L, (mutations + ptrMutRate) - actuallyMut));
- }
-
- public static void main(String[] args) {
- if (args.length != 5) {
- System.err.println(msg1);
- System.err.println(msg2);
- System.err.println(msg3);
- System.err.println(msg4);
- System.err.println(msg5);
- System.err.println(msg6);
- return;
- }
-
- size = Integer.parseInt(args[0]);
- workUnits = Integer.parseInt(args[1]);
- promoteRate = Integer.parseInt(args[2]);
- ptrMutRate = Integer.parseInt(args[3]);
- steps = Integer.parseInt(args[4]);
-
- System.out.println(size + " megabytes of live storage");
- System.out.println(workUnits + " work units per step");
- System.out.println("promotion ratio is 1:" + promoteRate);
- System.out.println("pointer mutation rate is " + ptrMutRate);
- System.out.println(steps + " steps");
-
- init();
-// checkTrees();
- youngBytes = 0;
- nodes = 0;
-
- System.err.println("Initialization complete...");
-
- long start = System.currentTimeMillis();
-
- for (int step = 0; step < steps; step++) {
- doStep(MEG);
- }
-
- long end = System.currentTimeMillis();
- float secs = ((float)(end-start))/1000.0F;
-
-// checkTrees();
-
- NumberFormat nf = NumberFormat.getInstance();
- nf.setMaximumFractionDigits(1);
- System.out.println("\nTook " + nf.format(secs) + " sec in steady state.");
- nf.setMaximumFractionDigits(2);
- System.out.println("Allocated " + steps + " Mb of young gen garbage"
- + " (= " + nf.format(((float)steps)/secs) +
- " Mb/sec)");
- System.out.println(" (actually allocated " +
- nf.format(((float) youngBytes)/MEG) + " megabytes)");
- float promoted = ((float)steps) / (float)promoteRate;
- System.out.println("Promoted " + promoted +
- " Mb (= " + nf.format(promoted/secs) + " Mb/sec)");
- System.out.println(" (actually promoted " +
- nf.format(((float) (nodes * BYTES_PER_NODE))/MEG) +
- " megabytes)");
- if (ptrMutRate != 0) {
- System.out.println("Mutated " + actuallyMut +
- " pointers (= " +
- nf.format(actuallyMut/secs) + " ptrs/sec)");
-
- }
- // This output serves mainly to discourage optimization.
- System.out.println("Checksum = " + (mutatorSum + aexport.length));
-
- }
-}
--- a/hotspot/test/stress/gc/TestMultiThreadStressRSet.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,305 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import sun.hotspot.WhiteBox;
-
-/*
- * @test TestMultiThreadStressRSet.java
- * @key stress
- * @requires vm.gc=="G1" | vm.gc=="null"
- * @requires os.maxMemory > 2G
- *
- * @summary Stress G1 Remembered Set using multiple threads
- * @library /test/lib /testlibrary
- * @build sun.hotspot.WhiteBox
- * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
- * -XX:+UseG1GC -XX:G1SummarizeRSetStatsPeriod=1 -Xlog:gc
- * -Xmx500m -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestMultiThreadStressRSet 10 4
- *
- * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
- * -XX:+UseG1GC -XX:G1SummarizeRSetStatsPeriod=100 -Xlog:gc
- * -Xmx1G -XX:G1HeapRegionSize=8m -XX:MaxGCPauseMillis=1000 TestMultiThreadStressRSet 60 16
- *
- * @run main/othervm/timeout=700 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
- * -XX:+UseG1GC -XX:G1SummarizeRSetStatsPeriod=100 -Xlog:gc
- * -Xmx500m -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestMultiThreadStressRSet 600 32
- */
-public class TestMultiThreadStressRSet {
-
- private static final Random RND = new Random(2015 * 2016);
- private static final WhiteBox WB = WhiteBox.getWhiteBox();
- private static final int REF_SIZE = WB.getHeapOopSize();
- private static final int REGION_SIZE = WB.g1RegionSize();
-
- // How many regions to use for the storage
- private static final int STORAGE_REGIONS = 20;
-
- // Size a single obj in the storage
- private static final int OBJ_SIZE = 1024;
-
- // How many regions of young/old gen to use in the BUFFER
- private static final int BUFFER_YOUNG_REGIONS = 60;
- private static final int BUFFER_OLD_REGIONS = 40;
-
- // Total number of objects in the storage.
- private final int N;
-
- // The storage of byte[]
- private final List<Object> STORAGE;
-
- // Where references to the Storage will be stored
- private final List<Object[]> BUFFER;
-
- // The length of a buffer element.
- // RSet deals with "cards" (areas of 512 bytes), not with single refs
- // So, to affect the RSet the BUFFER refs should be allocated in different
- // memory cards.
- private final int BUF_ARR_LEN = 100 * (512 / REF_SIZE);
-
- // Total number of objects in the young/old buffers
- private final int YOUNG;
- private final int OLD;
-
- // To cause Remembered Sets change their coarse level the test uses a window
- // within STORAGE. All the BUFFER elements refer to only STORAGE objects
- // from the current window. The window is defined by a range.
- // The first element has got the index: 'windowStart',
- // the last one: 'windowStart + windowSize - 1'
- // The window is shifting periodically.
- private int windowStart;
- private final int windowSize;
-
- // Counter of created worker threads
- private int counter = 0;
-
- private volatile String errorMessage = null;
- private volatile boolean isEnough = false;
-
- public static void main(String args[]) {
- if (args.length != 2) {
- throw new IllegalArgumentException("TEST BUG: wrong arg count " + args.length);
- }
- long time = Long.parseLong(args[0]);
- int threads = Integer.parseInt(args[1]);
- new TestMultiThreadStressRSet().test(time * 1000, threads);
- }
-
- /**
- * Initiates test parameters, fills out the STORAGE and BUFFER.
- */
- public TestMultiThreadStressRSet() {
-
- N = (REGION_SIZE - 1) * STORAGE_REGIONS / OBJ_SIZE + 1;
- STORAGE = new ArrayList<>(N);
- int bytes = OBJ_SIZE - 20;
- for (int i = 0; i < N - 1; i++) {
- STORAGE.add(new byte[bytes]);
- }
- STORAGE.add(new byte[REGION_SIZE / 2 + 100]); // humongous
- windowStart = 0;
- windowSize = REGION_SIZE / OBJ_SIZE;
-
- BUFFER = new ArrayList<>();
- int sizeOfBufferObject = 20 + REF_SIZE * BUF_ARR_LEN;
- OLD = REGION_SIZE * BUFFER_OLD_REGIONS / sizeOfBufferObject;
- YOUNG = REGION_SIZE * BUFFER_YOUNG_REGIONS / sizeOfBufferObject;
- for (int i = 0; i < OLD + YOUNG; i++) {
- BUFFER.add(new Object[BUF_ARR_LEN]);
- }
- }
-
- /**
- * Does the testing. Steps:
- * <ul>
- * <li> starts the Shifter thread
- * <li> during the given time starts new Worker threads, keeping the number
- * of live thread under limit.
- * <li> stops the Shifter thread
- * </ul>
- *
- * @param timeInMillis how long to stress
- * @param maxThreads the maximum number of Worker thread working together.
- */
- public void test(long timeInMillis, int maxThreads) {
- if (timeInMillis <= 0 || maxThreads <= 0) {
- throw new IllegalArgumentException("TEST BUG: be positive!");
- }
- System.out.println("%% Time to work: " + timeInMillis / 1000 + "s");
- System.out.println("%% Number of threads: " + maxThreads);
- long finish = System.currentTimeMillis() + timeInMillis;
- Shifter shift = new Shifter(this, 1000, (int) (windowSize * 0.9));
- shift.start();
- for (int i = 0; i < maxThreads; i++) {
- new Worker(this, 100).start();
- }
- try {
- while (System.currentTimeMillis() < finish && errorMessage == null) {
- Thread.sleep(100);
- }
- } catch (Throwable t) {
- printAllStackTraces(System.err);
- t.printStackTrace(System.err);
- this.errorMessage = t.getMessage();
- } finally {
- isEnough = true;
- }
- System.out.println("%% Total work cycles: " + counter);
- if (errorMessage != null) {
- throw new RuntimeException(errorMessage);
- }
- }
-
- /**
- * Returns an element from from the BUFFER (an object array) to keep
- * references to the storage.
- *
- * @return an Object[] from buffer.
- */
- private Object[] getFromBuffer() {
- int index = counter % (OLD + YOUNG);
- synchronized (BUFFER) {
- if (index < OLD) {
- if (counter % 100 == (counter / 100) % 100) {
- // need to generate garbage in the old gen to provoke mixed GC
- return replaceInBuffer(index);
- } else {
- return BUFFER.get(index);
- }
- } else {
- return replaceInBuffer(index);
- }
- }
- }
-
- private Object[] replaceInBuffer(int index) {
- Object[] objs = new Object[BUF_ARR_LEN];
- BUFFER.set(index, objs);
- return objs;
- }
-
- /**
- * Returns a random object from the current window within the storage.
- * A storage element with index from windowStart to windowStart+windowSize.
- *
- * @return a random element from the current window within the storage.
- */
- private Object getRandomObject() {
- int index = (windowStart + RND.nextInt(windowSize)) % N;
- return STORAGE.get(index);
- }
-
- private static void printAllStackTraces(PrintStream ps) {
- Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
- for (Thread t : traces.keySet()) {
- ps.println(t.toString() + " " + t.getState());
- for (StackTraceElement traceElement : traces.get(t)) {
- ps.println("\tat " + traceElement);
- }
- }
- }
-
- /**
- * Thread to create a number of references from BUFFER to STORAGE.
- */
- private static class Worker extends Thread {
-
- final TestMultiThreadStressRSet boss;
- final int refs; // number of refs to OldGen
-
- /**
- * @param boss the tests
- * @param refsToOldGen how many references to the OldGen to create
- */
- Worker(TestMultiThreadStressRSet boss, int refsToOldGen) {
- this.boss = boss;
- this.refs = refsToOldGen;
- }
-
- @Override
- public void run() {
- try {
- while (!boss.isEnough) {
- Object[] objs = boss.getFromBuffer();
- int step = objs.length / refs;
- for (int i = 0; i < refs; i += step) {
- objs[i] = boss.getRandomObject();
- }
- boss.counter++;
- }
- } catch (Throwable t) {
- t.printStackTrace(System.out);
- boss.errorMessage = t.getMessage();
- }
- }
- }
-
- /**
- * Periodically shifts the current STORAGE window, removing references
- * in BUFFER that refer to objects outside the window.
- */
- private static class Shifter extends Thread {
-
- final TestMultiThreadStressRSet boss;
- final int sleepTime;
- final int shift;
-
- Shifter(TestMultiThreadStressRSet boss, int sleepTime, int shift) {
- this.boss = boss;
- this.sleepTime = sleepTime;
- this.shift = shift;
- }
-
- @Override
- public void run() {
- try {
- while (!boss.isEnough) {
- Thread.sleep(sleepTime);
- boss.windowStart += shift;
- for (int i = 0; i < boss.OLD; i++) {
- Object[] objs = boss.BUFFER.get(i);
- for (int j = 0; j < objs.length; j++) {
- objs[j] = null;
- }
- }
- if (!WB.g1InConcurrentMark()) {
- System.out.println("%% start CMC");
- WB.g1StartConcMarkCycle();
- } else {
- System.out.println("%% CMC is already in progress");
- }
- }
- } catch (Throwable t) {
- t.printStackTrace(System.out);
- boss.errorMessage = t.getMessage();
- }
- }
- }
-}
-
--- a/hotspot/test/stress/gc/TestStressIHOPMultiThread.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
- /*
- * @test TestStressIHOPMultiThread
- * @bug 8148397
- * @key stress
- * @summary Stress test for IHOP
- * @requires vm.gc=="G1" | vm.gc=="null"
- * @run main/othervm/timeout=200 -Xmx128m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
- * -XX:+UseG1GC -XX:G1HeapRegionSize=1m -XX:+G1UseAdaptiveIHOP
- * -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread1.log
- * -Dtimeout=2 -DheapUsageMinBound=30 -DheapUsageMaxBound=80
- * -Dthreads=2 TestStressIHOPMultiThread
- * @run main/othervm/timeout=200 -Xmx256m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
- * -XX:+UseG1GC -XX:G1HeapRegionSize=2m -XX:+G1UseAdaptiveIHOP
- * -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread2.log
- * -Dtimeout=2 -DheapUsageMinBound=60 -DheapUsageMaxBound=90
- * -Dthreads=3 TestStressIHOPMultiThread
- * @run main/othervm/timeout=200 -Xmx256m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
- * -XX:+UseG1GC -XX:G1HeapRegionSize=4m -XX:-G1UseAdaptiveIHOP
- * -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread3.log
- * -Dtimeout=2 -DheapUsageMinBound=40 -DheapUsageMaxBound=90
- * -Dthreads=5 TestStressIHOPMultiThread
- * @run main/othervm/timeout=200 -Xmx128m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
- * -XX:+UseG1GC -XX:G1HeapRegionSize=8m -XX:+G1UseAdaptiveIHOP
- * -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread4.log
- * -Dtimeout=2 -DheapUsageMinBound=20 -DheapUsageMaxBound=90
- * -Dthreads=10 TestStressIHOPMultiThread
- * @run main/othervm/timeout=200 -Xmx512m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
- * -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:+G1UseAdaptiveIHOP
- * -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread5.log
- * -Dtimeout=2 -DheapUsageMinBound=20 -DheapUsageMaxBound=90
- * -Dthreads=17 TestStressIHOPMultiThread
- */
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Stress test for Adaptive IHOP. Starts a number of threads that fill and free
- * specified amount of memory. Tests work with enabled IHOP logging.
- *
- */
-public class TestStressIHOPMultiThread {
-
- public final static List<Object> GARBAGE = new LinkedList<>();
-
- private final long HEAP_SIZE;
- // Amount of memory to be allocated before iterations start
- private final long HEAP_PREALLOC_SIZE;
- // Amount of memory to be allocated and freed during iterations
- private final long HEAP_ALLOC_SIZE;
- private final int CHUNK_SIZE = 100000;
-
- private final int TIMEOUT;
- private final int THREADS;
- private final int HEAP_LOW_BOUND;
- private final int HEAP_HIGH_BOUND;
-
- private volatile boolean running = true;
- private final List<AllocationThread> threads;
-
- public static void main(String[] args) throws InterruptedException {
- new TestStressIHOPMultiThread().start();
-
- }
-
- TestStressIHOPMultiThread() {
-
- TIMEOUT = Integer.getInteger("timeout") * 60;
- THREADS = Integer.getInteger("threads");
- HEAP_LOW_BOUND = Integer.getInteger("heapUsageMinBound");
- HEAP_HIGH_BOUND = Integer.getInteger("heapUsageMaxBound");
- HEAP_SIZE = Runtime.getRuntime().maxMemory();
-
- HEAP_PREALLOC_SIZE = HEAP_SIZE * HEAP_LOW_BOUND / 100;
- HEAP_ALLOC_SIZE = HEAP_SIZE * (HEAP_HIGH_BOUND - HEAP_LOW_BOUND) / 100;
-
- threads = new ArrayList<>(THREADS);
- }
-
- public void start() throws InterruptedException {
- fill();
- createThreads();
- waitForStress();
- stressDone();
- waitForFinish();
- }
-
- /**
- * Fills HEAP_PREALLOC_SIZE bytes of garbage.
- */
- private void fill() {
- long allocated = 0;
- while (allocated < HEAP_PREALLOC_SIZE) {
- GARBAGE.add(new byte[CHUNK_SIZE]);
- allocated += CHUNK_SIZE;
- }
- }
-
- /**
- * Creates a number of threads which will fill and free amount of memory.
- */
- private void createThreads() {
- for (int i = 0; i < THREADS; ++i) {
- System.out.println("Create thread " + i);
- AllocationThread thread =new TestStressIHOPMultiThread.AllocationThread(i, HEAP_ALLOC_SIZE / THREADS);
- // Put reference to thread garbage into common garbage for avoiding possible optimization.
- GARBAGE.add(thread.getList());
- threads.add(thread);
- }
- threads.forEach(t -> t.start());
- }
-
- /**
- * Wait each thread for finishing
- */
- private void waitForFinish() {
- threads.forEach(thread -> {
- thread.silentJoin();
- });
- }
-
- private boolean isRunning() {
- return running;
- }
-
- private void stressDone() {
- running = false;
- }
-
- private void waitForStress() throws InterruptedException {
- Thread.sleep(TIMEOUT * 1000);
- }
-
- private class AllocationThread extends Thread {
-
- private final List<Object> garbage;
-
- private final long amountOfGarbage;
- private final int threadId;
-
- public AllocationThread(int id, long amount) {
- super("Thread " + id);
- threadId = id;
- amountOfGarbage = amount;
- garbage = new LinkedList<>();
- }
-
- /**
- * Returns list of garbage.
- * @return List with thread garbage.
- */
- public List<Object> getList(){
- return garbage;
- }
-
- @Override
- public void run() {
- System.out.println("Start the thread " + threadId);
- while (TestStressIHOPMultiThread.this.isRunning()) {
- allocate(amountOfGarbage);
- free();
- }
- }
-
- private void silentJoin() {
- System.out.println("Join the thread " + threadId);
- try {
- join();
- } catch (InterruptedException ie) {
- throw new RuntimeException(ie);
- }
- }
-
- /**
- * Allocates thread local garbage
- */
- private void allocate(long amount) {
- long allocated = 0;
- while (allocated < amount && TestStressIHOPMultiThread.this.isRunning()) {
- garbage.add(new byte[CHUNK_SIZE]);
- allocated += CHUNK_SIZE;
- }
- }
-
- /**
- * Frees thread local garbage
- */
- private void free() {
- garbage.clear();
- }
- }
-}
--- a/hotspot/test/stress/gc/TestStressRSetCoarsening.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,335 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.util.concurrent.TimeoutException;
-import sun.hotspot.WhiteBox;
-
-/*
- * @test TestStressRSetCoarsening.java
- * @key stress
- * @bug 8146984 8147087
- * @requires vm.gc=="G1" | vm.gc=="null"
- * @requires os.maxMemory > 3G
- *
- * @summary Stress G1 Remembered Set by creating a lot of cross region links
- * @modules java.base/jdk.internal.misc
- * @library /testlibrary /test/lib
- * @build sun.hotspot.WhiteBox
- * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm/timeout=300
- * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC
- * -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGC -XX:+PrintGCTimeStamps -Xlog:gc
- * -Xmx500m -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestStressRSetCoarsening 1 0 300
- * @run main/othervm/timeout=300
- * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC
- * -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGC -XX:+PrintGCTimeStamps -Xlog:gc
- * -Xmx500m -XX:G1HeapRegionSize=8m -XX:MaxGCPauseMillis=1000 TestStressRSetCoarsening 1 10 300
- * @run main/othervm/timeout=300
- * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC
- * -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGC -XX:+PrintGCTimeStamps -Xlog:gc
- * -Xmx500m -XX:G1HeapRegionSize=32m -XX:MaxGCPauseMillis=1000 TestStressRSetCoarsening 42 10 300
- * @run main/othervm/timeout=300
- * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC
- * -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGC -XX:+PrintGCTimeStamps -Xlog:gc
- * -Xmx500m -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestStressRSetCoarsening 2 0 300
- * @run main/othervm/timeout=1800
- * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC
- * -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGC -XX:+PrintGCTimeStamps -Xlog:gc
- * -Xmx1G -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestStressRSetCoarsening 500 0 1800
- * @run main/othervm/timeout=1800
- * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC
- * -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGC -XX:+PrintGCTimeStamps -Xlog:gc
- * -Xmx1G -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestStressRSetCoarsening 10 10 1800
- */
-
-/**
- * What the test does.
- * Preparation stage:
- * Fill out ~90% of the heap with objects, each object is an object array.
- * If we want to allocate K objects per region, we calculate N to meet:
- * sizeOf(Object[N]) ~= regionSize / K
- * Stress stage:
- * No more allocation, so no more GC.
- * We will perform a number of iterations. On each iteration i,
- * for each pair of regions Rx and Ry we will set c[i] references
- * from Rx to Ry. If c[i] less than c[i-1] at the end of iteration
- * concurrent mark cycle will be initiated (to recalculate remembered sets).
- * As the result RSet will be growing up and down, up and down many times.
- *
- * The test expects: no crash and no timeouts.
- *
- * Test Parameters:
- * args[0] - number of objects per Heap Region (1 - means humongous)
- * args[1] - number of regions to refresh to provoke GC at the end of cycle.
- * (0 - means no GC, i.e. no reading from RSet)
- * args[2] - timeout in seconds (to stop execution to avoid jtreg timeout)
- */
-public class TestStressRSetCoarsening {
-
- public static void main(String... args) throws InterruptedException {
- if (args.length != 3) {
- throw new IllegalArgumentException("Wrong number of arguments " + args.length);
- }
- int objectsPerRegion = Integer.parseInt(args[0]); // 1 means humongous
- int regsToRefresh = Integer.parseInt(args[1]); // 0 means no regions to refresh at the end of cycle
- int timeout = Integer.parseInt(args[2]); // in seconds, test should stop working eariler
- new TestStressRSetCoarsening(objectsPerRegion, regsToRefresh, timeout).go();
- }
-
- private static final long KB = 1024;
- private static final long MB = 1024 * KB;
-
- private static final WhiteBox WB = WhiteBox.getWhiteBox();
-
- public final Object[][] storage;
-
- /**
- * Number of objects per region. This is a test parameter.
- */
- public final int K;
-
- /**
- * Length of object array: sizeOf(Object[N]) ~= regionSize / K
- * N will be calculated as function of K.
- */
- public final int N;
-
- /**
- * How many regions involved into testing.
- * Will be calculated as heapFractionToAllocate * freeRegionCount.
- */
- public final int regionCount;
-
- /**
- * How much heap to use.
- */
- public final float heapFractionToAllocate = 0.9f;
-
- /**
- * How many regions to be refreshed at the end of cycle.
- * This is a test parameter.
- */
- public final int regsToRefresh;
-
- /**
- * Initial time.
- */
- public final long start;
-
- /**
- * Time when the test should stop working.
- */
- public final long finishAt;
-
- /**
- * Does pre-calculation and allocate necessary objects.
- *
- * @param objPerRegions how many objects per G1 heap region
- */
- TestStressRSetCoarsening(int objPerRegions, int regsToRefresh, int timeout) {
- this.K = objPerRegions;
- this.regsToRefresh = regsToRefresh;
- this.start = System.currentTimeMillis();
- this.finishAt = start + timeout * 900; // 10% ahead of jtreg timeout
-
- long regionSize = WB.g1RegionSize();
-
- // How many free regions
- Runtime rt = Runtime.getRuntime();
- long used = rt.totalMemory() - rt.freeMemory();
- long totalFree = rt.maxMemory() - used;
- regionCount = (int) ((totalFree / regionSize) * heapFractionToAllocate);
- long toAllocate = regionCount * regionSize;
- System.out.println("%% Test parameters");
- System.out.println("%% Objects per region : " + K);
- System.out.println("%% Heap fraction to allocate : " + (int) (heapFractionToAllocate * 100) + "%");
- System.out.println("%% Regions to refresh to provoke GC: " + regsToRefresh);
-
- System.out.println("%% Memory");
- System.out.println("%% used : " + used / MB + "M");
- System.out.println("%% available : " + totalFree / MB + "M");
- System.out.println("%% to allocate : " + toAllocate / MB + "M");
- System.out.println("%% (in regs) : " + regionCount);
- System.out.println("%% G1 Region Size: " + regionSize / MB + "M");
-
- int refSize = WB.getHeapOopSize();
-
- // Calculate N: K*sizeOf(Object[N]) ~= regionSize
- // sizeOf(Object[N]) ~= (N+4)*refSize
- // ==>
- // N = regionSize / K / refSize - 4;
- N = (int) ((regionSize / K) / refSize) - 5;
-
- /*
- * --------------
- * region0 storage[0] = new Object[N]
- * ...
- * storage[K-1] = new Object[N]
- * ---------------
- * region1 storage[K] = new Object[N]
- * ...
- * storage[2*K - 1] = new Object[N]
- * --------------
- * ...
- * --------------
- * regionX storage[X*K] = new Object[N]
- * ...
- * storage[(X+1)*K -1] = new Object[N]
- * where X = HeapFraction * TotalRegions
- * -------------
- */
- System.out.println("%% Objects");
- System.out.println("%% N (array length) : " + N);
- System.out.println("%% K (objects in regions): " + K);
- System.out.println("%% Reference size : " + refSize);
- System.out.println("%% Approximate obj size : " + (N + 2) * refSize / KB + "K)");
-
- storage = new Object[regionCount * K][];
- for (int i = 0; i < storage.length; i++) {
- storage[i] = new Object[N];
- }
- }
-
- public void go() throws InterruptedException {
- // threshold for sparce -> fine
- final int FINE = WB.getIntxVMFlag("G1RSetSparseRegionEntries").intValue();
-
- // threshold for fine -> coarse
- final int COARSE = WB.getIntxVMFlag("G1RSetRegionEntries").intValue();
-
- // regToRegRefCounts - array of reference counts from region to region
- // at the the end of iteration.
- // The number of test iterations is array length - 1.
- // If c[i] > c[i-1] then during the iteration i more references will
- // be created.
- // If c[i] < c[i-1] then some referenes will be cleaned.
- int[] regToRegRefCounts = {0, FINE / 2, 0, FINE, (FINE + COARSE) / 2, 0,
- COARSE, COARSE + 10, FINE + 1, FINE / 2, 0};
-
- // For progress tracking
- int[] progress = new int[regToRegRefCounts.length];
- progress[0] = 0;
- for (int i = 1; i < regToRegRefCounts.length; i++) {
- progress[i] = progress[i - 1] + Math.abs(regToRegRefCounts[i] - regToRegRefCounts[i - 1]);
- }
- try {
- for (int i = 1; i < regToRegRefCounts.length; i++) {
- int pre = regToRegRefCounts[i - 1];
- int cur = regToRegRefCounts[i];
- float prog = ((float) progress[i - 1] / progress[progress.length - 1]);
-
- System.out.println("%% step " + i
- + " out of " + (regToRegRefCounts.length - 1)
- + " (~" + (int) (100 * prog) + "% done)");
- System.out.println("%% " + pre + " --> " + cur);
- for (int to = 0; to < regionCount; to++) {
- // Select a celebrity object that we will install references to.
- // The celebrity will be referred from all other regions.
- // If the number of references after should be less than they
- // were before, select NULL.
- Object celebrity = cur > pre ? storage[to * K] : null;
- for (int from = 0; from < regionCount; from++) {
- if (to == from) {
- continue; // no need to refer to itself
- }
-
- int step = cur > pre ? +1 : -1;
- for (int rn = pre; rn != cur; rn += step) {
- storage[getY(to, from, rn)][getX(to, from, rn)] = celebrity;
- if (System.currentTimeMillis() > finishAt) {
- throw new TimeoutException();
- }
- }
- }
- }
- if (pre > cur) {
- // Number of references went down.
- // Need to provoke recalculation of RSet.
- WB.g1StartConcMarkCycle();
- while (WB.g1InConcurrentMark()) {
- Thread.sleep(1);
- }
- }
-
- // To force the use of rememebered set entries we need to provoke a GC.
- // To induce some fragmentation, and some mixed GCs, we need
- // to make a few objects unreachable.
- for (int toClean = i * regsToRefresh; toClean < (i + 1) * regsToRefresh; toClean++) {
- int to = toClean % regionCount;
- // Need to remove all references from all regions to the region 'to'
- for (int from = 0; from < regionCount; from++) {
- if (to == from) {
- continue; // no need to refer to itself
- }
- for (int rn = 0; rn <= cur; rn++) {
- storage[getY(to, from, rn)][getX(to, from, rn)] = null;
- }
- }
- // 'Refresh' storage elements for the region 'to'
- // After that loop all 'old' objects in the region 'to'
- // should become unreachable.
- for (int k = 0; k < K; k++) {
- storage[(to * K + k) % storage.length] = new Object[N];
- }
- }
- }
- } catch (TimeoutException e) {
- System.out.println("%% TIMEOUT!!!");
- }
- long now = System.currentTimeMillis();
- System.out.println("%% Summary");
- System.out.println("%% Time spent : " + ((now - start) / 1000) + " seconds");
- System.out.println("%% Free memory left : " + Runtime.getRuntime().freeMemory() / KB + "K");
- System.out.println("%% Test passed");
- }
-
- /**
- * Returns X index in the Storage of the reference #rn from the region
- * 'from' to the region 'to'.
- *
- * @param to region # to refer to
- * @param from region # to refer from
- * @param rn number of reference
- *
- * @return X index in the range: [0 ... N-1]
- */
- private int getX(int to, int from, int rn) {
- return (rn * regionCount + to) % N;
- }
-
- /**
- * Returns Y index in the Storage of the reference #rn from the region
- * 'from' to the region 'to'.
- *
- * @param to region # to refer to
- * @param from region # to refer from
- * @param rn number of reference
- *
- * @return Y index in the range: [0 ... K*regionCount -1]
- */
- private int getY(int to, int from, int rn) {
- return ((rn * regionCount + to) / N + from * K) % (regionCount * K);
- }
-}
-
--- a/hotspot/test/testlibrary/jdk/test/lib/OutputAnalyzer.java Thu Apr 28 00:38:21 2016 -0700
+++ b/hotspot/test/testlibrary/jdk/test/lib/OutputAnalyzer.java Thu Apr 28 23:08:17 2016 -0700
@@ -378,14 +378,14 @@
* - exit code
* Note: the command line is printed by the ProcessTools
*/
- private void reportDiagnosticSummary() {
- String msg =
- " stdout: [" + stdout + "];\n" +
- " stderr: [" + stderr + "]\n" +
- " exitValue = " + getExitValue() + "\n";
+ public void reportDiagnosticSummary() {
+ String msg =
+ " stdout: [" + stdout + "];\n" +
+ " stderr: [" + stderr + "]\n" +
+ " exitValue = " + getExitValue() + "\n";
- System.err.println(msg);
- }
+ System.err.println(msg);
+ }
/**
--- a/jaxp/.hgtags Thu Apr 28 00:38:21 2016 -0700
+++ b/jaxp/.hgtags Thu Apr 28 23:08:17 2016 -0700
@@ -357,3 +357,4 @@
36326537f929d20cc5885b93939f90c0efcc4681 jdk-9+112
28626780e245fccbfb9bad8e3b05f62357958038 jdk-9+113
147114dd0641cd7c9fe6e81642eb993a7b9c6f0b jdk-9+114
+1902a5bda18e794b31fc5f520f5e7d827714b50d jdk-9+115
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,15 +1,16 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * Copyright 2005 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -24,7 +25,6 @@
import com.sun.org.apache.xerces.internal.util.XML11Char;
import com.sun.org.apache.xerces.internal.util.XMLChar;
import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
-import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager.Limit;
import com.sun.org.apache.xerces.internal.xni.QName;
import com.sun.org.apache.xerces.internal.xni.XMLString;
@@ -815,7 +815,7 @@
load(0, true, true);
}
else if (fCurrentEntity.position == fCurrentEntity.count - 1) {
- invokeListeners(0);
+ invokeListeners(1);
fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1];
load(1, false, false);
fCurrentEntity.position = 0;
@@ -960,7 +960,7 @@
load(0, true, true);
}
else if (fCurrentEntity.position == fCurrentEntity.count - 1) {
- invokeListeners(0);
+ invokeListeners(1);
fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1];
load(1, false, false);
fCurrentEntity.startPosition = 0;
@@ -1397,7 +1397,7 @@
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count - 1) {
- invokeListeners(0);
+ invokeListeners(1);
fCurrentEntity.ch[0] = (char)c;
entityChanged = load(1, true, false);
if (!entityChanged) {
@@ -1446,8 +1446,9 @@
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count - 1) {
+ invokeListeners(1);
fCurrentEntity.ch[0] = (char)c;
- entityChanged = load(1, true, true);
+ entityChanged = load(1, true, false);
if (!entityChanged) {
// the load change the position to be 1,
// need to restore it when entity not changed
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -3,13 +3,14 @@
*/
/*
- * Copyright 2005 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -19,17 +20,17 @@
*/
package com.sun.org.apache.xerces.internal.impl;
-import com.sun.xml.internal.stream.dtd.nonvalidating.DTDGrammar;
-import java.io.EOFException;
-import java.io.IOException;
+import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
-
+import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
+import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl;
import com.sun.org.apache.xerces.internal.util.XMLChar;
import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
-
+import com.sun.org.apache.xerces.internal.utils.XMLLimitAnalyzer;
+import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler;
import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
@@ -41,11 +42,9 @@
import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDScanner;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
import com.sun.org.apache.xerces.internal.xni.Augmentations;
-import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
-import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler;
-import com.sun.org.apache.xerces.internal.impl.Constants;
-import com.sun.org.apache.xerces.internal.utils.XMLLimitAnalyzer;
-import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
+import com.sun.xml.internal.stream.dtd.nonvalidating.DTDGrammar;
+import java.io.EOFException;
+import java.io.IOException;
/**
* This class is responsible for scanning the declarations found
@@ -387,15 +386,25 @@
*/
@Override
public boolean skipDTD(boolean supportDTD) throws IOException {
- if (!supportDTD) {
- fStringBuffer.clear();
- if (!fEntityScanner.scanData("]", fStringBuffer)) {
- fEntityScanner.fCurrentEntity.position--;
+ if (supportDTD)
+ return false;
+
+ fStringBuffer.clear();
+ while (fEntityScanner.scanData("]", fStringBuffer)) {
+ int c = fEntityScanner.peekChar();
+ if (c != -1) {
+ if (XMLChar.isHighSurrogate(c)) {
+ scanSurrogates(fStringBuffer);
+ }
+ if (isInvalidLiteral(c)) {
+ reportFatalError("InvalidCharInDTD",
+ new Object[] { Integer.toHexString(c) });
+ fEntityScanner.scanChar();
+ }
}
-
- return true;
}
- return false;
+ fEntityScanner.fCurrentEntity.position--;
+ return true;
}
//
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -3,13 +3,14 @@
*/
/*
- * Copyright 2005 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -18,7 +19,6 @@
* limitations under the License.
*/
-
package com.sun.org.apache.xerces.internal.impl;
import com.sun.xml.internal.stream.XMLBufferListener;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -3,13 +3,14 @@
*/
/*
- * Copyright 2005 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -20,7 +21,6 @@
package com.sun.org.apache.xerces.internal.impl;
-
import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDDescription;
import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
@@ -1106,8 +1106,7 @@
if (!moreToScan) {
// end doctype declaration
if (!fEntityScanner.skipChar(']')) {
- reportFatalError("EXPECTED_SQUARE_BRACKET_TO_CLOSE_INTERNAL_SUBSET",
- null);
+ reportFatalError("DoctypedeclNotClosed", new Object[]{fDoctypeName});
}
fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('>')) {
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,15 +1,16 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * Copyright 2005 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -20,8 +21,6 @@
package com.sun.org.apache.xerces.internal.impl;
-
-
import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader;
import com.sun.org.apache.xerces.internal.impl.io.UCSReader;
import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader;
@@ -44,8 +43,8 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
+import java.util.ArrayList;
import java.util.Locale;
-import java.util.Vector;
/**
* Implements the entity scanner methods.
@@ -58,11 +57,10 @@
*/
public class XMLEntityScanner implements XMLLocator {
-
- protected Entity.ScannedEntity fCurrentEntity = null ;
+ protected Entity.ScannedEntity fCurrentEntity = null;
protected int fBufferSize = XMLEntityManager.DEFAULT_BUFFER_SIZE;
- protected XMLEntityManager fEntityManager ;
+ protected XMLEntityManager fEntityManager;
/** Security manager. */
protected XMLSecurityManager fSecurityManager = null;
@@ -72,8 +70,9 @@
/** Debug switching readers for encodings. */
private static final boolean DEBUG_ENCODINGS = false;
+
/** Listeners which should know when load is being called */
- private Vector listeners = new Vector();
+ private ArrayList<XMLBufferListener> listeners = new ArrayList<>();
private static final boolean [] VALID_NAMES = new boolean[127];
@@ -140,9 +139,11 @@
VALID_NAMES[58]=true;
VALID_NAMES[95]=true;
}
- // SAPJVM: Remember, that the XML version has explicitly been set,
+
+ // Remember, that the XML version has explicitly been set,
// so that XMLStreamReader.getVersion() can find that out.
- boolean xmlVersionSetExplicitly = false;
+ protected boolean xmlVersionSetExplicitly = false;
+
//
// Constructors
//
@@ -257,7 +258,7 @@
* @param xmlVersion the XML version of the current entity
*/
public final void setXMLVersion(String xmlVersion) {
- xmlVersionSetExplicitly = true; // SAPJVM
+ xmlVersionSetExplicitly = true;
fCurrentEntity.xmlVersion = xmlVersion;
} // setXMLVersion(String)
@@ -546,8 +547,7 @@
// scan character
int c = fCurrentEntity.ch[fCurrentEntity.position++];
- if (c == '\n' ||
- (c == '\r' && isExternal)) {
+ if (c == '\n' || (c == '\r' && isExternal)) {
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count) {
@@ -953,7 +953,7 @@
if (fCurrentEntity.position == fCurrentEntity.count) {
load(0, true, true);
} else if (fCurrentEntity.position == fCurrentEntity.count - 1) {
- invokeListeners(0);
+ invokeListeners(1);
fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1];
load(1, false, false);
fCurrentEntity.position = 0;
@@ -1105,7 +1105,7 @@
if (fCurrentEntity.position == fCurrentEntity.count) {
load(0, true, true);
} else if (fCurrentEntity.position == fCurrentEntity.count - 1) {
- invokeListeners(0);
+ invokeListeners(1);
fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1];
load(1, false, false);
fCurrentEntity.position = 0;
@@ -1256,8 +1256,8 @@
* <p>
* <strong>Note:</strong> The characters are consumed.
* <p>
- * <strong>Note:</strong> This assumes that the length of the delimiter
- * and that the delimiter contains at least one character.
+ * <strong>Note:</strong> This assumes that the delimiter contains at
+ * least one character.
* <p>
* <strong>Note:</strong> This method does not guarantee to return
* the longest run of character data. This method may return before
@@ -1436,7 +1436,7 @@
} while (!done);
return !done;
- } // scanData(String,XMLString)
+ } // scanData(String, XMLStringBuffer)
/**
* Skips a character appearing immediately on the input.
@@ -1558,7 +1558,7 @@
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count - 1) {
- invokeListeners(0);
+ invokeListeners(1);
fCurrentEntity.ch[0] = (char)c;
entityChanged = load(1, true, false);
if (!entityChanged){
@@ -1727,8 +1727,7 @@
final int length = s.length;
//first make sure that required capacity is avaible
if(arrangeCapacity(length, false)){
- int beforeSkip = fCurrentEntity.position ;
- int afterSkip = fCurrentEntity.position + length ;
+ int beforeSkip = fCurrentEntity.position;
if(DEBUG_SKIP_STRING){
System.out.println("skipString,length = " + new String(s) + "," + length);
@@ -2107,8 +2106,9 @@
* is being changed.
*/
public void registerListener(XMLBufferListener listener) {
- if(!listeners.contains(listener))
+ if (!listeners.contains(listener)) {
listeners.add(listener);
+ }
}
/**
@@ -2116,9 +2116,8 @@
* @param loadPos Starting position from which new data is being loaded into scanner buffer.
*/
public void invokeListeners(int loadPos){
- for(int i=0;i<listeners.size();i++){
- XMLBufferListener listener =(XMLBufferListener) listeners.get(i);
- listener.refresh(loadPos);
+ for (int i=0; i<listeners.size(); i++) {
+ listeners.get(i).refresh(loadPos);
}
}
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java Thu Apr 28 23:08:17 2016 -0700
@@ -3,13 +3,14 @@
*/
/*
- * Copyright 2005 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -20,7 +21,6 @@
package com.sun.org.apache.xerces.internal.impl;
-
import com.sun.org.apache.xerces.internal.util.Status;
import com.sun.xml.internal.stream.XMLEntityStorage;
import java.io.IOException;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties Thu Apr 28 00:38:21 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties Thu Apr 28 23:08:17 2016 -0700
@@ -145,6 +145,7 @@
MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL = White space is required after \"<!DOCTYPE\" in the document type declaration.
MSG_ROOT_ELEMENT_TYPE_REQUIRED = The root element type must appear after \"<!DOCTYPE\" in the document type declaration.
DoctypedeclUnterminated = The document type declaration for root element type \"{0}\" must end with ''>''.
+ DoctypedeclNotClosed = The document type declaration for root element type \"{0}\" must be closed with '']''.
PEReferenceWithinMarkup = The parameter entity reference \"%{0};\" cannot occur within markup in the internal subset of the DTD.
MSG_MARKUP_NOT_RECOGNIZED_IN_DTD = The markup declarations contained or pointed to by the document type declaration must be well-formed.
# 2.10 White Space Handling
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties Thu Apr 28 00:38:21 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties Thu Apr 28 23:08:17 2016 -0700
@@ -145,6 +145,7 @@
MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL = Leerstelle nach "<!DOCTYPE" in der Dokumenttypdeklaration erforderlich.
MSG_ROOT_ELEMENT_TYPE_REQUIRED = Root-Elementtyp muss nach "<!DOCTYPE" in der Dokumenttypdeklaration enthalten sein.
DoctypedeclUnterminated = Dokumenttypdeklaration f\u00FCr Root-Elementtyp "{0}" muss mit ">" enden.
+ DoctypedeclNotClosed = Dokumenttypdeklaration f\u00FCr Root-Elementtyp "{0}" muss mit "]" abgeschlossen werden.
PEReferenceWithinMarkup = Parameterentit\u00E4tsreferenz "%{0};" darf nicht in Markup in der internen Teilmenge der DTD vorkommen.
MSG_MARKUP_NOT_RECOGNIZED_IN_DTD = Die Markup-Deklarationen, die in der Dokumenttypdeklaration enthalten sind bzw. auf die von der Dokumenttypdeklaration verwiesen wird, m\u00FCssen ordnungsgem\u00E4\u00DF formatiert sein.
# 2.10 White Space Handling
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties Thu Apr 28 00:38:21 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties Thu Apr 28 23:08:17 2016 -0700
@@ -145,6 +145,7 @@
MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL = Es necesario un espacio en blanco despu\u00E9s de "<!DOCTYPE" en la declaraci\u00F3n de tipo de documento.
MSG_ROOT_ELEMENT_TYPE_REQUIRED = El tipo de elemento ra\u00EDz debe aparecer despu\u00E9s de "<!DOCTYPE" en la declaraci\u00F3n de tipo de documento.
DoctypedeclUnterminated = La declaraci\u00F3n de tipo de documento para el tipo de elemento ra\u00EDz "{0}" debe finalizar en ''>''.
+ DoctypedeclNotClosed = La declaraci\u00F3n de tipo de documento para el tipo de elemento ra\u00EDz "{0}" debe cerrar en '']''.
PEReferenceWithinMarkup = La referencia de entidad del par\u00E1metro "%{0};" no puede producirse en el marcador en el subconjunto interno del DTD.
MSG_MARKUP_NOT_RECOGNIZED_IN_DTD = Las declaraciones de marcador que se incluyen o a las que apunta la declaraci\u00F3n de tipo de documento deben tener el formato correcto.
# 2.10 White Space Handling
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties Thu Apr 28 00:38:21 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties Thu Apr 28 23:08:17 2016 -0700
@@ -145,6 +145,7 @@
MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL = Un espace est obligatoire apr\u00E8s "<!DOCTYPE" dans la d\u00E9claration de type de document.
MSG_ROOT_ELEMENT_TYPE_REQUIRED = Le type d'\u00E9l\u00E9ment racine doit figurer apr\u00E8s "<!DOCTYPE" dans la d\u00E9claration de type de document.
DoctypedeclUnterminated = La d\u00E9claration de type de document pour le type d''\u00E9l\u00E9ment racine "{0}" doit se terminer par ''>''.
+ DoctypedeclNotClosed = La d\u00E9claration de type de document pour le type d''\u00E9l\u00E9ment racine "{0}" doit se conclure par '']''.
PEReferenceWithinMarkup = La r\u00E9f\u00E9rence d''entit\u00E9 de param\u00E8tre "%{0};" ne peut pas survenir dans le balisage du sous-ensemble interne de la DTD.
MSG_MARKUP_NOT_RECOGNIZED_IN_DTD = Les d\u00E9clarations de balisage contenues dans la d\u00E9claration de type de document ou sur lesquelles pointe cette derni\u00E8re doivent avoir un format correct.
# 2.10 White Space Handling
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties Thu Apr 28 00:38:21 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties Thu Apr 28 23:08:17 2016 -0700
@@ -145,6 +145,7 @@
MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL = \u00C8 richiesto uno spazio dopo "<!DOCTYPE" nella dichiarazione del tipo di documento.
MSG_ROOT_ELEMENT_TYPE_REQUIRED = Il tipo di elemento radice deve comparire dopo "<!DOCTYPE" nella dichiarazione del tipo di documento.
DoctypedeclUnterminated = La dichiarazione del tipo di documento per il tipo di elemento radice "{0}" deve terminare con ''>''.
+ DoctypedeclNotClosed = La dichiarazione del tipo di documento per il tipo di elemento radice "{0}" deve chiudere con '']''.
PEReferenceWithinMarkup = Il riferimento di entit\u00E0 di parametro "%{0};" non pu\u00F2 essere presente nel markup del set secondario interno del DTD.
MSG_MARKUP_NOT_RECOGNIZED_IN_DTD = Le dichiarazioni di markup contenute o indicate dalla dichiarazione del tipo di documento devono avere un formato corretto.
# 2.10 White Space Handling
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/HTTPInputSource.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/HTTPInputSource.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,15 +1,16 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
*/
+
/*
- * Copyright 2004,2005 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,18 +18,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.sun.org.apache.xerces.internal.util;
+import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
+import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
import java.io.InputStream;
import java.io.Reader;
-
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
-import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
-import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
-
/**
* This class represents an input source for an XML resource
* retrievable over HTTP. In addition to the properties
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/Asserts.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,566 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.testlibrary;
+
+import java.util.Objects;
+
+/**
+ * Asserts that can be used for verifying assumptions in tests.
+ *
+ * An assertion will throw a {@link RuntimeException} if the assertion isn't true.
+ * All the asserts can be imported into a test by using a static import:
+ *
+ * <pre>
+ * {@code
+ * import static jdk.testlibrary.Asserts.*;
+ * }
+ *
+ * Always provide a message describing the assumption if the line number of the
+ * failing assertion isn't enough to understand why the assumption failed. For
+ * example, if the assertion is in a loop or in a method that is called
+ * multiple times, then the line number won't provide enough context to
+ * understand the failure.
+ * </pre>
+ *
+ * @deprecated This class is deprecated. Use the one from
+ * {@code <root>/test/lib/share/classes/jdk/test/lib}
+ */
+@Deprecated
+public class Asserts {
+
+ /**
+ * Shorthand for {@link #assertLessThan(Comparable, Comparable)}.
+ *
+ * @param <T> a type
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @see #assertLessThan(Comparable, Comparable)
+ */
+ public static <T extends Comparable<T>> void assertLT(T lhs, T rhs) {
+ assertLessThan(lhs, rhs);
+ }
+
+ /**
+ * Shorthand for {@link #assertLessThan(Comparable, Comparable, String)}.
+ *
+ * @param <T> a type
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @param msg A description of the assumption; {@code null} for a default message.
+ * @see #assertLessThan(Comparable, Comparable, String)
+ */
+ public static <T extends Comparable<T>> void assertLT(T lhs, T rhs, String msg) {
+ assertLessThan(lhs, rhs, msg);
+ }
+
+ /**
+ * Calls {@link #assertLessThan(Comparable, Comparable, String)} with a default message.
+ *
+ * @param <T> a type
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @see #assertLessThan(Comparable, Comparable, String)
+ */
+ public static <T extends Comparable<T>> void assertLessThan(T lhs, T rhs) {
+ assertLessThan(lhs, rhs, null);
+ }
+
+ /**
+ * Asserts that {@code lhs} is less than {@code rhs}.
+ *
+ * @param <T> a type
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @param msg A description of the assumption; {@code null} for a default message.
+ * @throws RuntimeException if the assertion is not true.
+ */
+ public static <T extends Comparable<T>>void assertLessThan(T lhs, T rhs, String msg) {
+ if (!(compare(lhs, rhs, msg) < 0)) {
+ msg = Objects.toString(msg, "assertLessThan")
+ + ": expected that " + Objects.toString(lhs)
+ + " < " + Objects.toString(rhs);
+ fail(msg);
+ }
+ }
+
+ /**
+ * Shorthand for {@link #assertLessThanOrEqual(Comparable, Comparable)}.
+ *
+ * @param <T> a type
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @see #assertLessThanOrEqual(Comparable, Comparable)
+ */
+ public static <T extends Comparable<T>> void assertLTE(T lhs, T rhs) {
+ assertLessThanOrEqual(lhs, rhs);
+ }
+
+ /**
+ * Shorthand for {@link #assertLessThanOrEqual(Comparable, Comparable, String)}.
+ *
+ * @param <T> a type
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @param msg A description of the assumption; {@code null} for a default message.
+ * @see #assertLessThanOrEqual(Comparable, Comparable, String)
+ */
+ public static <T extends Comparable<T>> void assertLTE(T lhs, T rhs, String msg) {
+ assertLessThanOrEqual(lhs, rhs, msg);
+ }
+
+ /**
+ * Calls {@link #assertLessThanOrEqual(Comparable, Comparable, String)} with a default message.
+ *
+ * @param <T> a type
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @see #assertLessThanOrEqual(Comparable, Comparable, String)
+ */
+ public static <T extends Comparable<T>> void assertLessThanOrEqual(T lhs, T rhs) {
+ assertLessThanOrEqual(lhs, rhs, null);
+ }
+
+ /**
+ * Asserts that {@code lhs} is less than or equal to {@code rhs}.
+ *
+ * @param <T> a type
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @param msg A description of the assumption; {@code null} for a default message.
+ * @throws RuntimeException if the assertion is not true.
+ */
+ public static <T extends Comparable<T>> void assertLessThanOrEqual(T lhs, T rhs, String msg) {
+ if (!(compare(lhs, rhs, msg) <= 0)) {
+ msg = Objects.toString(msg, "assertLessThanOrEqual")
+ + ": expected that " + Objects.toString(lhs)
+ + " <= " + Objects.toString(rhs);
+ fail(msg);
+ }
+ }
+
+ /**
+ * Shorthand for {@link #assertEquals(Object, Object)}.
+ *
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @see #assertEquals(Object, Object)
+ */
+ public static void assertEQ(Object lhs, Object rhs) {
+ assertEquals(lhs, rhs);
+ }
+
+ /**
+ * Shorthand for {@link #assertEquals(Object, Object, String)}.
+ *
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @param msg A description of the assumption; {@code null} for a default message.
+ * @see #assertEquals(Object, Object, String)
+ */
+ public static void assertEQ(Object lhs, Object rhs, String msg) {
+ assertEquals(lhs, rhs, msg);
+ }
+
+ /**
+ * Calls {@link #assertEquals(java.lang.Object, java.lang.Object, java.lang.String)} with a default message.
+ *
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @see #assertEquals(Object, Object, String)
+ */
+ public static void assertEquals(Object lhs, Object rhs) {
+ assertEquals(lhs, rhs, null);
+ }
+
+ /**
+ * Asserts that {@code lhs} is equal to {@code rhs}.
+ *
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @param msg A description of the assumption; {@code null} for a default message.
+ * @throws RuntimeException if the assertion is not true.
+ */
+ public static void assertEquals(Object lhs, Object rhs, String msg) {
+ if ((lhs != rhs) && ((lhs == null) || !(lhs.equals(rhs)))) {
+ msg = Objects.toString(msg, "assertEquals")
+ + ": expected " + Objects.toString(lhs)
+ + " to equal " + Objects.toString(rhs);
+ fail(msg);
+ }
+ }
+
+ /**
+ * Calls {@link #assertSame(java.lang.Object, java.lang.Object, java.lang.String)} with a default message.
+ *
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @see #assertSame(Object, Object, String)
+ */
+ public static void assertSame(Object lhs, Object rhs) {
+ assertSame(lhs, rhs, null);
+ }
+
+ /**
+ * Asserts that {@code lhs} is the same as {@code rhs}.
+ *
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @param msg A description of the assumption; {@code null} for a default message.
+ * @throws RuntimeException if the assertion is not true.
+ */
+ public static void assertSame(Object lhs, Object rhs, String msg) {
+ if (lhs != rhs) {
+ msg = Objects.toString(msg, "assertSame")
+ + ": expected " + Objects.toString(lhs)
+ + " to equal " + Objects.toString(rhs);
+ fail(msg);
+ }
+ }
+
+ /**
+ * Shorthand for {@link #assertGreaterThanOrEqual(Comparable, Comparable)}.
+ *
+ * @param <T> a type
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @see #assertGreaterThanOrEqual(Comparable, Comparable)
+ */
+ public static <T extends Comparable<T>> void assertGTE(T lhs, T rhs) {
+ assertGreaterThanOrEqual(lhs, rhs);
+ }
+
+ /**
+ * Shorthand for {@link #assertGreaterThanOrEqual(Comparable, Comparable, String)}.
+ *
+ * @param <T> a type
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @param msg A description of the assumption; {@code null} for a default message.
+ * @see #assertGreaterThanOrEqual(Comparable, Comparable, String)
+ */
+ public static <T extends Comparable<T>> void assertGTE(T lhs, T rhs, String msg) {
+ assertGreaterThanOrEqual(lhs, rhs, msg);
+ }
+
+ /**
+ * Calls {@link #assertGreaterThanOrEqual(Comparable, Comparable, String)} with a default message.
+ *
+ * @param <T> a type
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @see #assertGreaterThanOrEqual(Comparable, Comparable, String)
+ */
+ public static <T extends Comparable<T>> void assertGreaterThanOrEqual(T lhs, T rhs) {
+ assertGreaterThanOrEqual(lhs, rhs, null);
+ }
+
+ /**
+ * Asserts that {@code lhs} is greater than or equal to {@code rhs}.
+ *
+ * @param <T> a type
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @param msg A description of the assumption; {@code null} for a default message.
+ * @throws RuntimeException if the assertion is not true.
+ */
+ public static <T extends Comparable<T>> void assertGreaterThanOrEqual(T lhs, T rhs, String msg) {
+ if (!(compare(lhs, rhs, msg) >= 0)) {
+ msg = Objects.toString(msg, "assertGreaterThanOrEqual")
+ + ": expected " + Objects.toString(lhs)
+ + " >= " + Objects.toString(rhs);
+ fail(msg);
+ }
+ }
+
+ /**
+ * Shorthand for {@link #assertGreaterThan(Comparable, Comparable)}.
+ *
+ * @param <T> a type
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @see #assertGreaterThan(Comparable, Comparable)
+ */
+ public static <T extends Comparable<T>> void assertGT(T lhs, T rhs) {
+ assertGreaterThan(lhs, rhs);
+ }
+
+ /**
+ * Shorthand for {@link #assertGreaterThan(Comparable, Comparable, String)}.
+ *
+ * @param <T> a type
+ * @param lhs the left hand value
+ * @param rhs the right hand value
+ * @param msg A description of the assumption; {@code null} for a default message.
+ * @see #assertGreaterThan(Comparable, Comparable, String)
+ */
+ public static <T extends Comparable<T>> void assertGT(T lhs, T rhs, String msg) {
+ assertGreaterThan(lhs, rhs, msg);
+ }
+
+ /**
+ * Calls {@link #assertGreaterThan(Comparable, Comparable, String)} with a default message.
+ *
+ * @param <T> a type
+ * @param lhs the left hand value
+ * @param rhs the right hand value
+ * @see #assertGreaterThan(Comparable, Comparable, String)
+ */
+ public static <T extends Comparable<T>> void assertGreaterThan(T lhs, T rhs) {
+ assertGreaterThan(lhs, rhs, null);
+ }
+
+ /**
+ * Asserts that {@code lhs} is greater than {@code rhs}.
+ *
+ * @param <T> a type
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @param msg A description of the assumption; {@code null} for a default message.
+ * @throws RuntimeException if the assertion is not true.
+ */
+ public static <T extends Comparable<T>> void assertGreaterThan(T lhs, T rhs, String msg) {
+ if (!(compare(lhs, rhs, msg) > 0)) {
+ msg = Objects.toString(msg, "assertGreaterThan")
+ + ": expected " + Objects.toString(lhs)
+ + " > " + Objects.toString(rhs);
+ fail(msg);
+ }
+ }
+
+ /**
+ * Shorthand for {@link #assertNotEquals(Object, Object)}.
+ *
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @see #assertNotEquals(Object, Object)
+ */
+ public static void assertNE(Object lhs, Object rhs) {
+ assertNotEquals(lhs, rhs);
+ }
+
+ /**
+ * Shorthand for {@link #assertNotEquals(Object, Object, String)}.
+ *
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @param msg A description of the assumption; {@code null} for a default message.
+ * @see #assertNotEquals(Object, Object, String)
+ */
+ public static void assertNE(Object lhs, Object rhs, String msg) {
+ assertNotEquals(lhs, rhs, msg);
+ }
+
+ /**
+ * Calls {@link #assertNotEquals(Object, Object, String)} with a default message.
+ *
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @see #assertNotEquals(Object, Object, String)
+ */
+ public static void assertNotEquals(Object lhs, Object rhs) {
+ assertNotEquals(lhs, rhs, null);
+ }
+
+ /**
+ * Asserts that {@code lhs} is not equal to {@code rhs}.
+ *
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @param msg A description of the assumption; {@code null} for a default message.
+ * @throws RuntimeException if the assertion is not true.
+ */
+ public static void assertNotEquals(Object lhs, Object rhs, String msg) {
+ if ((lhs == rhs) || (lhs != null && lhs.equals(rhs))) {
+ msg = Objects.toString(msg, "assertNotEquals")
+ + ": expected " + Objects.toString(lhs)
+ + " to not equal " + Objects.toString(rhs);
+ fail(msg);
+ }
+ }
+
+ /**
+ * Calls {@link #assertNull(Object, String)} with a default message.
+ *
+ * @param o The reference assumed to be null.
+ * @see #assertNull(Object, String)
+ */
+ public static void assertNull(Object o) {
+ assertNull(o, null);
+ }
+
+ /**
+ * Asserts that {@code o} is null.
+ *
+ * @param o The reference assumed to be null.
+ * @param msg A description of the assumption; {@code null} for a default message.
+ * @throws RuntimeException if the assertion is not true.
+ */
+ public static void assertNull(Object o, String msg) {
+ assertEquals(o, null, msg);
+ }
+
+ /**
+ * Calls {@link #assertNotNull(Object, String)} with a default message.
+ *
+ * @param o The reference assumed <i>not</i> to be null,
+ * @see #assertNotNull(Object, String)
+ */
+ public static void assertNotNull(Object o) {
+ assertNotNull(o, null);
+ }
+
+ /**
+ * Asserts that {@code o} is <i>not</i> null.
+ *
+ * @param o The reference assumed <i>not</i> to be null,
+ * @param msg A description of the assumption; {@code null} for a default message.
+ * @throws RuntimeException if the assertion is not true.
+ */
+ public static void assertNotNull(Object o, String msg) {
+ assertNotEquals(o, null, msg);
+ }
+
+ /**
+ * Calls {@link #assertFalse(boolean, String)} with a default message.
+ *
+ * @param value The value assumed to be false.
+ * @see #assertFalse(boolean, String)
+ */
+ public static void assertFalse(boolean value) {
+ assertFalse(value, null);
+ }
+
+ /**
+ * Asserts that {@code value} is {@code false}.
+ *
+ * @param value The value assumed to be false.
+ * @param msg A description of the assumption; {@code null} for a default message.
+ * @throws RuntimeException if the assertion is not true.
+ */
+ public static void assertFalse(boolean value, String msg) {
+ if (value) {
+ msg = Objects.toString(msg, "assertFalse")
+ + ": expected false, was true";
+ fail(msg);
+ }
+ }
+
+ /**
+ * Calls {@link #assertTrue(boolean, String)} with a default message.
+ *
+ * @param value The value assumed to be true.
+ * @see #assertTrue(boolean, String)
+ */
+ public static void assertTrue(boolean value) {
+ assertTrue(value, null);
+ }
+
+ /**
+ * Asserts that {@code value} is {@code true}.
+ *
+ * @param value The value assumed to be true.
+ * @param msg A description of the assumption; {@code null} for a default message.
+ * @throws RuntimeException if the assertion is not true.
+ */
+ public static void assertTrue(boolean value, String msg) {
+ if (!value) {
+ msg = Objects.toString(msg, "assertTrue")
+ + ": expected true, was false";
+ fail(msg);
+ }
+ }
+
+ private static <T extends Comparable<T>> int compare(T lhs, T rhs, String msg) {
+ if (lhs == null || rhs == null) {
+ fail(lhs, rhs, msg + ": values must be non-null:", ",");
+ }
+ return lhs.compareTo(rhs);
+ }
+
+ /**
+ * Returns a string formatted with a message and expected and actual values.
+ * @param lhs the actual value
+ * @param rhs the expected value
+ * @param message the actual value
+ * @param relation the asserted relationship between lhs and rhs
+ * @return a formatted string
+ */
+ public static String format(Object lhs, Object rhs, String message, String relation) {
+ StringBuilder sb = new StringBuilder(80);
+ if (message != null) {
+ sb.append(message);
+ sb.append(' ');
+ }
+ sb.append("<");
+ sb.append(Objects.toString(lhs));
+ sb.append("> ");
+ sb.append(Objects.toString(relation, ","));
+ sb.append(" <");
+ sb.append(Objects.toString(rhs));
+ sb.append(">");
+ return sb.toString();
+ }
+
+ /**
+ * Fail reports a failure with message fail.
+ *
+ * @throws RuntimeException always
+ */
+ public static void fail() {
+ fail("fail");
+ }
+
+ /**
+ * Fail reports a failure with a message.
+ * @param message for the failure
+ * @throws RuntimeException always
+ */
+ public static void fail(String message) {
+ throw new RuntimeException(message);
+ }
+
+ /**
+ * Fail reports a failure with a formatted message.
+ *
+ * @param lhs the actual value
+ * @param rhs the expected value
+ * @param message to be format before the expected and actual values
+ * @param relation the asserted relationship between lhs and rhs
+ * @throws RuntimeException always
+ */
+ public static void fail(Object lhs, Object rhs, String message, String relation) {
+ throw new RuntimeException(format(lhs, rhs, message, relation));
+ }
+
+ /**
+ * Fail reports a failure with a message and a cause.
+ * @param message to be format before the expected and actual values
+ * @param cause the exception that caused this failure
+ * @throws RuntimeException always
+ */
+ public static void fail(String message, Throwable cause) {
+ throw new RuntimeException(message, cause);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/CompilerUtils.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+package jdk.testlibrary;
+
+import javax.tools.JavaCompiler;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * This class consists exclusively of static utility methods for invoking the
+ * java compiler.
+ */
+
+public final class CompilerUtils {
+ private CompilerUtils() { }
+
+ /**
+ * Compile all the java sources in {@code <source>/**} to
+ * {@code <destination>/**}. The destination directory will be created if
+ * it doesn't exist.
+ *
+ * All warnings/errors emitted by the compiler are output to System.out/err.
+ *
+ * @return true if the compilation is successful
+ *
+ * @throws IOException if there is an I/O error scanning the source tree or
+ * creating the destination directory
+ */
+ public static boolean compile(Path source, Path destination, String ... options)
+ throws IOException
+ {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager jfm = compiler.getStandardFileManager(null, null, null);
+
+ List<Path> sources
+ = Files.find(source, Integer.MAX_VALUE,
+ (file, attrs) -> (file.toString().endsWith(".java")))
+ .collect(Collectors.toList());
+
+ Files.createDirectories(destination);
+ jfm.setLocation(StandardLocation.CLASS_PATH, Collections.EMPTY_LIST);
+ jfm.setLocationFromPaths(StandardLocation.CLASS_OUTPUT,
+ Arrays.asList(destination));
+
+ List<String> opts = Arrays.asList(options);
+ JavaCompiler.CompilationTask task
+ = compiler.getTask(null, jfm, null, opts, null,
+ jfm.getJavaFileObjectsFromPaths(sources));
+
+ return task.call();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/JDKToolFinder.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.testlibrary;
+
+import java.io.FileNotFoundException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/**
+ * @deprecated This class is deprecated. Use the one from
+ * {@code <root>/test/lib/share/classes/jdk/test/lib}
+ */
+@Deprecated
+public final class JDKToolFinder {
+
+ private JDKToolFinder() {
+ }
+
+ /**
+ * Returns the full path to an executable in jdk/bin based on System
+ * property {@code test.jdk} or {@code compile.jdk} (both are set by the jtreg test suite)
+ *
+ * @return Full path to an executable in jdk/bin
+ */
+ public static String getJDKTool(String tool) {
+
+ // First try to find the executable in test.jdk
+ try {
+ return getTool(tool, "test.jdk");
+ } catch (FileNotFoundException e) {
+
+ }
+
+ // Now see if it's available in compile.jdk
+ try {
+ return getTool(tool, "compile.jdk");
+ } catch (FileNotFoundException e) {
+ throw new RuntimeException("Failed to find " + tool +
+ ", looked in test.jdk (" + System.getProperty("test.jdk") +
+ ") and compile.jdk (" + System.getProperty("compile.jdk") + ")");
+ }
+ }
+
+ /**
+ * Returns the full path to an executable in jdk/bin based on System
+ * property {@code compile.jdk}
+ *
+ * @return Full path to an executable in jdk/bin
+ */
+ public static String getCompileJDKTool(String tool) {
+ try {
+ return getTool(tool, "compile.jdk");
+ } catch (FileNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Returns the full path to an executable in jdk/bin based on System
+ * property {@code test.jdk}
+ *
+ * @return Full path to an executable in jdk/bin
+ */
+ public static String getTestJDKTool(String tool) {
+ try {
+ return getTool(tool, "test.jdk");
+ } catch (FileNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static String getTool(String tool, String property) throws FileNotFoundException {
+ String jdkPath = System.getProperty(property);
+
+ if (jdkPath == null) {
+ throw new RuntimeException(
+ "System property '" + property + "' not set. This property is normally set by jtreg. "
+ + "When running test separately, set this property using '-D" + property + "=/path/to/jdk'.");
+ }
+
+ Path toolName = Paths.get("bin", tool + (Platform.isWindows() ? ".exe" : ""));
+
+ Path jdkTool = Paths.get(jdkPath, toolName.toString());
+ if (!jdkTool.toFile().exists()) {
+ throw new FileNotFoundException("Could not find file " + jdkTool.toAbsolutePath());
+ }
+
+ return jdkTool.toAbsolutePath().toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/JDKToolLauncher.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.testlibrary;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A utility for constructing command lines for starting JDK tool processes.
+ *
+ * The JDKToolLauncher can in particular be combined with a
+ * java.lang.ProcessBuilder to easily run a JDK tool. For example, the following
+ * code run {@code jmap -heap} against a process with GC logging turned on for
+ * the {@code jmap} process:
+ *
+ * <pre>
+ * {@code
+ * JDKToolLauncher jmap = JDKToolLauncher.create("jmap")
+ * .addVMArg("-Xlog:gc*=debug")
+ * .addToolArg("-heap")
+ * .addToolArg(pid);
+ * ProcessBuilder pb = new ProcessBuilder(jmap.getCommand());
+ * Process p = pb.start();
+ * }
+ * </pre>
+ * @deprecated This class is deprecated. Use the one from
+ * {@code <root>/test/lib/share/classes/jdk/test/lib}
+ */
+@Deprecated
+public class JDKToolLauncher {
+ private final String executable;
+ private final List<String> vmArgs = new ArrayList<String>();
+ private final List<String> toolArgs = new ArrayList<String>();
+
+ private JDKToolLauncher(String tool, boolean useCompilerJDK) {
+ if (useCompilerJDK) {
+ executable = JDKToolFinder.getJDKTool(tool);
+ } else {
+ executable = JDKToolFinder.getTestJDKTool(tool);
+ }
+ vmArgs.addAll(Arrays.asList(ProcessTools.getPlatformSpecificVMArgs()));
+ }
+
+ /**
+ * Creates a new JDKToolLauncher for the specified tool. Using tools path
+ * from the compiler JDK.
+ *
+ * @param tool
+ * The name of the tool
+ * @return A new JDKToolLauncher
+ */
+ public static JDKToolLauncher create(String tool) {
+ return new JDKToolLauncher(tool, true);
+ }
+
+ /**
+ * Creates a new JDKToolLauncher for the specified tool in the Tested JDK.
+ *
+ * @param tool
+ * The name of the tool
+ *
+ * @return A new JDKToolLauncher
+ */
+ public static JDKToolLauncher createUsingTestJDK(String tool) {
+ return new JDKToolLauncher(tool, false);
+ }
+
+ /**
+ * Adds an argument to the JVM running the tool.
+ *
+ * The JVM arguments are passed to the underlying JVM running the tool.
+ * Arguments will automatically be prepended with "-J".
+ *
+ * Any platform specific arguments required for running the tool are
+ * automatically added.
+ *
+ *
+ * @param arg
+ * The argument to VM running the tool
+ * @return The JDKToolLauncher instance
+ */
+ public JDKToolLauncher addVMArg(String arg) {
+ vmArgs.add(arg);
+ return this;
+ }
+
+ /**
+ * Adds an argument to the tool.
+ *
+ * @param arg
+ * The argument to the tool
+ * @return The JDKToolLauncher instance
+ */
+ public JDKToolLauncher addToolArg(String arg) {
+ toolArgs.add(arg);
+ return this;
+ }
+
+ /**
+ * Returns the command that can be used for running the tool.
+ *
+ * @return An array whose elements are the arguments of the command.
+ */
+ public String[] getCommand() {
+ List<String> command = new ArrayList<String>();
+ command.add(executable);
+ // Add -J in front of all vmArgs
+ for (String arg : vmArgs) {
+ command.add("-J" + arg);
+ }
+ command.addAll(toolArgs);
+ return command.toArray(new String[command.size()]);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/OutputAnalyzer.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,576 @@
+/*
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.testlibrary;
+
+import static jdk.testlibrary.Asserts.*;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Utility class for verifying output and exit value from a {@code Process}.
+ *
+ * @deprecated This class is deprecated. Use the one from
+ * {@code <root>/test/lib/share/classes/jdk/test/lib/process}
+ *
+ */
+@Deprecated
+public final class OutputAnalyzer {
+ private final OutputBuffer output;
+ private final String stdout;
+ private final String stderr;
+ private final int exitValue; // useless now. output contains exit value.
+
+ /**
+ * Create an OutputAnalyzer, a utility class for verifying output and exit
+ * value from a Process.
+ * <p>
+ * OutputAnalyzer should never be instantiated directly -
+ * use {@linkplain ProcessTools#executeProcess(ProcessBuilder)} instead
+ *
+ * @param process
+ * Process to analyze
+ * @throws IOException
+ * If an I/O error occurs.
+ */
+ OutputAnalyzer(Process process) throws IOException {
+ output = new OutputBuffer(process);
+ exitValue = -1;
+ this.stdout = null;
+ this.stderr = null;
+ }
+
+ /**
+ * Create an OutputAnalyzer, a utility class for verifying output.
+ *
+ * @param buf
+ * String buffer to analyze
+ */
+ OutputAnalyzer(String buf) {
+ this(buf, buf);
+ }
+
+ /**
+ * Create an OutputAnalyzer, a utility class for verifying output
+ *
+ * @param stdout
+ * stdout buffer to analyze
+ * @param stderr
+ * stderr buffer to analyze
+ */
+ OutputAnalyzer(String stdout, String stderr) {
+ this.output = null;
+ this.stdout = stdout;
+ this.stderr = stderr;
+ exitValue = -1;
+ }
+
+ /**
+ * Verify that the stdout and stderr contents of output buffer contains the
+ * string
+ *
+ * @param expectedString
+ * String that buffer should contain
+ * @throws RuntimeException
+ * If the string was not found
+ */
+ public OutputAnalyzer shouldContain(String expectedString) {
+ if (!getStdout().contains(expectedString)
+ && !getStderr().contains(expectedString)) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("'" + expectedString
+ + "' missing from stdout/stderr \n");
+ }
+ return this;
+ }
+
+ /**
+ * Verify that the stdout contents of output buffer contains the string
+ *
+ * @param expectedString
+ * String that buffer should contain
+ * @throws RuntimeException
+ * If the string was not found
+ */
+ public OutputAnalyzer stdoutShouldContain(String expectedString) {
+ if (!getStdout().contains(expectedString)) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("'" + expectedString
+ + "' missing from stdout \n");
+ }
+ return this;
+ }
+
+ /**
+ * Verify that the stderr contents of output buffer contains the string
+ *
+ * @param expectedString
+ * String that buffer should contain
+ * @throws RuntimeException
+ * If the string was not found
+ */
+ public OutputAnalyzer stderrShouldContain(String expectedString) {
+ if (!getStderr().contains(expectedString)) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("'" + expectedString
+ + "' missing from stderr \n");
+ }
+ return this;
+ }
+
+ /**
+ * Verify that the stdout and stderr contents of output buffer does not
+ * contain the string
+ *
+ * @param notExpectedString
+ * String that the buffer should not contain
+ * @throws RuntimeException
+ * If the string was found
+ */
+ public OutputAnalyzer shouldNotContain(String notExpectedString) {
+ if (getStdout().contains(notExpectedString)) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("'" + notExpectedString
+ + "' found in stdout \n");
+ }
+ if (getStderr().contains(notExpectedString)) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("'" + notExpectedString
+ + "' found in stderr \n");
+ }
+ return this;
+ }
+
+ /**
+ * Verify that the stdout contents of output buffer does not contain the
+ * string
+ *
+ * @param notExpectedString
+ * String that the buffer should not contain
+ * @throws RuntimeException
+ * If the string was found
+ */
+ public OutputAnalyzer stdoutShouldNotContain(String notExpectedString) {
+ if (getStdout().contains(notExpectedString)) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("'" + notExpectedString
+ + "' found in stdout \n");
+ }
+ return this;
+ }
+
+ /**
+ * Verify that the stderr contents of output buffer does not contain the
+ * string
+ *
+ * @param notExpectedString
+ * String that the buffer should not contain
+ * @throws RuntimeException
+ * If the string was found
+ */
+ public OutputAnalyzer stderrShouldNotContain(String notExpectedString) {
+ if (getStderr().contains(notExpectedString)) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("'" + notExpectedString
+ + "' found in stderr \n");
+ }
+ return this;
+ }
+
+ /**
+ * Verify that the stdout and stderr contents of output buffer matches the
+ * pattern
+ *
+ * @param pattern
+ * @throws RuntimeException
+ * If the pattern was not found
+ */
+ public OutputAnalyzer shouldMatch(String pattern) {
+ Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE)
+ .matcher(getStdout());
+ Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE)
+ .matcher(getStderr());
+ if (!stdoutMatcher.find() && !stderrMatcher.find()) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("'" + pattern
+ + "' missing from stdout/stderr \n");
+ }
+ return this;
+ }
+
+ /**
+ * Verify that the stdout contents of output buffer matches the pattern
+ *
+ * @param pattern
+ * @throws RuntimeException
+ * If the pattern was not found
+ */
+ public OutputAnalyzer stdoutShouldMatch(String pattern) {
+ Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
+ getStdout());
+ if (!matcher.find()) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("'" + pattern
+ + "' missing from stdout \n");
+ }
+ return this;
+ }
+
+ /**
+ * Verify that the stderr contents of output buffer matches the pattern
+ *
+ * @param pattern
+ * @throws RuntimeException
+ * If the pattern was not found
+ */
+ public OutputAnalyzer stderrShouldMatch(String pattern) {
+ Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
+ getStderr());
+ if (!matcher.find()) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("'" + pattern
+ + "' missing from stderr \n");
+ }
+ return this;
+ }
+
+ /**
+ * Verify that the stdout and stderr contents of output buffer does not
+ * match the pattern
+ *
+ * @param pattern
+ * @throws RuntimeException
+ * If the pattern was found
+ */
+ public OutputAnalyzer shouldNotMatch(String pattern) {
+ Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
+ getStdout());
+ if (matcher.find()) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("'" + pattern + "' found in stdout: '"
+ + matcher.group() + "' \n");
+ }
+ matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(getStderr());
+ if (matcher.find()) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("'" + pattern + "' found in stderr: '"
+ + matcher.group() + "' \n");
+ }
+ return this;
+ }
+
+ /**
+ * Verify that the stdout contents of output buffer does not match the
+ * pattern
+ *
+ * @param pattern
+ * @throws RuntimeException
+ * If the pattern was found
+ */
+ public OutputAnalyzer stdoutShouldNotMatch(String pattern) {
+ Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
+ getStdout());
+ if (matcher.find()) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("'" + pattern + "' found in stdout \n");
+ }
+ return this;
+ }
+
+ /**
+ * Verify that the stderr contents of output buffer does not match the
+ * pattern
+ *
+ * @param pattern
+ * @throws RuntimeException
+ * If the pattern was found
+ */
+ public OutputAnalyzer stderrShouldNotMatch(String pattern) {
+ Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
+ getStderr());
+ if (matcher.find()) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("'" + pattern + "' found in stderr \n");
+ }
+ return this;
+ }
+
+ /**
+ * Get the captured group of the first string matching the pattern. stderr
+ * is searched before stdout.
+ *
+ * @param pattern
+ * The multi-line pattern to match
+ * @param group
+ * The group to capture
+ * @return The matched string or null if no match was found
+ */
+ public String firstMatch(String pattern, int group) {
+ Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE)
+ .matcher(getStderr());
+ Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE)
+ .matcher(getStdout());
+ if (stderrMatcher.find()) {
+ return stderrMatcher.group(group);
+ }
+ if (stdoutMatcher.find()) {
+ return stdoutMatcher.group(group);
+ }
+ return null;
+ }
+
+ /**
+ * Get the first string matching the pattern. stderr is searched before
+ * stdout.
+ *
+ * @param pattern
+ * The multi-line pattern to match
+ * @return The matched string or null if no match was found
+ */
+ public String firstMatch(String pattern) {
+ return firstMatch(pattern, 0);
+ }
+
+ /**
+ * Verify the exit value of the process
+ *
+ * @param expectedExitValue
+ * Expected exit value from process
+ * @throws RuntimeException
+ * If the exit value from the process did not match the expected
+ * value
+ */
+ public OutputAnalyzer shouldHaveExitValue(int expectedExitValue) {
+ if (getExitValue() != expectedExitValue) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("Expected to get exit value of ["
+ + expectedExitValue + "]\n");
+ }
+ return this;
+ }
+
+ /**
+ * Report summary that will help to diagnose the problem Currently includes:
+ * - standard input produced by the process under test - standard output -
+ * exit code Note: the command line is printed by the ProcessTools
+ */
+ private OutputAnalyzer reportDiagnosticSummary() {
+ String msg = " stdout: [" + getStdout() + "];\n" + " stderr: [" + getStderr()
+ + "]\n" + " exitValue = " + getExitValue() + "\n";
+
+ System.err.println(msg);
+ return this;
+ }
+
+ /**
+ * Get the contents of the output buffer (stdout and stderr)
+ *
+ * @return Content of the output buffer
+ */
+ public String getOutput() {
+ return getStdout() + getStderr();
+ }
+
+ /**
+ * Get the contents of the stdout buffer
+ *
+ * @return Content of the stdout buffer
+ */
+ public String getStdout() {
+ return output == null ? stdout : output.getStdout();
+ }
+
+ /**
+ * Get the contents of the stderr buffer
+ *
+ * @return Content of the stderr buffer
+ */
+ public String getStderr() {
+ return output == null ? stderr : output.getStderr();
+ }
+
+ /**
+ * Get the process exit value
+ *
+ * @return Process exit value
+ */
+ public int getExitValue() {
+ return output == null ? exitValue : output.getExitValue();
+ }
+
+
+ /**
+ * Print the stdout buffer to the given {@code PrintStream}.
+ *
+ * @return this OutputAnalyzer
+ */
+ public OutputAnalyzer outputTo(PrintStream out) {
+ out.println(getStdout());
+ return this;
+ }
+
+ /**
+ * Print the stderr buffer to the given {@code PrintStream}.
+ *
+ * @return this OutputAnalyzer
+ */
+ public OutputAnalyzer errorTo(PrintStream out) {
+ out.println(getStderr());
+ return this;
+ }
+
+
+ /**
+ * Get the contents of the output buffer (stdout and stderr) as list of strings.
+ * Output will be split by system property 'line.separator'.
+ *
+ * @return Contents of the output buffer as list of strings
+ */
+ public List<String> asLines() {
+ return asLines(getOutput());
+ }
+
+ private List<String> asLines(String buffer) {
+ List<String> l = new ArrayList<>();
+ String[] a = buffer.split(Utils.NEW_LINE);
+ for (String string : a) {
+ l.add(string);
+ }
+ return l;
+ }
+
+ /**
+ * Check if there is a line matching {@code pattern} and return its index
+ *
+ * @param pattern Matching pattern
+ * @return Index of first matching line
+ */
+ private int indexOf(List<String> lines, String pattern) {
+ for (int i = 0; i < lines.size(); i++) {
+ if (lines.get(i).matches(pattern)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * @see #shouldMatchByLine(String, String, String)
+ */
+ public int shouldMatchByLine(String pattern) {
+ return shouldMatchByLine(null, null, pattern);
+ }
+
+ /**
+ * @see #stdoutShouldMatchByLine(String, String, String)
+ */
+ public int stdoutShouldMatchByLine(String pattern) {
+ return stdoutShouldMatchByLine(null, null, pattern);
+ }
+
+ /**
+ * @see #shouldMatchByLine(String, String, String)
+ */
+ public int shouldMatchByLineFrom(String from, String pattern) {
+ return shouldMatchByLine(from, null, pattern);
+ }
+
+ /**
+ * @see #shouldMatchByLine(String, String, String)
+ */
+ public int shouldMatchByLineTo(String to, String pattern) {
+ return shouldMatchByLine(null, to, pattern);
+ }
+
+ /**
+ * Verify that the stdout and stderr contents of output buffer match the
+ * {@code pattern} line by line. The whole output could be matched or
+ * just a subset of it.
+ *
+ * @param from
+ * The line from where output will be matched.
+ * Set {@code from} to null for matching from the first line.
+ * @param to
+ * The line until where output will be matched.
+ * Set {@code to} to null for matching until the last line.
+ * @param pattern
+ * Matching pattern
+ * @return Count of lines which match the {@code pattern}
+ */
+ public int shouldMatchByLine(String from, String to, String pattern) {
+ return shouldMatchByLine(getOutput(), from, to, pattern);
+ }
+
+ /**
+ * Verify that the stdout contents of output buffer matches the
+ * {@code pattern} line by line. The whole stdout could be matched or
+ * just a subset of it.
+ *
+ * @param from
+ * The line from where stdout will be matched.
+ * Set {@code from} to null for matching from the first line.
+ * @param to
+ * The line until where stdout will be matched.
+ * Set {@code to} to null for matching until the last line.
+ * @param pattern
+ * Matching pattern
+ * @return Count of lines which match the {@code pattern}
+ */
+ public int stdoutShouldMatchByLine(String from, String to, String pattern) {
+ return shouldMatchByLine(getStdout(), from, to, pattern);
+ }
+
+ private int shouldMatchByLine(String buffer, String from, String to, String pattern) {
+ List<String> lines = asLines(buffer);
+
+ int fromIndex = 0;
+ if (from != null) {
+ fromIndex = indexOf(lines, from);
+ assertGreaterThan(fromIndex, -1,
+ "The line/pattern '" + from + "' from where the output should match can not be found");
+ }
+
+ int toIndex = lines.size();
+ if (to != null) {
+ toIndex = indexOf(lines, to);
+ assertGreaterThan(toIndex, -1,
+ "The line/pattern '" + to + "' until where the output should match can not be found");
+ }
+
+ List<String> subList = lines.subList(fromIndex, toIndex);
+ int matchedCount = 0;
+ for (String line : subList) {
+ assertTrue(line.matches(pattern),
+ "The line '" + line + "' does not match pattern '" + pattern + "'");
+ matchedCount++;
+ }
+
+ return matchedCount;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/OutputBuffer.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.testlibrary;
+
+import java.io.ByteArrayOutputStream;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+/**
+ * @deprecated This class is deprecated. Use the one from
+ * {@code <root>/test/lib/share/classes/jdk/test/lib/process}
+ */
+@Deprecated
+class OutputBuffer {
+ private static class OutputBufferException extends RuntimeException {
+ private static final long serialVersionUID = 8528687792643129571L;
+
+ public OutputBufferException(Throwable cause) {
+ super(cause);
+ }
+ }
+
+ private final Process p;
+ private final Future<Void> outTask;
+ private final Future<Void> errTask;
+ private final ByteArrayOutputStream stderrBuffer = new ByteArrayOutputStream();
+ private final ByteArrayOutputStream stdoutBuffer = new ByteArrayOutputStream();
+
+ /**
+ * Create an OutputBuffer, a class for storing and managing stdout and
+ * stderr results separately
+ *
+ * @param stdout
+ * stdout result
+ * @param stderr
+ * stderr result
+ */
+ OutputBuffer(Process p) {
+ this.p = p;
+ StreamPumper outPumper = new StreamPumper(p.getInputStream(),
+ stdoutBuffer);
+ StreamPumper errPumper = new StreamPumper(p.getErrorStream(),
+ stderrBuffer);
+
+ outTask = outPumper.process();
+ errTask = errPumper.process();
+ }
+
+ /**
+ * Returns the stdout result
+ *
+ * @return stdout result
+ */
+ public String getStdout() {
+ try {
+ outTask.get();
+ return stdoutBuffer.toString();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new OutputBufferException(e);
+ } catch (ExecutionException | CancellationException e) {
+ throw new OutputBufferException(e);
+ }
+ }
+
+ /**
+ * Returns the stderr result
+ *
+ * @return stderr result
+ */
+ public String getStderr() {
+ try {
+ errTask.get();
+ return stderrBuffer.toString();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new OutputBufferException(e);
+ } catch (ExecutionException | CancellationException e) {
+ throw new OutputBufferException(e);
+ }
+ }
+
+ public int getExitValue() {
+ try {
+ return p.waitFor();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new OutputBufferException(e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/Platform.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2013, 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 jdk.testlibrary;
+import java.util.regex.Pattern;
+import java.io.RandomAccessFile;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+/**
+ * @deprecated This class is deprecated. Use the one from
+ * {@code <root>/test/lib/share/classes/jdk/test/lib}
+ */
+@Deprecated
+public class Platform {
+ private static final String osName = System.getProperty("os.name");
+ private static final String dataModel = System.getProperty("sun.arch.data.model");
+ private static final String vmVersion = System.getProperty("java.vm.version");
+ private static final String jdkDebug = System.getProperty("jdk.debug");
+ private static final String osArch = System.getProperty("os.arch");
+ private static final String vmName = System.getProperty("java.vm.name");
+ private static final String userName = System.getProperty("user.name");
+ private static final String compiler = System.getProperty("sun.management.compiler");
+
+ public static boolean isClient() {
+ return vmName.endsWith(" Client VM");
+ }
+
+ public static boolean isServer() {
+ return vmName.endsWith(" Server VM");
+ }
+
+ public static boolean isGraal() {
+ return vmName.endsWith(" Graal VM");
+ }
+
+ public static boolean isMinimal() {
+ return vmName.endsWith(" Minimal VM");
+ }
+
+ public static boolean isEmbedded() {
+ return vmName.contains("Embedded");
+ }
+
+ public static boolean isTieredSupported() {
+ return compiler.contains("Tiered Compilers");
+ }
+
+
+ public static boolean is32bit() {
+ return dataModel.equals("32");
+ }
+
+ public static boolean is64bit() {
+ return dataModel.equals("64");
+ }
+
+ public static boolean isAix() {
+ return isOs("aix");
+ }
+
+ public static boolean isLinux() {
+ return isOs("linux");
+ }
+
+ public static boolean isOSX() {
+ return isOs("mac");
+ }
+
+ public static boolean isSolaris() {
+ return isOs("sunos");
+ }
+
+ public static boolean isWindows() {
+ return isOs("win");
+ }
+
+ private static boolean isOs(String osname) {
+ return osName.toLowerCase().startsWith(osname.toLowerCase());
+ }
+
+ public static String getOsName() {
+ return osName;
+ }
+
+ public static boolean isDebugBuild() {
+ return (jdkDebug.toLowerCase().contains("debug"));
+ }
+
+ public static String getVMVersion() {
+ return vmVersion;
+ }
+
+ // Returns true for sparc and sparcv9.
+ public static boolean isSparc() {
+ return isArch("sparc.*");
+ }
+
+ public static boolean isARM() {
+ return isArch("arm.*");
+ }
+
+ public static boolean isPPC() {
+ return isArch("ppc.*");
+ }
+
+ public static boolean isX86() {
+ // On Linux it's 'i386', Windows 'x86' without '_64' suffix.
+ return isArch("(i386)|(x86(?!_64))");
+ }
+
+ public static boolean isX64() {
+ // On OSX it's 'x86_64' and on other (Linux, Windows and Solaris) platforms it's 'amd64'
+ return isArch("(amd64)|(x86_64)");
+ }
+
+ private static boolean isArch(String archnameRE) {
+ return Pattern.compile(archnameRE, Pattern.CASE_INSENSITIVE)
+ .matcher(osArch)
+ .matches();
+ }
+
+ public static String getOsArch() {
+ return osArch;
+ }
+
+ /**
+ * Return a boolean for whether we expect to be able to attach
+ * the SA to our own processes on this system.
+ */
+ public static boolean shouldSAAttach()
+ throws IOException {
+
+ if (isAix()) {
+ return false; // SA not implemented.
+ } else if (isLinux()) {
+ return canPtraceAttachLinux();
+ } else if (isOSX()) {
+ return canAttachOSX();
+ } else {
+ // Other platforms expected to work:
+ return true;
+ }
+ }
+
+ /**
+ * On Linux, first check the SELinux boolean "deny_ptrace" and return false
+ * as we expect to be denied if that is "1".
+ */
+ public static boolean canPtraceAttachLinux()
+ throws IOException {
+
+ // SELinux deny_ptrace:
+ try(RandomAccessFile file = new RandomAccessFile("/sys/fs/selinux/booleans/deny_ptrace", "r")) {
+ if (file.readByte() != '0') {
+ return false;
+ }
+ }
+ catch(FileNotFoundException ex) {
+ // Ignored
+ }
+
+ // YAMA enhanced security ptrace_scope:
+ // 0 - a process can PTRACE_ATTACH to any other process running under the same uid
+ // 1 - restricted ptrace: a process must be a children of the inferior or user is root
+ // 2 - only processes with CAP_SYS_PTRACE may use ptrace or user is root
+ // 3 - no attach: no processes may use ptrace with PTRACE_ATTACH
+
+ try(RandomAccessFile file = new RandomAccessFile("/proc/sys/kernel/yama/ptrace_scope", "r")) {
+ byte yama_scope = file.readByte();
+ if (yama_scope == '3') {
+ return false;
+ }
+
+ if (!userName.equals("root") && yama_scope != '0') {
+ return false;
+ }
+ }
+ catch(FileNotFoundException ex) {
+ // Ignored
+ }
+
+ // Otherwise expect to be permitted:
+ return true;
+ }
+
+ /**
+ * On OSX, expect permission to attach only if we are root.
+ */
+ public static boolean canAttachOSX() {
+ return userName.equals("root");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/ProcessTools.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,579 @@
+/*
+ * Copyright (c) 2013, 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 jdk.testlibrary;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.concurrent.CountDownLatch;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.function.Predicate;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+
+
+/**
+ * @deprecated This class is deprecated. Use the one from
+ * {@code <root>/test/lib/share/classes/jdk/test/lib/process}
+ */
+@Deprecated
+public final class ProcessTools {
+ private static final class LineForwarder extends StreamPumper.LinePump {
+ private final PrintStream ps;
+ private final String prefix;
+ LineForwarder(String prefix, PrintStream os) {
+ this.ps = os;
+ this.prefix = prefix;
+ }
+ @Override
+ protected void processLine(String line) {
+ ps.println("[" + prefix + "] " + line);
+ }
+ }
+
+ private ProcessTools() {
+ }
+
+ /**
+ * <p>Starts a process from its builder.</p>
+ * <span>The default redirects of STDOUT and STDERR are started</span>
+ * @param name The process name
+ * @param processBuilder The process builder
+ * @return Returns the initialized process
+ * @throws IOException
+ */
+ public static Process startProcess(String name,
+ ProcessBuilder processBuilder)
+ throws IOException {
+ return startProcess(name, processBuilder, (Consumer<String>)null);
+ }
+
+ /**
+ * <p>Starts a process from its builder.</p>
+ * <span>The default redirects of STDOUT and STDERR are started</span>
+ * <p>It is possible to monitor the in-streams via the provided {@code consumer}
+ * @param name The process name
+ * @param consumer {@linkplain Consumer} instance to process the in-streams
+ * @param processBuilder The process builder
+ * @return Returns the initialized process
+ * @throws IOException
+ */
+ @SuppressWarnings("overloads")
+ public static Process startProcess(String name,
+ ProcessBuilder processBuilder,
+ Consumer<String> consumer)
+ throws IOException {
+ try {
+ return startProcess(name, processBuilder, consumer, null, -1, TimeUnit.NANOSECONDS);
+ } catch (InterruptedException | TimeoutException e) {
+ // will never happen
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * <p>Starts a process from its builder.</p>
+ * <span>The default redirects of STDOUT and STDERR are started</span>
+ * <p>
+ * It is possible to wait for the process to get to a warmed-up state
+ * via {@linkplain Predicate} condition on the STDOUT
+ * </p>
+ * @param name The process name
+ * @param processBuilder The process builder
+ * @param linePredicate The {@linkplain Predicate} to use on the STDOUT
+ * Used to determine the moment the target app is
+ * properly warmed-up.
+ * It can be null - in that case the warmup is skipped.
+ * @param timeout The timeout for the warmup waiting; -1 = no wait; 0 = wait forever
+ * @param unit The timeout {@linkplain TimeUnit}
+ * @return Returns the initialized {@linkplain Process}
+ * @throws IOException
+ * @throws InterruptedException
+ * @throws TimeoutException
+ */
+ public static Process startProcess(String name,
+ ProcessBuilder processBuilder,
+ final Predicate<String> linePredicate,
+ long timeout,
+ TimeUnit unit)
+ throws IOException, InterruptedException, TimeoutException {
+ return startProcess(name, processBuilder, null, linePredicate, timeout, unit);
+ }
+
+ /**
+ * <p>Starts a process from its builder.</p>
+ * <span>The default redirects of STDOUT and STDERR are started</span>
+ * <p>
+ * It is possible to wait for the process to get to a warmed-up state
+ * via {@linkplain Predicate} condition on the STDOUT and monitor the
+ * in-streams via the provided {@linkplain Consumer}
+ * </p>
+ * @param name The process name
+ * @param processBuilder The process builder
+ * @param lineConsumer The {@linkplain Consumer} the lines will be forwarded to
+ * @param linePredicate The {@linkplain Predicate} to use on the STDOUT
+ * Used to determine the moment the target app is
+ * properly warmed-up.
+ * It can be null - in that case the warmup is skipped.
+ * @param timeout The timeout for the warmup waiting; -1 = no wait; 0 = wait forever
+ * @param unit The timeout {@linkplain TimeUnit}
+ * @return Returns the initialized {@linkplain Process}
+ * @throws IOException
+ * @throws InterruptedException
+ * @throws TimeoutException
+ */
+ public static Process startProcess(String name,
+ ProcessBuilder processBuilder,
+ final Consumer<String> lineConsumer,
+ final Predicate<String> linePredicate,
+ long timeout,
+ TimeUnit unit)
+ throws IOException, InterruptedException, TimeoutException {
+ System.out.println("["+name+"]:" + processBuilder.command().stream().collect(Collectors.joining(" ")));
+ Process p = processBuilder.start();
+ StreamPumper stdout = new StreamPumper(p.getInputStream());
+ StreamPumper stderr = new StreamPumper(p.getErrorStream());
+
+ stdout.addPump(new LineForwarder(name, System.out));
+ stderr.addPump(new LineForwarder(name, System.err));
+ if (lineConsumer != null) {
+ StreamPumper.LinePump pump = new StreamPumper.LinePump() {
+ @Override
+ protected void processLine(String line) {
+ lineConsumer.accept(line);
+ }
+ };
+ stdout.addPump(pump);
+ stderr.addPump(pump);
+ }
+
+
+ CountDownLatch latch = new CountDownLatch(1);
+ if (linePredicate != null) {
+ StreamPumper.LinePump pump = new StreamPumper.LinePump() {
+ @Override
+ protected void processLine(String line) {
+ if (latch.getCount() > 0 && linePredicate.test(line)) {
+ latch.countDown();
+ }
+ }
+ };
+ stdout.addPump(pump);
+ stderr.addPump(pump);
+ } else {
+ latch.countDown();
+ }
+ final Future<Void> stdoutTask = stdout.process();
+ final Future<Void> stderrTask = stderr.process();
+
+ try {
+ if (timeout > -1) {
+ if (timeout == 0) {
+ latch.await();
+ } else {
+ if (!latch.await(Utils.adjustTimeout(timeout), unit)) {
+ throw new TimeoutException();
+ }
+ }
+ }
+ } catch (TimeoutException | InterruptedException e) {
+ System.err.println("Failed to start a process (thread dump follows)");
+ for(Map.Entry<Thread, StackTraceElement[]> s : Thread.getAllStackTraces().entrySet()) {
+ printStack(s.getKey(), s.getValue());
+ }
+
+ if (p.isAlive()) {
+ p.destroyForcibly();
+ }
+
+ stdoutTask.cancel(true);
+ stderrTask.cancel(true);
+ throw e;
+ }
+
+ return new ProcessImpl(p, stdoutTask, stderrTask);
+ }
+
+ /**
+ * <p>Starts a process from its builder.</p>
+ * <span>The default redirects of STDOUT and STDERR are started</span>
+ * <p>
+ * It is possible to wait for the process to get to a warmed-up state
+ * via {@linkplain Predicate} condition on the STDOUT. The warm-up will
+ * wait indefinitely.
+ * </p>
+ * @param name The process name
+ * @param processBuilder The process builder
+ * @param linePredicate The {@linkplain Predicate} to use on the STDOUT
+ * Used to determine the moment the target app is
+ * properly warmed-up.
+ * It can be null - in that case the warmup is skipped.
+ * @return Returns the initialized {@linkplain Process}
+ * @throws IOException
+ * @throws InterruptedException
+ * @throws TimeoutException
+ */
+ @SuppressWarnings("overloads")
+ public static Process startProcess(String name,
+ ProcessBuilder processBuilder,
+ final Predicate<String> linePredicate)
+ throws IOException, InterruptedException, TimeoutException {
+ return startProcess(name, processBuilder, linePredicate, 0, TimeUnit.SECONDS);
+ }
+
+ /**
+ * Get the process id of the current running Java process
+ *
+ * @return Process id
+ */
+ public static long getProcessId() {
+ return ProcessHandle.current().getPid();
+ }
+
+ /**
+ * Get platform specific VM arguments (e.g. -d64 on 64bit Solaris)
+ *
+ * @return String[] with platform specific arguments, empty if there are
+ * none
+ */
+ public static String[] getPlatformSpecificVMArgs() {
+ String osName = System.getProperty("os.name");
+ String dataModel = System.getProperty("sun.arch.data.model");
+
+ if (osName.equals("SunOS") && dataModel.equals("64")) {
+ return new String[] { "-d64" };
+ }
+
+ return new String[] {};
+ }
+
+ /**
+ * Create ProcessBuilder using the java launcher from the jdk to be tested,
+ * and with any platform specific arguments prepended.
+ *
+ * @param command Arguments to pass to the java command.
+ * @return The ProcessBuilder instance representing the java command.
+ */
+ public static ProcessBuilder createJavaProcessBuilder(String... command)
+ throws Exception {
+ return createJavaProcessBuilder(false, command);
+ }
+
+ /**
+ * Create ProcessBuilder using the java launcher from the jdk to be tested,
+ * and with any platform specific arguments prepended.
+ *
+ * @param addTestVmAndJavaOptions If true, adds test.vm.opts and test.java.opts
+ * to the java arguments.
+ * @param command Arguments to pass to the java command.
+ * @return The ProcessBuilder instance representing the java command.
+ */
+ public static ProcessBuilder createJavaProcessBuilder(boolean addTestVmAndJavaOptions, String... command) throws Exception {
+ String javapath = JDKToolFinder.getJDKTool("java");
+
+ ArrayList<String> args = new ArrayList<>();
+ args.add(javapath);
+ Collections.addAll(args, getPlatformSpecificVMArgs());
+
+ if (addTestVmAndJavaOptions) {
+ // -cp is needed to make sure the same classpath is used whether the test is
+ // run in AgentVM mode or OtherVM mode. It was added to the hotspot version
+ // of this API as part of 8077608. However, for the jdk version it is only
+ // added when addTestVmAndJavaOptions is true in order to minimize
+ // disruption to existing JDK tests, which have yet to be tested with -cp
+ // being added. At some point -cp should always be added to be consistent
+ // with what the hotspot version does.
+ args.add("-cp");
+ args.add(System.getProperty("java.class.path"));
+ Collections.addAll(args, Utils.getTestJavaOpts());
+ }
+
+ Collections.addAll(args, command);
+
+ // Reporting
+ StringBuilder cmdLine = new StringBuilder();
+ for (String cmd : args)
+ cmdLine.append(cmd).append(' ');
+ System.out.println("Command line: [" + cmdLine.toString() + "]");
+
+ return new ProcessBuilder(args.toArray(new String[args.size()]));
+ }
+
+ private static void printStack(Thread t, StackTraceElement[] stack) {
+ System.out.println("\t" + t +
+ " stack: (length = " + stack.length + ")");
+ if (t != null) {
+ for (StackTraceElement stack1 : stack) {
+ System.out.println("\t" + stack1);
+ }
+ System.out.println();
+ }
+ }
+
+ /**
+ * Executes a test java process, waits for it to finish and returns the process output.
+ * The default options from jtreg, test.vm.opts and test.java.opts, are added.
+ * The java from the test.jdk is used to execute the command.
+ *
+ * The command line will be like:
+ * {test.jdk}/bin/java {test.vm.opts} {test.java.opts} cmds
+ *
+ * The java process will have exited before this method returns.
+ *
+ * @param cmds User specifed arguments.
+ * @return The output from the process.
+ */
+ public static OutputAnalyzer executeTestJava(String... options) throws Exception {
+ ProcessBuilder pb = createJavaProcessBuilder(Utils.addTestJavaOpts(options));
+ return executeProcess(pb);
+ }
+
+ /**
+ * @deprecated Use executeTestJava instead
+ */
+ public static OutputAnalyzer executeTestJvm(String... options) throws Exception {
+ return executeTestJava(options);
+ }
+
+ /**
+ * Executes a process, waits for it to finish and returns the process output.
+ * The process will have exited before this method returns.
+ * @param pb The ProcessBuilder to execute.
+ * @return The {@linkplain OutputAnalyzer} instance wrapping the process.
+ */
+ public static OutputAnalyzer executeProcess(ProcessBuilder pb) throws Exception {
+ return executeProcess(pb, null);
+ }
+
+ /**
+ * Executes a process, pipe some text into its STDIN, waits for it
+ * to finish and returns the process output. The process will have exited
+ * before this method returns.
+ * @param pb The ProcessBuilder to execute.
+ * @param input The text to pipe into STDIN. Can be null.
+ * @return The {@linkplain OutputAnalyzer} instance wrapping the process.
+ */
+ public static OutputAnalyzer executeProcess(ProcessBuilder pb, String input)
+ throws Exception {
+ OutputAnalyzer output = null;
+ Process p = null;
+ boolean failed = false;
+ try {
+ p = pb.start();
+ if (input != null) {
+ try (OutputStream os = p.getOutputStream();
+ PrintStream ps = new PrintStream(os)) {
+ ps.print(input);
+ ps.flush();
+ }
+ }
+ output = new OutputAnalyzer(p);
+ p.waitFor();
+
+ return output;
+ } catch (Throwable t) {
+ if (p != null) {
+ p.destroyForcibly().waitFor();
+ }
+
+ failed = true;
+ System.out.println("executeProcess() failed: " + t);
+ throw t;
+ } finally {
+ if (failed) {
+ System.err.println(getProcessLog(pb, output));
+ }
+ }
+ }
+
+ /**
+ * Executes a process, waits for it to finish and returns the process output.
+ *
+ * The process will have exited before this method returns.
+ *
+ * @param cmds The command line to execute.
+ * @return The output from the process.
+ */
+ public static OutputAnalyzer executeProcess(String... cmds) throws Throwable {
+ return executeProcess(new ProcessBuilder(cmds));
+ }
+
+ /**
+ * Used to log command line, stdout, stderr and exit code from an executed process.
+ * @param pb The executed process.
+ * @param output The output from the process.
+ */
+ public static String getProcessLog(ProcessBuilder pb, OutputAnalyzer output) {
+ String stderr = output == null ? "null" : output.getStderr();
+ String stdout = output == null ? "null" : output.getStdout();
+ String exitValue = output == null ? "null": Integer.toString(output.getExitValue());
+ StringBuilder logMsg = new StringBuilder();
+ final String nl = System.getProperty("line.separator");
+ logMsg.append("--- ProcessLog ---" + nl);
+ logMsg.append("cmd: " + getCommandLine(pb) + nl);
+ logMsg.append("exitvalue: " + exitValue + nl);
+ logMsg.append("stderr: " + stderr + nl);
+ logMsg.append("stdout: " + stdout + nl);
+
+ return logMsg.toString();
+ }
+
+ /**
+ * @return The full command line for the ProcessBuilder.
+ */
+ public static String getCommandLine(ProcessBuilder pb) {
+ if (pb == null) {
+ return "null";
+ }
+ StringBuilder cmd = new StringBuilder();
+ for (String s : pb.command()) {
+ cmd.append(s).append(" ");
+ }
+ return cmd.toString().trim();
+ }
+
+ /**
+ * Executes a process, waits for it to finish, prints the process output
+ * to stdout, and returns the process output.
+ *
+ * The process will have exited before this method returns.
+ *
+ * @param cmds The command line to execute.
+ * @return The {@linkplain OutputAnalyzer} instance wrapping the process.
+ */
+ public static OutputAnalyzer executeCommand(String... cmds)
+ throws Throwable {
+ String cmdLine = Arrays.stream(cmds).collect(Collectors.joining(" "));
+ System.out.println("Command line: [" + cmdLine + "]");
+ OutputAnalyzer analyzer = ProcessTools.executeProcess(cmds);
+ System.out.println(analyzer.getOutput());
+ return analyzer;
+ }
+
+ /**
+ * Executes a process, waits for it to finish, prints the process output
+ * to stdout and returns the process output.
+ *
+ * The process will have exited before this method returns.
+ *
+ * @param pb The ProcessBuilder to execute.
+ * @return The {@linkplain OutputAnalyzer} instance wrapping the process.
+ */
+ public static OutputAnalyzer executeCommand(ProcessBuilder pb)
+ throws Throwable {
+ String cmdLine = pb.command().stream().collect(Collectors.joining(" "));
+ System.out.println("Command line: [" + cmdLine + "]");
+ OutputAnalyzer analyzer = ProcessTools.executeProcess(pb);
+ System.out.println(analyzer.getOutput());
+ return analyzer;
+ }
+
+ private static class ProcessImpl extends Process {
+
+ private final Process p;
+ private final Future<Void> stdoutTask;
+ private final Future<Void> stderrTask;
+
+ public ProcessImpl(Process p, Future<Void> stdoutTask, Future<Void> stderrTask) {
+ this.p = p;
+ this.stdoutTask = stdoutTask;
+ this.stderrTask = stderrTask;
+ }
+
+ @Override
+ public OutputStream getOutputStream() {
+ return p.getOutputStream();
+ }
+
+ @Override
+ public InputStream getInputStream() {
+ return p.getInputStream();
+ }
+
+ @Override
+ public InputStream getErrorStream() {
+ return p.getErrorStream();
+ }
+
+ @Override
+ public int waitFor() throws InterruptedException {
+ int rslt = p.waitFor();
+ waitForStreams();
+ return rslt;
+ }
+
+ @Override
+ public int exitValue() {
+ return p.exitValue();
+ }
+
+ @Override
+ public void destroy() {
+ p.destroy();
+ }
+
+ @Override
+ public long getPid() {
+ return p.getPid();
+ }
+
+ @Override
+ public boolean isAlive() {
+ return p.isAlive();
+ }
+
+ @Override
+ public Process destroyForcibly() {
+ return p.destroyForcibly();
+ }
+
+ @Override
+ public boolean waitFor(long timeout, TimeUnit unit) throws InterruptedException {
+ boolean rslt = p.waitFor(timeout, unit);
+ if (rslt) {
+ waitForStreams();
+ }
+ return rslt;
+ }
+
+ private void waitForStreams() throws InterruptedException {
+ try {
+ stdoutTask.get();
+ } catch (ExecutionException e) {
+ }
+ try {
+ stderrTask.get();
+ } catch (ExecutionException e) {
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/README.txt Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,1 @@
+These files are copies of the corresponding files in test/lib/testlibrary/ from jdk repo.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/StreamPumper.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.testlibrary;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * @deprecated This class is deprecated. Use the one from
+ * {@code <root>/test/lib/share/classes/jdk/test/lib/process}
+ */
+@Deprecated
+public final class StreamPumper implements Runnable {
+
+ private static final int BUF_SIZE = 256;
+
+ /**
+ * Pump will be called by the StreamPumper to process the incoming data
+ */
+ abstract public static class Pump {
+ abstract void register(StreamPumper d);
+ }
+
+ /**
+ * OutputStream -> Pump adapter
+ */
+ final public static class StreamPump extends Pump {
+ private final OutputStream out;
+ public StreamPump(OutputStream out) {
+ this.out = out;
+ }
+
+ @Override
+ void register(StreamPumper sp) {
+ sp.addOutputStream(out);
+ }
+ }
+
+ /**
+ * Used to process the incoming data line-by-line
+ */
+ abstract public static class LinePump extends Pump {
+ @Override
+ final void register(StreamPumper sp) {
+ sp.addLineProcessor(this);
+ }
+
+ abstract protected void processLine(String line);
+ }
+
+ private final InputStream in;
+ private final Set<OutputStream> outStreams = new HashSet<>();
+ private final Set<LinePump> linePumps = new HashSet<>();
+
+ private final AtomicBoolean processing = new AtomicBoolean(false);
+ private final FutureTask<Void> processingTask = new FutureTask<>(this, null);
+
+ public StreamPumper(InputStream in) {
+ this.in = in;
+ }
+
+ /**
+ * Create a StreamPumper that reads from in and writes to out.
+ *
+ * @param in
+ * The stream to read from.
+ * @param out
+ * The stream to write to.
+ */
+ public StreamPumper(InputStream in, OutputStream out) {
+ this(in);
+ this.addOutputStream(out);
+ }
+
+ /**
+ * Implements Thread.run(). Continuously read from {@code in} and write to
+ * {@code out} until {@code in} has reached end of stream. Abort on
+ * interruption. Abort on IOExceptions.
+ */
+ @Override
+ public void run() {
+ try (BufferedInputStream is = new BufferedInputStream(in)) {
+ ByteArrayOutputStream lineBos = new ByteArrayOutputStream();
+ byte[] buf = new byte[BUF_SIZE];
+ int len = 0;
+ int linelen = 0;
+
+ while ((len = is.read(buf)) > 0 && !Thread.interrupted()) {
+ for(OutputStream out : outStreams) {
+ out.write(buf, 0, len);
+ }
+ if (!linePumps.isEmpty()) {
+ int i = 0;
+ int lastcrlf = -1;
+ while (i < len) {
+ if (buf[i] == '\n' || buf[i] == '\r') {
+ int bufLinelen = i - lastcrlf - 1;
+ if (bufLinelen > 0) {
+ lineBos.write(buf, lastcrlf + 1, bufLinelen);
+ }
+ linelen += bufLinelen;
+
+ if (linelen > 0) {
+ lineBos.flush();
+ final String line = lineBos.toString();
+ linePumps.stream().forEach((lp) -> {
+ lp.processLine(line);
+ });
+ lineBos.reset();
+ linelen = 0;
+ }
+ lastcrlf = i;
+ }
+
+ i++;
+ }
+ if (lastcrlf == -1) {
+ lineBos.write(buf, 0, len);
+ linelen += len;
+ } else if (lastcrlf < len - 1) {
+ lineBos.write(buf, lastcrlf + 1, len - lastcrlf - 1);
+ linelen += len - lastcrlf - 1;
+ }
+ }
+ }
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ for(OutputStream out : outStreams) {
+ try {
+ out.flush();
+ } catch (IOException e) {}
+ }
+ try {
+ in.close();
+ } catch (IOException e) {}
+ }
+ }
+
+ final void addOutputStream(OutputStream out) {
+ outStreams.add(out);
+ }
+
+ final void addLineProcessor(LinePump lp) {
+ linePumps.add(lp);
+ }
+
+ final public StreamPumper addPump(Pump ... pump) {
+ if (processing.get()) {
+ throw new IllegalStateException("Can not modify pumper while " +
+ "processing is in progress");
+ }
+ for(Pump p : pump) {
+ p.register(this);
+ }
+ return this;
+ }
+
+ final public Future<Void> process() {
+ if (!processing.compareAndSet(false, true)) {
+ throw new IllegalStateException("Can not re-run the processing");
+ }
+ Thread t = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ processingTask.run();
+ }
+ });
+ t.setDaemon(true);
+ t.start();
+
+ return processingTask;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/Utils.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2013, 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 jdk.testlibrary;
+
+import static jdk.testlibrary.Asserts.assertTrue;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BooleanSupplier;
+import java.util.function.Function;
+
+/**
+ * Common library for various test helper functions.
+ *
+ * @deprecated This class is deprecated. Use the one from
+ * {@code <root>/test/lib/share/classes/jdk/test/lib}
+ */
+@Deprecated
+public final class Utils {
+
+ /**
+ * Returns the sequence used by operating system to separate lines.
+ */
+ public static final String NEW_LINE = System.getProperty("line.separator");
+
+ /**
+ * Returns the value of 'test.vm.opts'system property.
+ */
+ public static final String VM_OPTIONS = System.getProperty("test.vm.opts", "").trim();
+
+ /**
+ * Returns the value of 'test.java.opts'system property.
+ */
+ public static final String JAVA_OPTIONS = System.getProperty("test.java.opts", "").trim();
+
+ /**
+ * Returns the value of 'test.timeout.factor' system property
+ * converted to {@code double}.
+ */
+ public static final double TIMEOUT_FACTOR;
+ static {
+ String toFactor = System.getProperty("test.timeout.factor", "1.0");
+ TIMEOUT_FACTOR = Double.parseDouble(toFactor);
+ }
+
+ /**
+ * Returns the value of JTREG default test timeout in milliseconds
+ * converted to {@code long}.
+ */
+ public static final long DEFAULT_TEST_TIMEOUT = TimeUnit.SECONDS.toMillis(120);
+
+ private Utils() {
+ // Private constructor to prevent class instantiation
+ }
+
+ /**
+ * Returns the list of VM options.
+ *
+ * @return List of VM options
+ */
+ public static List<String> getVmOptions() {
+ return Arrays.asList(safeSplitString(VM_OPTIONS));
+ }
+
+ /**
+ * Returns the list of VM options with -J prefix.
+ *
+ * @return The list of VM options with -J prefix
+ */
+ public static List<String> getForwardVmOptions() {
+ String[] opts = safeSplitString(VM_OPTIONS);
+ for (int i = 0; i < opts.length; i++) {
+ opts[i] = "-J" + opts[i];
+ }
+ return Arrays.asList(opts);
+ }
+
+ /**
+ * Returns the default JTReg arguments for a jvm running a test.
+ * This is the combination of JTReg arguments test.vm.opts and test.java.opts.
+ * @return An array of options, or an empty array if no opptions.
+ */
+ public static String[] getTestJavaOpts() {
+ List<String> opts = new ArrayList<String>();
+ Collections.addAll(opts, safeSplitString(VM_OPTIONS));
+ Collections.addAll(opts, safeSplitString(JAVA_OPTIONS));
+ return opts.toArray(new String[0]);
+ }
+
+ /**
+ * Combines given arguments with default JTReg arguments for a jvm running a test.
+ * This is the combination of JTReg arguments test.vm.opts and test.java.opts
+ * @return The combination of JTReg test java options and user args.
+ */
+ public static String[] addTestJavaOpts(String... userArgs) {
+ List<String> opts = new ArrayList<String>();
+ Collections.addAll(opts, getTestJavaOpts());
+ Collections.addAll(opts, userArgs);
+ return opts.toArray(new String[0]);
+ }
+
+ /**
+ * Removes any options specifying which GC to use, for example "-XX:+UseG1GC".
+ * Removes any options matching: -XX:(+/-)Use*GC
+ * Used when a test need to set its own GC version. Then any
+ * GC specified by the framework must first be removed.
+ * @return A copy of given opts with all GC options removed.
+ */
+ private static final Pattern useGcPattern = Pattern.compile(
+ "(?:\\-XX\\:[\\+\\-]Use.+GC)"
+ + "|(?:\\-Xconcgc)");
+ public static List<String> removeGcOpts(List<String> opts) {
+ List<String> optsWithoutGC = new ArrayList<String>();
+ for (String opt : opts) {
+ if (useGcPattern.matcher(opt).matches()) {
+ System.out.println("removeGcOpts: removed " + opt);
+ } else {
+ optsWithoutGC.add(opt);
+ }
+ }
+ return optsWithoutGC;
+ }
+
+ /**
+ * Splits a string by white space.
+ * Works like String.split(), but returns an empty array
+ * if the string is null or empty.
+ */
+ private static String[] safeSplitString(String s) {
+ if (s == null || s.trim().isEmpty()) {
+ return new String[] {};
+ }
+ return s.trim().split("\\s+");
+ }
+
+ /**
+ * @return The full command line for the ProcessBuilder.
+ */
+ public static String getCommandLine(ProcessBuilder pb) {
+ StringBuilder cmd = new StringBuilder();
+ for (String s : pb.command()) {
+ cmd.append(s).append(" ");
+ }
+ return cmd.toString();
+ }
+
+ /**
+ * Returns the free port on the local host.
+ * The function will spin until a valid port number is found.
+ *
+ * @return The port number
+ * @throws InterruptedException if any thread has interrupted the current thread
+ * @throws IOException if an I/O error occurs when opening the socket
+ */
+ public static int getFreePort() throws InterruptedException, IOException {
+ int port = -1;
+
+ while (port <= 0) {
+ Thread.sleep(100);
+
+ ServerSocket serverSocket = null;
+ try {
+ serverSocket = new ServerSocket(0);
+ port = serverSocket.getLocalPort();
+ } finally {
+ serverSocket.close();
+ }
+ }
+
+ return port;
+ }
+
+ /**
+ * Returns the name of the local host.
+ *
+ * @return The host name
+ * @throws UnknownHostException if IP address of a host could not be determined
+ */
+ public static String getHostname() throws UnknownHostException {
+ InetAddress inetAddress = InetAddress.getLocalHost();
+ String hostName = inetAddress.getHostName();
+
+ assertTrue((hostName != null && !hostName.isEmpty()),
+ "Cannot get hostname");
+
+ return hostName;
+ }
+
+ /**
+ * Uses "jcmd -l" to search for a jvm pid. This function will wait
+ * forever (until jtreg timeout) for the pid to be found.
+ * @param key Regular expression to search for
+ * @return The found pid.
+ */
+ public static int waitForJvmPid(String key) throws Throwable {
+ final long iterationSleepMillis = 250;
+ System.out.println("waitForJvmPid: Waiting for key '" + key + "'");
+ System.out.flush();
+ while (true) {
+ int pid = tryFindJvmPid(key);
+ if (pid >= 0) {
+ return pid;
+ }
+ Thread.sleep(iterationSleepMillis);
+ }
+ }
+
+ /**
+ * Searches for a jvm pid in the output from "jcmd -l".
+ *
+ * Example output from jcmd is:
+ * 12498 sun.tools.jcmd.JCmd -l
+ * 12254 /tmp/jdk8/tl/jdk/JTwork/classes/com/sun/tools/attach/Application.jar
+ *
+ * @param key A regular expression to search for.
+ * @return The found pid, or -1 if Enot found.
+ * @throws Exception If multiple matching jvms are found.
+ */
+ public static int tryFindJvmPid(String key) throws Throwable {
+ OutputAnalyzer output = null;
+ try {
+ JDKToolLauncher jcmdLauncher = JDKToolLauncher.create("jcmd");
+ jcmdLauncher.addToolArg("-l");
+ output = ProcessTools.executeProcess(jcmdLauncher.getCommand());
+ output.shouldHaveExitValue(0);
+
+ // Search for a line starting with numbers (pid), follwed by the key.
+ Pattern pattern = Pattern.compile("([0-9]+)\\s.*(" + key + ").*\\r?\\n");
+ Matcher matcher = pattern.matcher(output.getStdout());
+
+ int pid = -1;
+ if (matcher.find()) {
+ pid = Integer.parseInt(matcher.group(1));
+ System.out.println("findJvmPid.pid: " + pid);
+ if (matcher.find()) {
+ throw new Exception("Found multiple JVM pids for key: " + key);
+ }
+ }
+ return pid;
+ } catch (Throwable t) {
+ System.out.println(String.format("Utils.findJvmPid(%s) failed: %s", key, t));
+ throw t;
+ }
+ }
+
+ /**
+ * Adjusts the provided timeout value for the TIMEOUT_FACTOR
+ * @param tOut the timeout value to be adjusted
+ * @return The timeout value adjusted for the value of "test.timeout.factor"
+ * system property
+ */
+ public static long adjustTimeout(long tOut) {
+ return Math.round(tOut * Utils.TIMEOUT_FACTOR);
+ }
+
+ /**
+ * Wait for condition to be true
+ *
+ * @param condition, a condition to wait for
+ */
+ public static final void waitForCondition(BooleanSupplier condition) {
+ waitForCondition(condition, -1L, 100L);
+ }
+
+ /**
+ * Wait until timeout for condition to be true
+ *
+ * @param condition, a condition to wait for
+ * @param timeout a time in milliseconds to wait for condition to be true
+ * specifying -1 will wait forever
+ * @return condition value, to determine if wait was successfull
+ */
+ public static final boolean waitForCondition(BooleanSupplier condition,
+ long timeout) {
+ return waitForCondition(condition, timeout, 100L);
+ }
+
+ /**
+ * Wait until timeout for condition to be true for specified time
+ *
+ * @param condition, a condition to wait for
+ * @param timeout a time in milliseconds to wait for condition to be true,
+ * specifying -1 will wait forever
+ * @param sleepTime a time to sleep value in milliseconds
+ * @return condition value, to determine if wait was successfull
+ */
+ public static final boolean waitForCondition(BooleanSupplier condition,
+ long timeout, long sleepTime) {
+ long startTime = System.currentTimeMillis();
+ while (!(condition.getAsBoolean() || (timeout != -1L
+ && ((System.currentTimeMillis() - startTime) > timeout)))) {
+ try {
+ Thread.sleep(sleepTime);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new Error(e);
+ }
+ }
+ return condition.getAsBoolean();
+ }
+
+ /**
+ * Interface same as java.lang.Runnable but with
+ * method {@code run()} able to throw any Throwable.
+ */
+ public static interface ThrowingRunnable {
+ void run() throws Throwable;
+ }
+
+ /**
+ * Filters out an exception that may be thrown by the given
+ * test according to the given filter.
+ *
+ * @param test - method that is invoked and checked for exception.
+ * @param filter - function that checks if the thrown exception matches
+ * criteria given in the filter's implementation.
+ * @return - exception that matches the filter if it has been thrown or
+ * {@code null} otherwise.
+ * @throws Throwable - if test has thrown an exception that does not
+ * match the filter.
+ */
+ public static Throwable filterException(ThrowingRunnable test,
+ Function<Throwable, Boolean> filter) throws Throwable {
+ try {
+ test.run();
+ } catch (Throwable t) {
+ if (filter.apply(t)) {
+ return t;
+ } else {
+ throw t;
+ }
+ }
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/BasicModularXMLParserTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import static org.testng.Assert.assertTrue;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static jdk.testlibrary.ProcessTools.executeTestJava;
+import jdk.testlibrary.CompilerUtils;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @library /javax/xml/jaxp/libs
+ * @build jdk.testlibrary.*
+ * @run testng BasicModularXMLParserTest
+ * @bug 8078820
+ * @summary Tests JAXP lib can instantiate the following interfaces
+ * with customized provider module on boot layer
+ *
+ * javax.xml.datatype.DatatypeFactory
+ * javax.xml.parsers.DocumentBuilderFactory
+ * javax.xml.parsers.SAXParserFactory
+ * javax.xml.stream.XMLEventFactory
+ * javax.xml.stream.XMLInputFactory
+ * javax.xml.stream.XMLOutputFactory
+ * javax.xml.transform.TransformerFactory
+ * javax.xml.validation.SchemaFactory
+ * javax.xml.xpath.XPathFactory
+ */
+
+@Test
+public class BasicModularXMLParserTest {
+
+ private static final String TEST_SRC = System.getProperty("test.src");
+
+ private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
+ private static final Path MOD_DIR1 = Paths.get("mod1");
+ private static final Path MOD_DIR2 = Paths.get("mod2");
+ private static final Path CLASSES_DIR = Paths.get("classes");
+
+ /*
+ * Compiles all modules used by the test
+ */
+ @BeforeTest
+ public void compileAll() throws Exception {
+ assertTrue(CompilerUtils.compile(SRC_DIR.resolve("xmlprovider1"), MOD_DIR1.resolve("xmlprovider1")));
+ assertTrue(CompilerUtils.compile(SRC_DIR.resolve("xmlprovider2"), MOD_DIR2.resolve("xmlprovider2")));
+ assertTrue(CompilerUtils.compile(SRC_DIR.resolve("unnamed"), CLASSES_DIR));
+ }
+
+ /*
+ * test the default JAXP implementation
+ */
+ public void testDefault() throws Exception {
+ int exitValue
+ = executeTestJava("-cp", CLASSES_DIR.toString(),
+ "Main")
+ .outputTo(System.out)
+ .errorTo(System.out)
+ .getExitValue();
+
+ assertTrue(exitValue == 0);
+ }
+
+ /*
+ * test loading one provider module
+ */
+ public void testWithOneProvider() throws Exception {
+ int exitValue
+ = executeTestJava("-mp", MOD_DIR1.toString(),
+ "-cp", CLASSES_DIR.toString(),
+ "Main", "xmlprovider1")
+ .outputTo(System.out)
+ .errorTo(System.out)
+ .getExitValue();
+
+ assertTrue(exitValue == 0);
+ }
+
+ /*
+ * test loading both provider modules
+ */
+ public void testWithTwoProvider() throws Exception {
+ int exitValue
+ = executeTestJava("-mp", MOD_DIR1.toString() + File.pathSeparator + MOD_DIR2.toString(),
+ "-cp", CLASSES_DIR.toString(),
+ "Main", "xmlprovider1", "xmlprovider2")
+ .outputTo(System.out)
+ .errorTo(System.out)
+ .getExitValue();
+
+ assertTrue(exitValue == 0);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/LayerModularXMLParserTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import static java.lang.module.ModuleFinder.empty;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+
+import java.lang.ClassLoader;
+import java.lang.String;
+import java.lang.System;
+import java.lang.module.Configuration;
+import java.lang.module.ModuleFinder;
+import java.lang.reflect.Layer;
+import java.lang.reflect.Method;
+import java.lang.reflect.Module;
+import java.nio.file.Paths;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+import java.util.Set;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import jdk.testlibrary.CompilerUtils;
+
+/*
+ * @test
+ * @library /javax/xml/jaxp/libs
+ * @build jdk.testlibrary.*
+ * @run testng LayerModularXMLParserTest
+ * @bug 8078820
+ * @summary Tests JAXP lib works with layer and TCCL
+ */
+
+@Test
+public class LayerModularXMLParserTest {
+
+ private static final String TEST_SRC = System.getProperty("test.src");
+
+ private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
+ private static final Path MOD_DIR1 = Paths.get("mod1");
+ private static final Path MOD_DIR2 = Paths.get("mod2");
+
+ /*
+ * services provided by provider1
+ */
+ private static final String[] services1 = { "javax.xml.parsers.DocumentBuilderFactory",
+ "javax.xml.parsers.SAXParserFactory", "javax.xml.stream.XMLInputFactory",
+ "javax.xml.stream.XMLOutputFactory", "javax.xml.transform.TransformerFactory",
+ "javax.xml.validation.SchemaFactory", "javax.xml.xpath.XPathFactory" };
+
+ /*
+ * services provided by provider2
+ */
+ private static final String[] services2 = { "javax.xml.datatype.DatatypeFactory",
+ "javax.xml.stream.XMLEventFactory" };
+
+ /*
+ * Compiles all modules used by the test
+ */
+ @BeforeTest
+ public void compileAll() throws Exception {
+ assertTrue(CompilerUtils.compile(SRC_DIR.resolve("xmlprovider1"), MOD_DIR1.resolve("xmlprovider1")));
+ assertTrue(CompilerUtils.compile(SRC_DIR.resolve("xmlprovider2"), MOD_DIR2.resolve("xmlprovider2")));
+ assertTrue(CompilerUtils.compile(SRC_DIR.resolve("test"), MOD_DIR1.resolve("test")));
+ assertTrue(CompilerUtils.compile(SRC_DIR.resolve("test"), MOD_DIR2.resolve("test")));
+ }
+
+ /*
+ * layer 1 is created on top of boot layer, layer1 includes module provider1.
+ *
+ * Instantiate each XML service, verify the services provided by provider1
+ * are loaded from layer 1, the other services are loaded from boot layer
+ */
+ public void testOneLayer() throws Exception {
+ ModuleFinder finder1 = ModuleFinder.of(MOD_DIR1);
+ Configuration cf1 = Layer.boot().configuration()
+ .resolveRequiresAndUses(finder1, empty(), Set.of("test"));
+ ClassLoader scl = ClassLoader.getSystemClassLoader();
+ Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, scl);
+ ClassLoader cl1 = layer1.findLoader("test");
+
+ Method m = cl1.loadClass("test.XMLFactoryHelper").getMethod("instantiateXMLService", String.class);
+ for (String service : services1) {
+ Object o = m.invoke(null, service);
+ Layer providerLayer = o.getClass().getModule().getLayer();
+ assertSame(providerLayer, layer1);
+ }
+
+ for (String service : services2) {
+ Object o = m.invoke(null, service);
+ Layer providerLayer = o.getClass().getModule().getLayer();
+ assertSame(providerLayer, Layer.boot());
+ }
+
+ }
+
+ /*
+ * layer 1 is created on top of boot layer, layer 1 includes module provider1.
+ * layer 2 is created on top of layer 1, layer 2 includes module provider2.
+ *
+ * Instantiate each XML service, verify the services provided by provider1
+ * are loaded from layer 1, the services provided by provider2 are loaded from layer 2
+ */
+ public void testTwoLayer() throws Exception {
+ ModuleFinder finder1 = ModuleFinder.of(MOD_DIR1);
+ Configuration cf1 = Layer.boot().configuration()
+ .resolveRequiresAndUses(finder1, empty(), Set.of("test"));
+ ClassLoader scl = ClassLoader.getSystemClassLoader();
+ Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, scl);
+
+ ModuleFinder finder2 = ModuleFinder.of(MOD_DIR2);
+ Configuration cf2 = cf1.resolveRequiresAndUses(finder2, empty(), Set.of("test"));
+ Layer layer2 = layer1.defineModulesWithOneLoader(cf2, layer1.findLoader("test"));
+ ClassLoader cl2 = layer2.findLoader("test");
+
+ Method m = cl2.loadClass("test.XMLFactoryHelper").getMethod("instantiateXMLService", String.class);
+ for (String service : services1) {
+ Object o = m.invoke(null, service);
+ Layer providerLayer = o.getClass().getModule().getLayer();
+ assertSame(providerLayer, layer1);
+ }
+
+ for (String service : services2) {
+ Object o = m.invoke(null, service);
+ Layer providerLayer = o.getClass().getModule().getLayer();
+ assertSame(providerLayer, layer2);
+ }
+
+ }
+
+ /*
+ * layer 1 is created on top of boot layer, layer 1 includes module provider1 and provider2.
+ * layer 2 is created on top of layer 1, layer 2 includes module provider2.
+ *
+ * Instantiate each XML service, verify the services provided by provider1
+ * are loaded from layer 1, the services provided by provider2 are loaded from layer 2
+ */
+ public void testTwoLayerWithDuplicate() throws Exception {
+ ModuleFinder finder1 = ModuleFinder.of(MOD_DIR1, MOD_DIR2);
+ Configuration cf1 = Layer.boot().configuration()
+ .resolveRequiresAndUses(finder1, empty(), Set.of("test"));
+ ClassLoader scl = ClassLoader.getSystemClassLoader();
+ Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, scl);
+
+ ModuleFinder finder2 = ModuleFinder.of(MOD_DIR2);
+ Configuration cf2 = cf1.resolveRequiresAndUses(finder2, empty(), Set.of("test"));
+ Layer layer2 = layer1.defineModulesWithOneLoader(cf2, layer1.findLoader("test"));
+ ClassLoader cl2 = layer2.findLoader("test");
+
+ Method m = cl2.loadClass("test.XMLFactoryHelper").getMethod("instantiateXMLService", String.class);
+ for (String service : services1) {
+ Object o = m.invoke(null, service);
+ Layer providerLayer = o.getClass().getModule().getLayer();
+ assertSame(providerLayer, layer1);
+ }
+
+ for (String service : services2) {
+ Object o = m.invoke(null, service);
+ Layer providerLayer = o.getClass().getModule().getLayer();
+ assertSame(providerLayer, layer2);
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/test/module-info.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+module test {
+ requires java.xml;
+ exports test;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/test/test/XMLFactoryHelper.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test;
+
+import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
+
+import java.lang.Class;
+import java.lang.String;
+import java.lang.System;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+public class XMLFactoryHelper {
+ /*
+ * instantiate a xml factory by reflection e.g.
+ * DocumentBuilderFactory.newInstance()
+ */
+ public static Object instantiateXMLService(String serviceName) throws Exception {
+ ClassLoader backup = Thread.currentThread().getContextClassLoader();
+ try {
+ // set thread context class loader to module class loader
+ Thread.currentThread().setContextClassLoader(XMLFactoryHelper.class.getClassLoader());
+ if (serviceName.equals("javax.xml.validation.SchemaFactory"))
+ return Class.forName(serviceName).getMethod("newInstance", String.class)
+ .invoke(null, W3C_XML_SCHEMA_NS_URI);
+ else
+ return Class.forName(serviceName).getMethod("newInstance").invoke(null);
+ } finally {
+ Thread.currentThread().setContextClassLoader(backup);
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/unnamed/Main.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
+
+import java.lang.reflect.Layer;
+import java.lang.reflect.Module;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Stream;
+
+public class Main {
+ /*
+ * @param args, the names of provider modules, which have been loaded
+ */
+ public static void main(String[] args) throws Exception {
+ Module xml = Layer.boot().findModule("java.xml").get();
+
+ Set<String> allServices = new HashSet<>(Arrays.asList(expectedAllServices));
+ if (!allServices.equals(xml.getDescriptor().uses()))
+ throw new AssertionError("Expect xml module uses: " + allServices + " But actually uses: "
+ + xml.getDescriptor().uses());
+
+ long violationCount = Stream.of(args)
+ .map(xmlProviderName -> Layer.boot().findModule(xmlProviderName).get())
+ .mapToLong(
+ // services provided by the implementation in provider module
+ provider -> provider.getDescriptor().provides().keySet().stream()
+ .filter(serviceName -> {
+ allServices.remove(serviceName); // remove service provided by
+ // customized module from allServices
+ return !belongToModule(serviceName, instantiateXMLService(serviceName), provider);
+ }).count())
+ .sum();
+
+ // the remaining services should be provided by the default implementation
+ violationCount += allServices.stream()
+ .filter(serviceName -> !belongToModule(serviceName, instantiateXMLService(serviceName), xml))
+ .count();
+
+ if (violationCount > 0)
+ throw new AssertionError(violationCount + " services are not provided by expected module");
+ }
+
+ /*
+ * instantiate a xml factory by reflection e.g.
+ * DocumentBuilderFactory.newInstance()
+ */
+ private static Object instantiateXMLService(String serviceName) {
+ try {
+ if (serviceName.equals("javax.xml.validation.SchemaFactory"))
+ return Class.forName(serviceName).getMethod("newInstance", String.class)
+ .invoke(null, W3C_XML_SCHEMA_NS_URI);
+ else
+ return Class.forName(serviceName).getMethod("newInstance").invoke(null);
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ throw new RuntimeException(e);
+ }
+ }
+
+ /*
+ * verify which module provides the xml factory
+ */
+ private static boolean belongToModule(String factoryName, Object factory, Module expected) {
+ Module actual = factory.getClass().getModule();
+ if (!actual.equals(expected)) {
+ System.err.println("Expect " + factoryName + " is provided by " + expected
+ + ", but actual implementation " + factory.getClass() + " is provided by " + actual);
+ return false;
+ } else {
+ System.out.println(factory.getClass() + " is provided by " + expected);
+ return true;
+ }
+ }
+
+ /*
+ * This list equals the declarations in java.xml module-info.java
+ */
+ private static final String[] expectedAllServices = { "javax.xml.datatype.DatatypeFactory",
+ "javax.xml.parsers.DocumentBuilderFactory", "javax.xml.parsers.SAXParserFactory",
+ "javax.xml.stream.XMLEventFactory", "javax.xml.stream.XMLInputFactory",
+ "javax.xml.stream.XMLOutputFactory", "javax.xml.transform.TransformerFactory",
+ "javax.xml.validation.SchemaFactory", "javax.xml.xpath.XPathFactory" };
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider1/module-info.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+module xmlprovider1 {
+ requires java.xml;
+
+ provides javax.xml.parsers.DocumentBuilderFactory with xp1.DocumentBuilderFactoryImpl;
+ provides javax.xml.parsers.SAXParserFactory with xp1.SAXParserFactoryImpl;
+ provides javax.xml.stream.XMLInputFactory with xp1.XMLInputFactoryImpl;
+ provides javax.xml.stream.XMLOutputFactory with xp1.XMLOutputFactoryImpl;
+ provides javax.xml.transform.TransformerFactory with xp1.TransformerFactoryImpl;
+ provides javax.xml.validation.SchemaFactory with xp1.SchemaFactoryImpl;
+ provides javax.xml.xpath.XPathFactory with xp1.XPathFactoryImpl;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider1/xp1/DocumentBuilderFactoryImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package xp1;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+public class DocumentBuilderFactoryImpl extends DocumentBuilderFactory {
+
+ @Override
+ public DocumentBuilder newDocumentBuilder() throws ParserConfigurationException {
+ return null;
+ }
+
+ @Override
+ public void setAttribute(String name, Object value) throws IllegalArgumentException {
+
+ }
+
+ @Override
+ public Object getAttribute(String name) throws IllegalArgumentException {
+ return null;
+ }
+
+ @Override
+ public void setFeature(String name, boolean value) throws ParserConfigurationException {
+
+ }
+
+ @Override
+ public boolean getFeature(String name) throws ParserConfigurationException {
+ return false;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider1/xp1/SAXParserFactoryImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package xp1;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+
+public class SAXParserFactoryImpl extends SAXParserFactory {
+
+ @Override
+ public SAXParser newSAXParser() throws ParserConfigurationException, SAXException {
+ return null;
+ }
+
+ @Override
+ public void setFeature(String name, boolean value) throws ParserConfigurationException,
+ SAXNotRecognizedException, SAXNotSupportedException {
+
+ }
+
+ @Override
+ public boolean getFeature(String name) throws ParserConfigurationException, SAXNotRecognizedException,
+ SAXNotSupportedException {
+ return false;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider1/xp1/SchemaFactoryImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package xp1;
+
+import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
+
+import javax.xml.transform.Source;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+
+import org.w3c.dom.ls.LSResourceResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+
+public class SchemaFactoryImpl extends SchemaFactory {
+
+ @Override
+ public boolean isSchemaLanguageSupported(String schemaLanguage) {
+ // must be true, otherwise JAXP library will deny this impl
+ if (schemaLanguage.equals(W3C_XML_SCHEMA_NS_URI))
+ return true;
+ else
+ return false;
+ }
+
+ @Override
+ public void setErrorHandler(ErrorHandler errorHandler) {
+
+ }
+
+ @Override
+ public ErrorHandler getErrorHandler() {
+ return null;
+ }
+
+ @Override
+ public void setResourceResolver(LSResourceResolver resourceResolver) {
+
+ }
+
+ @Override
+ public LSResourceResolver getResourceResolver() {
+ return null;
+ }
+
+ @Override
+ public Schema newSchema(Source[] schemas) throws SAXException {
+ return null;
+ }
+
+ @Override
+ public Schema newSchema() throws SAXException {
+ return null;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider1/xp1/TransformerFactoryImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package xp1;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.Source;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.URIResolver;
+
+public class TransformerFactoryImpl extends TransformerFactory {
+
+ @Override
+ public Transformer newTransformer(Source source) throws TransformerConfigurationException {
+ return null;
+ }
+
+ @Override
+ public Transformer newTransformer() throws TransformerConfigurationException {
+ return null;
+ }
+
+ @Override
+ public Templates newTemplates(Source source) throws TransformerConfigurationException {
+ return null;
+ }
+
+ @Override
+ public Source getAssociatedStylesheet(Source source, String media, String title, String charset)
+ throws TransformerConfigurationException {
+ return null;
+ }
+
+ @Override
+ public void setURIResolver(URIResolver resolver) {
+
+ }
+
+ @Override
+ public URIResolver getURIResolver() {
+ return null;
+ }
+
+ @Override
+ public void setFeature(String name, boolean value) throws TransformerConfigurationException {
+
+ }
+
+ @Override
+ public boolean getFeature(String name) {
+ return false;
+ }
+
+ @Override
+ public void setAttribute(String name, Object value) {
+
+ }
+
+ @Override
+ public Object getAttribute(String name) {
+ return null;
+ }
+
+ @Override
+ public void setErrorListener(ErrorListener listener) {
+
+ }
+
+ @Override
+ public ErrorListener getErrorListener() {
+ return null;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider1/xp1/XMLInputFactoryImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package xp1;
+
+import java.io.InputStream;
+import java.io.Reader;
+
+import javax.xml.stream.EventFilter;
+import javax.xml.stream.StreamFilter;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLReporter;
+import javax.xml.stream.XMLResolver;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.util.XMLEventAllocator;
+import javax.xml.transform.Source;
+
+public class XMLInputFactoryImpl extends XMLInputFactory {
+
+ @Override
+ public XMLStreamReader createXMLStreamReader(Reader reader) throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLStreamReader createXMLStreamReader(Source source) throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLStreamReader createXMLStreamReader(InputStream stream) throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLStreamReader createXMLStreamReader(InputStream stream, String encoding)
+ throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLStreamReader createXMLStreamReader(String systemId, InputStream stream)
+ throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLStreamReader createXMLStreamReader(String systemId, Reader reader) throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLEventReader createXMLEventReader(Reader reader) throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLEventReader createXMLEventReader(String systemId, Reader reader) throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLEventReader createXMLEventReader(XMLStreamReader reader) throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLEventReader createXMLEventReader(Source source) throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLEventReader createXMLEventReader(InputStream stream) throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLEventReader createXMLEventReader(InputStream stream, String encoding) throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLEventReader createXMLEventReader(String systemId, InputStream stream) throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLStreamReader createFilteredReader(XMLStreamReader reader, StreamFilter filter)
+ throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLEventReader createFilteredReader(XMLEventReader reader, EventFilter filter)
+ throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLResolver getXMLResolver() {
+ return null;
+ }
+
+ @Override
+ public void setXMLResolver(XMLResolver resolver) {
+
+ }
+
+ @Override
+ public XMLReporter getXMLReporter() {
+ return null;
+ }
+
+ @Override
+ public void setXMLReporter(XMLReporter reporter) {
+
+ }
+
+ @Override
+ public void setProperty(String name, Object value) throws IllegalArgumentException {
+
+ }
+
+ @Override
+ public Object getProperty(String name) throws IllegalArgumentException {
+ return null;
+ }
+
+ @Override
+ public boolean isPropertySupported(String name) {
+ return false;
+ }
+
+ @Override
+ public void setEventAllocator(XMLEventAllocator allocator) {
+
+ }
+
+ @Override
+ public XMLEventAllocator getEventAllocator() {
+ return null;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider1/xp1/XMLOutputFactoryImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package xp1;
+
+import java.io.OutputStream;
+import java.io.Writer;
+
+import javax.xml.stream.XMLEventWriter;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Result;
+
+public class XMLOutputFactoryImpl extends XMLOutputFactory {
+
+ @Override
+ public XMLStreamWriter createXMLStreamWriter(Writer stream) throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLStreamWriter createXMLStreamWriter(OutputStream stream) throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLStreamWriter createXMLStreamWriter(OutputStream stream, String encoding)
+ throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLStreamWriter createXMLStreamWriter(Result result) throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLEventWriter createXMLEventWriter(Result result) throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLEventWriter createXMLEventWriter(OutputStream stream) throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLEventWriter createXMLEventWriter(OutputStream stream, String encoding)
+ throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public XMLEventWriter createXMLEventWriter(Writer stream) throws XMLStreamException {
+ return null;
+ }
+
+ @Override
+ public void setProperty(String name, Object value) throws IllegalArgumentException {
+
+ }
+
+ @Override
+ public Object getProperty(String name) throws IllegalArgumentException {
+ return null;
+ }
+
+ @Override
+ public boolean isPropertySupported(String name) {
+ return false;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider1/xp1/XPathFactoryImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package xp1;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathFactory;
+import javax.xml.xpath.XPathFactoryConfigurationException;
+import javax.xml.xpath.XPathFunctionResolver;
+import javax.xml.xpath.XPathVariableResolver;
+
+public class XPathFactoryImpl extends XPathFactory {
+
+ @Override
+ public boolean isObjectModelSupported(String objectModel) {
+ // must be true, otherwise JAXP library will deny this impl
+ return true;
+ }
+
+ @Override
+ public void setFeature(String name, boolean value) throws XPathFactoryConfigurationException {
+
+ }
+
+ @Override
+ public boolean getFeature(String name) throws XPathFactoryConfigurationException {
+ return false;
+ }
+
+ @Override
+ public void setXPathVariableResolver(XPathVariableResolver resolver) {
+
+ }
+
+ @Override
+ public void setXPathFunctionResolver(XPathFunctionResolver resolver) {
+
+ }
+
+ @Override
+ public XPath newXPath() {
+ return null;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider2/module-info.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+module xmlprovider2 {
+ requires java.xml;
+
+ provides javax.xml.datatype.DatatypeFactory with xp2.DatatypeFactoryImpl;
+ provides javax.xml.stream.XMLEventFactory with xp2.XMLEventFactoryImpl;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider2/xp2/DatatypeFactoryImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package xp2;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.GregorianCalendar;
+
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.Duration;
+import javax.xml.datatype.XMLGregorianCalendar;
+
+public class DatatypeFactoryImpl extends DatatypeFactory {
+
+ @Override
+ public Duration newDuration(String lexicalRepresentation) {
+ return null;
+ }
+
+ @Override
+ public Duration newDuration(long durationInMilliSeconds) {
+ return null;
+ }
+
+ @Override
+ public Duration newDuration(boolean isPositive, BigInteger years, BigInteger months, BigInteger days,
+ BigInteger hours, BigInteger minutes, BigDecimal seconds) {
+ return null;
+ }
+
+ @Override
+ public XMLGregorianCalendar newXMLGregorianCalendar() {
+ return null;
+ }
+
+ @Override
+ public XMLGregorianCalendar newXMLGregorianCalendar(String lexicalRepresentation) {
+ return null;
+ }
+
+ @Override
+ public XMLGregorianCalendar newXMLGregorianCalendar(GregorianCalendar cal) {
+ return null;
+ }
+
+ @Override
+ public XMLGregorianCalendar newXMLGregorianCalendar(BigInteger year, int month, int day, int hour,
+ int minute, int second, BigDecimal fractionalSecond, int timezone) {
+ return null;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider2/xp2/XMLEventFactoryImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package xp2;
+
+import java.util.Iterator;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLEventFactory;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.Characters;
+import javax.xml.stream.events.Comment;
+import javax.xml.stream.events.DTD;
+import javax.xml.stream.events.EndDocument;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.EntityDeclaration;
+import javax.xml.stream.events.EntityReference;
+import javax.xml.stream.events.Namespace;
+import javax.xml.stream.events.ProcessingInstruction;
+import javax.xml.stream.events.StartDocument;
+import javax.xml.stream.events.StartElement;
+
+public class XMLEventFactoryImpl extends XMLEventFactory {
+
+ @Override
+ public void setLocation(Location location) {
+
+ }
+
+ @Override
+ public Attribute createAttribute(String prefix, String namespaceURI, String localName, String value) {
+ return null;
+ }
+
+ @Override
+ public Attribute createAttribute(String localName, String value) {
+ return null;
+ }
+
+ @Override
+ public Attribute createAttribute(QName name, String value) {
+ return null;
+ }
+
+ @Override
+ public Namespace createNamespace(String namespaceURI) {
+ return null;
+ }
+
+ @Override
+ public Namespace createNamespace(String prefix, String namespaceUri) {
+ return null;
+ }
+
+ @Override
+ public StartElement createStartElement(QName name, Iterator attributes, Iterator namespaces) {
+ return null;
+ }
+
+ @Override
+ public StartElement createStartElement(String prefix, String namespaceUri, String localName) {
+ return null;
+ }
+
+ @Override
+ public StartElement createStartElement(String prefix, String namespaceUri, String localName,
+ Iterator attributes, Iterator namespaces) {
+ return null;
+ }
+
+ @Override
+ public StartElement createStartElement(String prefix, String namespaceUri, String localName,
+ Iterator attributes, Iterator namespaces, NamespaceContext context) {
+ return null;
+ }
+
+ @Override
+ public EndElement createEndElement(QName name, Iterator namespaces) {
+ return null;
+ }
+
+ @Override
+ public EndElement createEndElement(String prefix, String namespaceUri, String localName) {
+ return null;
+ }
+
+ @Override
+ public EndElement createEndElement(String prefix, String namespaceUri, String localName,
+ Iterator namespaces) {
+ return null;
+ }
+
+ @Override
+ public Characters createCharacters(String content) {
+ return null;
+ }
+
+ @Override
+ public Characters createCData(String content) {
+ return null;
+ }
+
+ @Override
+ public Characters createSpace(String content) {
+ return null;
+ }
+
+ @Override
+ public Characters createIgnorableSpace(String content) {
+ return null;
+ }
+
+ @Override
+ public StartDocument createStartDocument() {
+ return null;
+ }
+
+ @Override
+ public StartDocument createStartDocument(String encoding, String version, boolean standalone) {
+ return null;
+ }
+
+ @Override
+ public StartDocument createStartDocument(String encoding, String version) {
+ return null;
+ }
+
+ @Override
+ public StartDocument createStartDocument(String encoding) {
+ return null;
+ }
+
+ @Override
+ public EndDocument createEndDocument() {
+ return null;
+ }
+
+ @Override
+ public EntityReference createEntityReference(String name, EntityDeclaration declaration) {
+ return null;
+ }
+
+ @Override
+ public Comment createComment(String text) {
+ return null;
+ }
+
+ @Override
+ public ProcessingInstruction createProcessingInstruction(String target, String data) {
+ return null;
+ }
+
+ @Override
+ public DTD createDTD(String dtd) {
+ return null;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/TEST.properties Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,5 @@
+# Tests that must run in othervm mode
+othervm.dirs= .
+
+# Declare module dependency
+modules=java.xml
--- a/jaxp/test/javax/xml/jaxp/unittest/TEST.properties Thu Apr 28 00:38:21 2016 -0700
+++ b/jaxp/test/javax/xml/jaxp/unittest/TEST.properties Thu Apr 28 23:08:17 2016 -0700
@@ -4,5 +4,6 @@
lib.dirs = /javax/xml/jaxp/libs
# Declare module dependency
-modules=java.xml/com.sun.org.apache.xerces.internal.jaxp \
+modules=java.xml/com.sun.org.apache.xerces.internal.impl \
+ java.xml/com.sun.org.apache.xerces.internal.jaxp \
java.xml/com.sun.org.apache.xml.internal.serialize
--- a/jaxp/test/javax/xml/jaxp/unittest/stream/XMLEventReaderTest/Bug6668115Test.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jaxp/test/javax/xml/jaxp/unittest/stream/XMLEventReaderTest/Bug6668115Test.java Thu Apr 28 23:08:17 2016 -0700
@@ -28,7 +28,6 @@
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.events.XMLEvent;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -74,7 +73,7 @@
er.nextTag();
er.nextTag();
- XMLEvent event = er.peek();
+ er.peek();
System.out.println(er.getElementText());
er.nextTag();
System.out.println(er.getElementText());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/stream/XMLEventReaderTest/Bug8153781.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package stream.XMLEventReaderTest;
+
+import java.io.StringReader;
+
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.XMLEvent;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
+
+/*
+ * @bug 8153781
+ * @summary Test if method skipDTD of class XMLDTDScannerImpl will correctly skip the DTD section,
+ * even if a call to XMLEntityScanner.scanData for skipping to the closing ']' returns true.
+ */
+public class Bug8153781 {
+ public static int DOCTYPE_SECTION_LENGTH = XMLEntityManager.DEFAULT_BUFFER_SIZE * 2;
+ public static int DOCUMENT_LENGTH = DOCTYPE_SECTION_LENGTH + 4096;
+
+ public String createXMLDocument(int doctypeoffset) {
+ StringBuilder xmlcontentbuilder = new StringBuilder(DOCUMENT_LENGTH);
+ xmlcontentbuilder.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n");
+ xmlcontentbuilder.append("<!DOCTYPE dummy [\r\n");
+ xmlcontentbuilder.append(" <!ELEMENT dummy EMPTY>\r\n");
+ xmlcontentbuilder.append(" <!--\r\n");
+ int doctypelines = DOCTYPE_SECTION_LENGTH / 3;
+ for (int i = 0; i < doctypeoffset; i++)
+ xmlcontentbuilder.append('a');
+ for (int i = 0; i < doctypelines; i++)
+ xmlcontentbuilder.append("a\r\n");
+ xmlcontentbuilder.append(" -->\r\n");
+ xmlcontentbuilder.append(" ]\r\n");
+ xmlcontentbuilder.append(">\r\n");
+ xmlcontentbuilder.append("<dummy>\r\n");
+ xmlcontentbuilder.append("</dummy>\r\n");
+ System.out.println("Document length:" + xmlcontentbuilder.length());
+ return xmlcontentbuilder.toString();
+ }
+
+ public void runReader(XMLInputFactory factory, int offset) throws XMLStreamException {
+ StringReader stringReader = new StringReader(createXMLDocument(offset));
+ XMLEventReader reader = factory.createXMLEventReader(stringReader);
+
+ while (reader.hasNext()) {
+ XMLEvent event = reader.nextEvent();
+ System.out.println("Event Type: " + event.getEventType());
+ }
+ }
+
+ @Test
+ public void test() {
+ try {
+ XMLInputFactory factory = XMLInputFactory.newInstance();
+ factory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
+ for (int i = 0; i < 3; i++) {
+ runReader(factory, i);
+ }
+ } catch (XMLStreamException xe) {
+ xe.printStackTrace();
+ Assert.fail(xe.getMessage());
+ }
+ }
+}
--- a/jaxws/.hgtags Thu Apr 28 00:38:21 2016 -0700
+++ b/jaxws/.hgtags Thu Apr 28 23:08:17 2016 -0700
@@ -360,3 +360,4 @@
21274e7937bae291658d68143aca0e3ee9296db0 jdk-9+112
e980062475c10d21137051045bf95ee229db9b27 jdk-9+113
b314bb02182b9ca94708a91f312c377f5435f740 jdk-9+114
+4ff86e5489e4c0513dadfa69def8601c110ca5cd jdk-9+115
--- a/jdk/.hgtags Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/.hgtags Thu Apr 28 23:08:17 2016 -0700
@@ -358,3 +358,4 @@
68f8be44b6a6b33dfa841ec671c0ba6e4056b372 jdk-9+113
bb8379287f3736f38c52b2d1418784e2592461d1 jdk-9+114
35225b837d66582037eeadeb471c13235dfd793d jdk-9+115
+baeb5edb38939cdb78ae0ac6f4fd368465cbf188 jdk-9+116
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/launcher/Launcher-jdk.jstatd.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,30 @@
+#
+# 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. 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.
+#
+
+include LauncherCommon.gmk
+
+$(eval $(call SetupBuildLauncher, jstatd, \
+ MAIN_CLASS := sun.tools.jstatd.Jstatd, \
+))
--- a/jdk/make/launcher/Launcher-jdk.jvmstat.rmi.gmk Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +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. 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.
-#
-
-include LauncherCommon.gmk
-
-$(eval $(call SetupBuildLauncher, jstatd, \
- MAIN_CLASS := sun.tools.jstatd.Jstatd, \
-))
--- a/jdk/make/lib/CoreLibraries.gmk Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/make/lib/CoreLibraries.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -267,7 +267,7 @@
LDFLAGS_windows := -export:JIMAGE_Open -export:JIMAGE_Close \
-export:JIMAGE_PackageToModule \
-export:JIMAGE_FindResource -export:JIMAGE_GetResource \
- -export:JIMAGE_ResourceIterator, \
+ -export:JIMAGE_ResourceIterator -export:JIMAGE_ResourcePath, \
LIBS_unix := -ljvm -ldl $(LIBCXX), \
LIBS_solaris := -lc, \
LIBS_macosx := -lc++, \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/lib/Lib-jdk.net.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. 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.
+#
+
+include LibCommon.gmk
+
+################################################################################
+
+ifeq ($(OPENJDK_TARGET_OS), solaris)
+
+ $(eval $(call SetupNativeCompilation, BUILD_LIBEXTNET, \
+ LIBRARY := extnet, \
+ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ SRC := $(JDK_TOPDIR)/src/jdk.net/solaris/native/libextnet, \
+ OPTIMIZATION := LOW, \
+ CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/jdk.net, \
+ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libextnet/mapfile-vers, \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
+ $(call SET_SHARED_LIBRARY_ORIGIN), \
+ LIBS := -lsocket -lc -ljava, \
+ OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libextnet, \
+ ))
+
+ $(BUILD_LIBEXTNET): $(call FindLib, java.base, java)
+
+ TARGETS += $(BUILD_LIBEXTNET)
+endif
+
+
+################################################################################
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/mapfiles/libextnet/mapfile-vers Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. 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.
+#
+
+SUNWprivate_1.1 {
+ global:
+ Java_jdk_net_SolarisSocketOptions_init;
+ Java_jdk_net_SolarisSocketOptions_setFlowOption;
+ Java_jdk_net_SolarisSocketOptions_getFlowOption;
+ Java_jdk_net_SolarisSocketOptions_flowSupported;
+ local:
+ *;
+};
--- a/jdk/make/mapfiles/libjimage/mapfile-vers Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/make/mapfiles/libjimage/mapfile-vers Thu Apr 28 23:08:17 2016 -0700
@@ -34,6 +34,7 @@
JIMAGE_FindResource;
JIMAGE_GetResource;
JIMAGE_ResourceIterator;
+ JIMAGE_ResourcePath;
local:
*;
};
--- a/jdk/make/mapfiles/libnet/mapfile-vers Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/make/mapfiles/libnet/mapfile-vers Thu Apr 28 23:08:17 2016 -0700
@@ -98,10 +98,6 @@
Java_sun_net_sdp_SdpSupport_create0;
Java_sun_net_spi_DefaultProxySelector_init;
Java_sun_net_spi_DefaultProxySelector_getSystemProxy;
- Java_sun_net_ExtendedOptionsImpl_init;
- Java_sun_net_ExtendedOptionsImpl_setFlowOption;
- Java_sun_net_ExtendedOptionsImpl_getFlowOption;
- Java_sun_net_ExtendedOptionsImpl_flowSupported;
NET_AllocSockaddr;
NET_SockaddrToInetAddress;
NET_SockaddrEqualsInetAddress;
--- a/jdk/make/netbeans/client_sanity/nbproject/genfiles.properties Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/make/netbeans/client_sanity/nbproject/genfiles.properties Thu Apr 28 23:08:17 2016 -0700
@@ -3,6 +3,6 @@
build.xml.stylesheet.CRC32=8064a381@1.75.2.48
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=55414227
+nbproject/build-impl.xml.data.CRC32=16caf60f
nbproject/build-impl.xml.script.CRC32=c12f9d04
nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48
--- a/jdk/make/netbeans/client_sanity/nbproject/project.properties Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/make/netbeans/client_sanity/nbproject/project.properties Thu Apr 28 23:08:17 2016 -0700
@@ -76,4 +76,4 @@
src.src.dir=..\\..\\..\\test\\sanity\\client\\SwingSet\\src
src.src2.dir=..\\..\\..\\test\\sanity\\client\\lib\\SwingSet3\\src
src.src3.dir=..\\..\\..\\test\\sanity\\client\\lib\\jemmy\\src
-src.src4.dir=..\\..\\..\\test\\sanity\\client\\lib\\Jemmy2Ext\\src
+src.src4.dir=..\\..\\..\\test\\sanity\\client\\lib\\Extensions\\src
--- a/jdk/make/netbeans/client_sanity/nbproject/project.xml Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/make/netbeans/client_sanity/nbproject/project.xml Thu Apr 28 23:08:17 2016 -0700
@@ -6,7 +6,7 @@
<name>SanityTests</name>
<source-roots>
<root id="src.src3.dir" name="lib\jemmy\src"/>
- <root id="src.src4.dir" name="lib\Jemmy2Ext\src"/>
+ <root id="src.src4.dir" name="lib\Extensions\src"/>
<root id="src.src2.dir" name="lib\SwingSet3\src"/>
<root id="src.src.dir" name="SwingSet\src"/>
</source-roots>
--- a/jdk/make/src/classes/build/tools/module/GenModuleInfoSource.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/make/src/classes/build/tools/module/GenModuleInfoSource.java Thu Apr 28 23:08:17 2016 -0700
@@ -52,7 +52,7 @@
"Usage: GenModuleInfoSource [option] -o <output file> <module-info-java>\n" +
"Options are:\n" +
" -exports <package-name>\n" +
- " -exports <package-name>/<module-name>\n" +
+ " -exports <package-name>[/<module-name>]\n" +
" -uses <service>\n" +
" -provides <service>/<provider-impl-classname>\n";
--- a/jdk/src/java.base/aix/native/libnet/aix_close.c Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/aix/native/libnet/aix_close.c Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, SAP SE and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -50,6 +51,8 @@
...
*/
+#include <assert.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
@@ -86,10 +89,35 @@
static int sigWakeup = (SIGRTMAX - 1);
/*
- * The fd table and the number of file descriptors
+ * fdTable holds one entry per file descriptor, up to a certain
+ * maximum.
+ * Theoretically, the number of possible file descriptors can get
+ * large, though usually it does not. Entries for small value file
+ * descriptors are kept in a simple table, which covers most scenarios.
+ * Entries for large value file descriptors are kept in an overflow
+ * table, which is organized as a sparse two dimensional array whose
+ * slabs are allocated on demand. This covers all corner cases while
+ * keeping memory consumption reasonable.
*/
-static fdEntry_t *fdTable = NULL;
-static int fdCount = 0;
+
+/* Base table for low value file descriptors */
+static fdEntry_t* fdTable = NULL;
+/* Maximum size of base table (in number of entries). */
+static const int fdTableMaxSize = 0x1000; /* 4K */
+/* Actual size of base table (in number of entries) */
+static int fdTableLen = 0;
+/* Max. theoretical number of file descriptors on system. */
+static int fdLimit = 0;
+
+/* Overflow table, should base table not be large enough. Organized as
+ * an array of n slabs, each holding 64k entries.
+ */
+static fdEntry_t** fdOverflowTable = NULL;
+/* Number of slabs in the overflow table */
+static int fdOverflowTableLen = 0;
+/* Number of entries in one slab */
+static const int fdOverflowTableSlabSize = 0x10000; /* 64k */
+pthread_mutex_t fdOverflowTableLock = PTHREAD_MUTEX_INITIALIZER;
/*
* Null signal handler
@@ -108,42 +136,42 @@
struct rlimit nbr_files;
sigset_t sigset;
struct sigaction sa;
+ int i = 0;
- /* Check already initialized */
- if (fdCount > 0 && fdTable != NULL) {
- return;
- }
-
- /*
- * Allocate table based on the maximum number of
- * file descriptors.
- */
+ /* Determine the maximum number of possible file descriptors. */
if (-1 == getrlimit(RLIMIT_NOFILE, &nbr_files)) {
fprintf(stderr, "library initialization failed - "
"unable to get max # of allocated fds\n");
abort();
}
- fdCount = nbr_files.rlim_max;
- /*
- * We have a conceptual problem here, when the number of files is
- * unlimited. As a kind of workaround, we ensure the table is big
- * enough for handle even a large number of files. Since SAP itself
- * recommends a limit of 32000 files, we just use 64000 as 'infinity'.
- */
- if (nbr_files.rlim_max == RLIM_INFINITY) {
- fdCount = 64000;
+ if (nbr_files.rlim_max != RLIM_INFINITY) {
+ fdLimit = nbr_files.rlim_max;
+ } else {
+ /* We just do not know. */
+ fdLimit = INT_MAX;
}
- fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
+
+ /* Allocate table for low value file descriptors. */
+ fdTableLen = fdLimit < fdTableMaxSize ? fdLimit : fdTableMaxSize;
+ fdTable = (fdEntry_t*) calloc(fdTableLen, sizeof(fdEntry_t));
if (fdTable == NULL) {
fprintf(stderr, "library initialization failed - "
"unable to allocate file descriptor table - out of memory");
abort();
+ } else {
+ for (i = 0; i < fdTableLen; i ++) {
+ pthread_mutex_init(&fdTable[i].lock, NULL);
+ }
}
- {
- int i;
- for (i=0; i < fdCount; i++) {
- pthread_mutex_init(&fdTable[i].lock, NULL);
+ /* Allocate overflow table, if needed */
+ if (fdLimit > fdTableMaxSize) {
+ fdOverflowTableLen = ((fdLimit - fdTableMaxSize) / fdOverflowTableSlabSize) + 1;
+ fdOverflowTable = (fdEntry_t**) calloc(fdOverflowTableLen, sizeof(fdEntry_t*));
+ if (fdOverflowTable == NULL) {
+ fprintf(stderr, "library initialization failed - "
+ "unable to allocate file descriptor overflow table - out of memory");
+ abort();
}
}
@@ -161,17 +189,60 @@
}
/*
- * Return the fd table for this fd or NULL is fd out
- * of range.
+ * Return the fd table for this fd.
*/
static inline fdEntry_t *getFdEntry(int fd)
{
- if (fd < 0 || fd >= fdCount) {
+ fdEntry_t* result = NULL;
+
+ if (fd < 0) {
return NULL;
}
- return &fdTable[fd];
+
+ /* This should not happen. If it does, our assumption about
+ * max. fd value was wrong. */
+ assert(fd < fdLimit);
+
+ if (fd < fdTableMaxSize) {
+ /* fd is in base table. */
+ assert(fd < fdTableLen);
+ result = &fdTable[fd];
+ } else {
+ /* fd is in overflow table. */
+ const int indexInOverflowTable = fd - fdTableMaxSize;
+ const int rootindex = indexInOverflowTable / fdOverflowTableSlabSize;
+ const int slabindex = indexInOverflowTable % fdOverflowTableSlabSize;
+ fdEntry_t* slab = NULL;
+ assert(rootindex < fdOverflowTableLen);
+ assert(slabindex < fdOverflowTableSlabSize);
+ pthread_mutex_lock(&fdOverflowTableLock);
+ /* Allocate new slab in overflow table if needed */
+ if (fdOverflowTable[rootindex] == NULL) {
+ fdEntry_t* const newSlab =
+ (fdEntry_t*)calloc(fdOverflowTableSlabSize, sizeof(fdEntry_t));
+ if (newSlab == NULL) {
+ fprintf(stderr, "Unable to allocate file descriptor overflow"
+ " table slab - out of memory");
+ pthread_mutex_unlock(&fdOverflowTableLock);
+ abort();
+ } else {
+ int i;
+ for (i = 0; i < fdOverflowTableSlabSize; i ++) {
+ pthread_mutex_init(&newSlab[i].lock, NULL);
+ }
+ fdOverflowTable[rootindex] = newSlab;
+ }
+ }
+ pthread_mutex_unlock(&fdOverflowTableLock);
+ slab = fdOverflowTable[rootindex];
+ result = &slab[slabindex];
+ }
+
+ return result;
+
}
+
/*
* Start a blocking operation :-
* Insert thread onto thread list for the fd.
--- a/jdk/src/java.base/linux/native/libnet/linux_close.c Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/linux/native/libnet/linux_close.c Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,8 @@
* questions.
*/
+#include <assert.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
@@ -59,10 +61,35 @@
static int sigWakeup = (__SIGRTMAX - 2);
/*
- * The fd table and the number of file descriptors
+ * fdTable holds one entry per file descriptor, up to a certain
+ * maximum.
+ * Theoretically, the number of possible file descriptors can get
+ * large, though usually it does not. Entries for small value file
+ * descriptors are kept in a simple table, which covers most scenarios.
+ * Entries for large value file descriptors are kept in an overflow
+ * table, which is organized as a sparse two dimensional array whose
+ * slabs are allocated on demand. This covers all corner cases while
+ * keeping memory consumption reasonable.
*/
-static fdEntry_t *fdTable;
-static int fdCount;
+
+/* Base table for low value file descriptors */
+static fdEntry_t* fdTable = NULL;
+/* Maximum size of base table (in number of entries). */
+static const int fdTableMaxSize = 0x1000; /* 4K */
+/* Actual size of base table (in number of entries) */
+static int fdTableLen = 0;
+/* Max. theoretical number of file descriptors on system. */
+static int fdLimit = 0;
+
+/* Overflow table, should base table not be large enough. Organized as
+ * an array of n slabs, each holding 64k entries.
+ */
+static fdEntry_t** fdOverflowTable = NULL;
+/* Number of slabs in the overflow table */
+static int fdOverflowTableLen = 0;
+/* Number of entries in one slab */
+static const int fdOverflowTableSlabSize = 0x10000; /* 64k */
+pthread_mutex_t fdOverflowTableLock = PTHREAD_MUTEX_INITIALIZER;
/*
* Null signal handler
@@ -78,18 +105,43 @@
struct rlimit nbr_files;
sigset_t sigset;
struct sigaction sa;
+ int i = 0;
- /*
- * Allocate table based on the maximum number of
- * file descriptors.
- */
- getrlimit(RLIMIT_NOFILE, &nbr_files);
- fdCount = nbr_files.rlim_max;
- fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
+ /* Determine the maximum number of possible file descriptors. */
+ if (-1 == getrlimit(RLIMIT_NOFILE, &nbr_files)) {
+ fprintf(stderr, "library initialization failed - "
+ "unable to get max # of allocated fds\n");
+ abort();
+ }
+ if (nbr_files.rlim_max != RLIM_INFINITY) {
+ fdLimit = nbr_files.rlim_max;
+ } else {
+ /* We just do not know. */
+ fdLimit = INT_MAX;
+ }
+
+ /* Allocate table for low value file descriptors. */
+ fdTableLen = fdLimit < fdTableMaxSize ? fdLimit : fdTableMaxSize;
+ fdTable = (fdEntry_t*) calloc(fdTableLen, sizeof(fdEntry_t));
if (fdTable == NULL) {
fprintf(stderr, "library initialization failed - "
"unable to allocate file descriptor table - out of memory");
abort();
+ } else {
+ for (i = 0; i < fdTableLen; i ++) {
+ pthread_mutex_init(&fdTable[i].lock, NULL);
+ }
+ }
+
+ /* Allocate overflow table, if needed */
+ if (fdLimit > fdTableMaxSize) {
+ fdOverflowTableLen = ((fdLimit - fdTableMaxSize) / fdOverflowTableSlabSize) + 1;
+ fdOverflowTable = (fdEntry_t**) calloc(fdOverflowTableLen, sizeof(fdEntry_t*));
+ if (fdOverflowTable == NULL) {
+ fprintf(stderr, "library initialization failed - "
+ "unable to allocate file descriptor overflow table - out of memory");
+ abort();
+ }
}
/*
@@ -106,15 +158,57 @@
}
/*
- * Return the fd table for this fd or NULL is fd out
- * of range.
+ * Return the fd table for this fd.
*/
static inline fdEntry_t *getFdEntry(int fd)
{
- if (fd < 0 || fd >= fdCount) {
+ fdEntry_t* result = NULL;
+
+ if (fd < 0) {
return NULL;
}
- return &fdTable[fd];
+
+ /* This should not happen. If it does, our assumption about
+ * max. fd value was wrong. */
+ assert(fd < fdLimit);
+
+ if (fd < fdTableMaxSize) {
+ /* fd is in base table. */
+ assert(fd < fdTableLen);
+ result = &fdTable[fd];
+ } else {
+ /* fd is in overflow table. */
+ const int indexInOverflowTable = fd - fdTableMaxSize;
+ const int rootindex = indexInOverflowTable / fdOverflowTableSlabSize;
+ const int slabindex = indexInOverflowTable % fdOverflowTableSlabSize;
+ fdEntry_t* slab = NULL;
+ assert(rootindex < fdOverflowTableLen);
+ assert(slabindex < fdOverflowTableSlabSize);
+ pthread_mutex_lock(&fdOverflowTableLock);
+ /* Allocate new slab in overflow table if needed */
+ if (fdOverflowTable[rootindex] == NULL) {
+ fdEntry_t* const newSlab =
+ (fdEntry_t*)calloc(fdOverflowTableSlabSize, sizeof(fdEntry_t));
+ if (newSlab == NULL) {
+ fprintf(stderr, "Unable to allocate file descriptor overflow"
+ " table slab - out of memory");
+ pthread_mutex_unlock(&fdOverflowTableLock);
+ abort();
+ } else {
+ int i;
+ for (i = 0; i < fdOverflowTableSlabSize; i ++) {
+ pthread_mutex_init(&newSlab[i].lock, NULL);
+ }
+ fdOverflowTable[rootindex] = newSlab;
+ }
+ }
+ pthread_mutex_unlock(&fdOverflowTableLock);
+ slab = fdOverflowTable[rootindex];
+ result = &slab[slabindex];
+ }
+
+ return result;
+
}
/*
--- a/jdk/src/java.base/macosx/native/libnet/bsd_close.c Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/macosx/native/libnet/bsd_close.c Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,8 @@
* questions.
*/
+#include <assert.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/param.h>
@@ -61,18 +63,35 @@
static int sigWakeup = SIGIO;
/*
- * The fd table and the number of file descriptors
+ * fdTable holds one entry per file descriptor, up to a certain
+ * maximum.
+ * Theoretically, the number of possible file descriptors can get
+ * large, though usually it does not. Entries for small value file
+ * descriptors are kept in a simple table, which covers most scenarios.
+ * Entries for large value file descriptors are kept in an overflow
+ * table, which is organized as a sparse two dimensional array whose
+ * slabs are allocated on demand. This covers all corner cases while
+ * keeping memory consumption reasonable.
*/
-static fdEntry_t *fdTable;
-static int fdCount;
-/*
- * This limit applies if getlimit() returns unlimited.
- * Unfortunately, this means if someone wants a higher limit
- * then they have to set an explicit limit, higher than this,
- * which is probably counter-intuitive.
+/* Base table for low value file descriptors */
+static fdEntry_t* fdTable = NULL;
+/* Maximum size of base table (in number of entries). */
+static const int fdTableMaxSize = 0x1000; /* 4K */
+/* Actual size of base table (in number of entries) */
+static int fdTableLen = 0;
+/* Max. theoretical number of file descriptors on system. */
+static int fdLimit = 0;
+
+/* Overflow table, should base table not be large enough. Organized as
+ * an array of n slabs, each holding 64k entries.
*/
-#define MAX_FD_COUNT 4096
+static fdEntry_t** fdOverflowTable = NULL;
+/* Number of slabs in the overflow table */
+static int fdOverflowTableLen = 0;
+/* Number of entries in one slab */
+static const int fdOverflowTableSlabSize = 0x10000; /* 64k */
+pthread_mutex_t fdOverflowTableLock = PTHREAD_MUTEX_INITIALIZER;
/*
* Null signal handler
@@ -88,26 +107,43 @@
struct rlimit nbr_files;
sigset_t sigset;
struct sigaction sa;
- int i;
+ int i = 0;
- /*
- * Allocate table based on the maximum number of
- * file descriptors.
- */
- getrlimit(RLIMIT_NOFILE, &nbr_files);
- if (nbr_files.rlim_max == RLIM_INFINITY) {
- fdCount = MAX_FD_COUNT;
+ /* Determine the maximum number of possible file descriptors. */
+ if (-1 == getrlimit(RLIMIT_NOFILE, &nbr_files)) {
+ fprintf(stderr, "library initialization failed - "
+ "unable to get max # of allocated fds\n");
+ abort();
+ }
+ if (nbr_files.rlim_max != RLIM_INFINITY) {
+ fdLimit = nbr_files.rlim_max;
} else {
- fdCount = nbr_files.rlim_max;
+ /* We just do not know. */
+ fdLimit = INT_MAX;
}
- fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
+
+ /* Allocate table for low value file descriptors. */
+ fdTableLen = fdLimit < fdTableMaxSize ? fdLimit : fdTableMaxSize;
+ fdTable = (fdEntry_t*) calloc(fdTableLen, sizeof(fdEntry_t));
if (fdTable == NULL) {
fprintf(stderr, "library initialization failed - "
"unable to allocate file descriptor table - out of memory");
abort();
+ } else {
+ for (i = 0; i < fdTableLen; i ++) {
+ pthread_mutex_init(&fdTable[i].lock, NULL);
+ }
}
- for (i=0; i<fdCount; i++) {
- pthread_mutex_init(&fdTable[i].lock, NULL);
+
+ /* Allocate overflow table, if needed */
+ if (fdLimit > fdTableMaxSize) {
+ fdOverflowTableLen = ((fdLimit - fdTableMaxSize) / fdOverflowTableSlabSize) + 1;
+ fdOverflowTable = (fdEntry_t**) calloc(fdOverflowTableLen, sizeof(fdEntry_t*));
+ if (fdOverflowTable == NULL) {
+ fprintf(stderr, "library initialization failed - "
+ "unable to allocate file descriptor overflow table - out of memory");
+ abort();
+ }
}
/*
@@ -124,17 +160,60 @@
}
/*
- * Return the fd table for this fd or NULL is fd out
- * of range.
+ * Return the fd table for this fd.
*/
static inline fdEntry_t *getFdEntry(int fd)
{
- if (fd < 0 || fd >= fdCount) {
+ fdEntry_t* result = NULL;
+
+ if (fd < 0) {
return NULL;
}
- return &fdTable[fd];
+
+ /* This should not happen. If it does, our assumption about
+ * max. fd value was wrong. */
+ assert(fd < fdLimit);
+
+ if (fd < fdTableMaxSize) {
+ /* fd is in base table. */
+ assert(fd < fdTableLen);
+ result = &fdTable[fd];
+ } else {
+ /* fd is in overflow table. */
+ const int indexInOverflowTable = fd - fdTableMaxSize;
+ const int rootindex = indexInOverflowTable / fdOverflowTableSlabSize;
+ const int slabindex = indexInOverflowTable % fdOverflowTableSlabSize;
+ fdEntry_t* slab = NULL;
+ assert(rootindex < fdOverflowTableLen);
+ assert(slabindex < fdOverflowTableSlabSize);
+ pthread_mutex_lock(&fdOverflowTableLock);
+ /* Allocate new slab in overflow table if needed */
+ if (fdOverflowTable[rootindex] == NULL) {
+ fdEntry_t* const newSlab =
+ (fdEntry_t*)calloc(fdOverflowTableSlabSize, sizeof(fdEntry_t));
+ if (newSlab == NULL) {
+ fprintf(stderr, "Unable to allocate file descriptor overflow"
+ " table slab - out of memory");
+ pthread_mutex_unlock(&fdOverflowTableLock);
+ abort();
+ } else {
+ int i;
+ for (i = 0; i < fdOverflowTableSlabSize; i ++) {
+ pthread_mutex_init(&newSlab[i].lock, NULL);
+ }
+ fdOverflowTable[rootindex] = newSlab;
+ }
+ }
+ pthread_mutex_unlock(&fdOverflowTableLock);
+ slab = fdOverflowTable[rootindex];
+ result = &slab[slabindex];
+ }
+
+ return result;
+
}
+
/*
* Start a blocking operation :-
* Insert thread onto thread list for the fd.
--- a/jdk/src/java.base/share/classes/java/lang/Runtime.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Runtime.java Thu Apr 28 23:08:17 2016 -0700
@@ -718,41 +718,27 @@
}
/**
- * Enables/Disables tracing of instructions.
- * If the {@code boolean} argument is {@code true}, this
- * method suggests that the Java virtual machine emit debugging
- * information for each instruction in the virtual machine as it
- * is executed. The format of this information, and the file or other
- * output stream to which it is emitted, depends on the host environment.
- * The virtual machine may ignore this request if it does not support
- * this feature. The destination of the trace output is system
- * dependent.
- * <p>
- * If the {@code boolean} argument is {@code false}, this
- * method causes the virtual machine to stop performing the
- * detailed instruction trace it is performing.
+ * Not implemented, does nothing.
*
- * @param on {@code true} to enable instruction tracing;
- * {@code false} to disable this feature.
+ * @deprecated
+ * This method was intended to control instruction tracing.
+ * It has been superseded by JVM-specific tracing mechanisms.
+ *
+ * @param on ignored
*/
+ @Deprecated(since="9", forRemoval=true)
public void traceInstructions(boolean on) { }
/**
- * Enables/Disables tracing of method calls.
- * If the {@code boolean} argument is {@code true}, this
- * method suggests that the Java virtual machine emit debugging
- * information for each method in the virtual machine as it is
- * called. The format of this information, and the file or other output
- * stream to which it is emitted, depends on the host environment. The
- * virtual machine may ignore this request if it does not support
- * this feature.
- * <p>
- * Calling this method with argument false suggests that the
- * virtual machine cease emitting per-call debugging information.
+ * Not implemented, does nothing.
*
- * @param on {@code true} to enable instruction tracing;
- * {@code false} to disable this feature.
+ * @deprecated
+ * This method was intended to control method call tracing.
+ * It has been superseded by JVM-specific tracing mechanisms.
+ *
+ * @param on ignored
*/
+ @Deprecated(since="9", forRemoval=true)
public void traceMethodCalls(boolean on) { }
/**
--- a/jdk/src/java.base/share/classes/java/lang/System.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/System.java Thu Apr 28 23:08:17 2016 -0700
@@ -1155,8 +1155,9 @@
* @param level the log message level.
* @param msg the string message (or a key in the message catalog, if
* this logger is a {@link
- * LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class)
- * localized logger}); can be {@code null}.
+ * LoggerFinder#getLocalizedLogger(java.lang.String,
+ * java.util.ResourceBundle, java.lang.reflect.Module) localized logger});
+ * can be {@code null}.
*
* @throws NullPointerException if {@code level} is {@code null}.
*/
@@ -1222,8 +1223,9 @@
* @param level the log message level.
* @param msg the string message (or a key in the message catalog, if
* this logger is a {@link
- * LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class)
- * localized logger}); can be {@code null}.
+ * LoggerFinder#getLocalizedLogger(java.lang.String,
+ * java.util.ResourceBundle, java.lang.reflect.Module) localized logger});
+ * can be {@code null}.
* @param thrown a {@code Throwable} associated with the log message;
* can be {@code null}.
*
@@ -1270,8 +1272,9 @@
* @param format the string message format in {@link
* java.text.MessageFormat} format, (or a key in the message
* catalog, if this logger is a {@link
- * LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class)
- * localized logger}); can be {@code null}.
+ * LoggerFinder#getLocalizedLogger(java.lang.String,
+ * java.util.ResourceBundle, java.lang.reflect.Module) localized logger});
+ * can be {@code null}.
* @param params an optional list of parameters to the message (may be
* none).
*
@@ -1453,30 +1456,30 @@
/**
* Returns an instance of {@link Logger Logger}
- * for the given {@code caller}.
+ * for the given {@code module}.
*
* @param name the name of the logger.
- * @param caller the class for which the logger is being requested.
+ * @param module the module for which the logger is being requested.
*
- * @return a {@link Logger logger} suitable for the given caller's
- * use.
+ * @return a {@link Logger logger} suitable for use within the given
+ * module.
* @throws NullPointerException if {@code name} is {@code null} or
- * {@code caller} is {@code null}.
+ * {@code module} is {@code null}.
* @throws SecurityException if a security manager is present and its
* {@code checkPermission} method doesn't allow the
* {@code RuntimePermission("loggerFinder")}.
*/
- public abstract Logger getLogger(String name, /* Module */ Class<?> caller);
+ public abstract Logger getLogger(String name, Module module);
/**
* Returns a localizable instance of {@link Logger Logger}
- * for the given {@code caller}.
+ * for the given {@code module}.
* The returned logger will use the provided resource bundle for
* message localization.
*
* @implSpec By default, this method calls {@link
- * #getLogger(java.lang.String, java.lang.Class)
- * this.getLogger(name, caller)} to obtain a logger, then wraps that
+ * #getLogger(java.lang.String, java.lang.reflect.Module)
+ * this.getLogger(name, module)} to obtain a logger, then wraps that
* logger in a {@link Logger} instance where all methods that do not
* take a {@link ResourceBundle} as parameter are redirected to one
* which does - passing the given {@code bundle} for
@@ -1499,19 +1502,19 @@
*
* @param name the name of the logger.
* @param bundle a resource bundle; can be {@code null}.
- * @param caller the class for which the logger is being requested.
+ * @param module the module for which the logger is being requested.
* @return an instance of {@link Logger Logger} which will use the
* provided resource bundle for message localization.
*
* @throws NullPointerException if {@code name} is {@code null} or
- * {@code caller} is {@code null}.
+ * {@code module} is {@code null}.
* @throws SecurityException if a security manager is present and its
* {@code checkPermission} method doesn't allow the
* {@code RuntimePermission("loggerFinder")}.
*/
public Logger getLocalizedLogger(String name, ResourceBundle bundle,
- /* Module */ Class<?> caller) {
- return new LocalizedLoggerWrapper<>(getLogger(name, caller), bundle);
+ Module module) {
+ return new LocalizedLoggerWrapper<>(getLogger(name, module), bundle);
}
/**
@@ -1558,12 +1561,13 @@
*
* @implSpec
* Instances returned by this method route messages to loggers
- * obtained by calling {@link LoggerFinder#getLogger(java.lang.String, java.lang.Class)
- * LoggerFinder.getLogger(name, caller)}.
+ * obtained by calling {@link LoggerFinder#getLogger(java.lang.String,
+ * java.lang.reflect.Module) LoggerFinder.getLogger(name, module)}, where
+ * {@code module} is the caller's module.
*
* @apiNote
* This method may defer calling the {@link
- * LoggerFinder#getLogger(java.lang.String, java.lang.Class)
+ * LoggerFinder#getLogger(java.lang.String, java.lang.reflect.Module)
* LoggerFinder.getLogger} method to create an actual logger supplied by
* the logging backend, for instance, to allow loggers to be obtained during
* the system initialization time.
@@ -1579,7 +1583,7 @@
public static Logger getLogger(String name) {
Objects.requireNonNull(name);
final Class<?> caller = Reflection.getCallerClass();
- return LazyLoggers.getLogger(name, caller);
+ return LazyLoggers.getLogger(name, caller.getModule());
}
/**
@@ -1591,8 +1595,9 @@
* @implSpec
* The returned logger will perform message localization as specified
* by {@link LoggerFinder#getLocalizedLogger(java.lang.String,
- * java.util.ResourceBundle, java.lang.Class)
- * LoggerFinder.getLocalizedLogger(name, bundle, caller}.
+ * java.util.ResourceBundle, java.lang.reflect.Module)
+ * LoggerFinder.getLocalizedLogger(name, bundle, module}, where
+ * {@code module} is the caller's module.
*
* @apiNote
* This method is intended to be used after the system is fully initialized.
@@ -1624,12 +1629,14 @@
// Bootstrap sensitive classes in the JDK do not use resource bundles
// when logging. This could be revisited later, if it needs to.
if (sm != null) {
- return AccessController.doPrivileged((PrivilegedAction<Logger>)
- () -> LoggerFinder.accessProvider().getLocalizedLogger(name, rb, caller),
- null,
- LoggerFinder.LOGGERFINDER_PERMISSION);
+ final PrivilegedAction<Logger> pa =
+ () -> LoggerFinder.accessProvider()
+ .getLocalizedLogger(name, rb, caller.getModule());
+ return AccessController.doPrivileged(pa, null,
+ LoggerFinder.LOGGERFINDER_PERMISSION);
}
- return LoggerFinder.accessProvider().getLocalizedLogger(name, rb, caller);
+ return LoggerFinder.accessProvider()
+ .getLocalizedLogger(name, rb, caller.getModule());
}
/**
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -25,6 +25,7 @@
package java.lang.invoke;
+import java.lang.reflect.Array;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
@@ -1892,7 +1893,8 @@
MH_tryFinallyExec = 12,
MH_tryFinallyVoidExec = 13,
MH_decrementCounter = 14,
- MH_LIMIT = 15;
+ MH_Array_newInstance = 15,
+ MH_LIMIT = 16;
static MethodHandle getConstantHandle(int idx) {
MethodHandle handle = HANDLES[idx];
@@ -1965,6 +1967,9 @@
case MH_decrementCounter:
return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "decrementCounter",
MethodType.methodType(int.class, int.class));
+ case MH_Array_newInstance:
+ return IMPL_LOOKUP.findStatic(Array.class, "newInstance",
+ MethodType.methodType(Object.class, Class.class, int.class));
}
} catch (ReflectiveOperationException ex) {
throw newInternalError(ex);
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Thu Apr 28 23:08:17 2016 -0700
@@ -25,34 +25,38 @@
package java.lang.invoke;
-import java.lang.reflect.*;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.reflect.CallerSensitive;
+import jdk.internal.reflect.Reflection;
+import sun.invoke.util.ValueConversions;
+import sun.invoke.util.VerifyAccess;
+import sun.invoke.util.Wrapper;
+import sun.reflect.misc.ReflectUtil;
+import sun.security.util.SecurityConstants;
+
+import java.lang.invoke.LambdaForm.BasicType;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ReflectPermission;
+import java.nio.ByteOrder;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.BitSet;
import java.util.Iterator;
import java.util.List;
-import java.util.Arrays;
import java.util.Objects;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-import sun.invoke.util.ValueConversions;
-import sun.invoke.util.VerifyAccess;
-import sun.invoke.util.Wrapper;
-import jdk.internal.reflect.CallerSensitive;
-import jdk.internal.reflect.Reflection;
-import sun.reflect.misc.ReflectUtil;
-import sun.security.util.SecurityConstants;
-import java.lang.invoke.LambdaForm.BasicType;
-
-import static java.lang.invoke.MethodHandleImpl.Intrinsic;
-import static java.lang.invoke.MethodHandleNatives.Constants.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import jdk.internal.org.objectweb.asm.ClassWriter;
-import jdk.internal.org.objectweb.asm.Opcodes;
-
+import static java.lang.invoke.MethodHandleImpl.Intrinsic;
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
import static java.lang.invoke.MethodType.methodType;
@@ -741,10 +745,13 @@
if (name.startsWith("java.lang.invoke."))
throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
- // For caller-sensitive MethodHandles.lookup()
- // disallow lookup more restricted packages
+ // For caller-sensitive MethodHandles.lookup() disallow lookup from
+ // restricted packages. This a fragile and blunt approach.
+ // TODO replace with a more formal and less fragile mechanism
+ // that does not bluntly restrict classes under packages within
+ // java.base from looking up MethodHandles or VarHandles.
if (allowedModes == ALL_MODES && lookupClass.getClassLoader() == null) {
- if (name.startsWith("java.") ||
+ if ((name.startsWith("java.") && !name.startsWith("java.util.concurrent.")) ||
(name.startsWith("sun.") && !name.startsWith("sun.invoke."))) {
throw newIllegalArgumentException("illegal lookupClass: " + lookupClass);
}
@@ -1003,6 +1010,9 @@
* @throws NullPointerException if any argument is null
*/
public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+ if (refc.isArray()) {
+ throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
+ }
String name = "<init>";
MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
return getDirectConstructor(refc, ctor);
@@ -2214,6 +2224,27 @@
}
/**
+ * Produces a method handle constructing arrays of a desired type.
+ * The return type of the method handle will be the array type.
+ * The type of its sole argument will be {@code int}, which specifies the size of the array.
+ * @param arrayClass an array type
+ * @return a method handle which can create arrays of the given type
+ * @throws NullPointerException if the argument is {@code null}
+ * @throws IllegalArgumentException if {@code arrayClass} is not an array type
+ * @see java.lang.reflect.Array#newInstance(Class, int)
+ * @since 9
+ */
+ public static
+ MethodHandle arrayConstructor(Class<?> arrayClass) throws IllegalArgumentException {
+ if (!arrayClass.isArray()) {
+ throw newIllegalArgumentException("not an array class: " + arrayClass.getName());
+ }
+ MethodHandle ani = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_Array_newInstance).
+ bindTo(arrayClass.getComponentType());
+ return ani.asType(ani.type().changeReturnType(arrayClass));
+ }
+
+ /**
* Produces a method handle giving read access to elements of an array.
* The type of the method handle will have a return type of the array's
* element type. Its first argument will be the array type,
@@ -2337,13 +2368,12 @@
*
* @param viewArrayClass the view array class, with a component type of
* type {@code T}
- * @param bigEndian true if the endianness of the view array elements, as
- * stored in the underlying {@code byte} array, is big endian, otherwise
- * little endian
+ * @param byteOrder the endianness of the view array elements, as
+ * stored in the underlying {@code byte} array
* @return a VarHandle giving access to elements of a {@code byte[]} array
* viewed as if elements corresponding to the components type of the view
* array class
- * @throws NullPointerException if viewArrayClass is null
+ * @throws NullPointerException if viewArrayClass or byteOrder is null
* @throws IllegalArgumentException if viewArrayClass is not an array type
* @throws UnsupportedOperationException if the component type of
* viewArrayClass is not supported as a variable type
@@ -2351,8 +2381,10 @@
*/
public static
VarHandle byteArrayViewVarHandle(Class<?> viewArrayClass,
- boolean bigEndian) throws IllegalArgumentException {
- return VarHandles.byteArrayViewHandle(viewArrayClass, bigEndian);
+ ByteOrder byteOrder) throws IllegalArgumentException {
+ Objects.requireNonNull(byteOrder);
+ return VarHandles.byteArrayViewHandle(viewArrayClass,
+ byteOrder == ByteOrder.BIG_ENDIAN);
}
/**
@@ -2422,14 +2454,13 @@
*
* @param viewArrayClass the view array class, with a component type of
* type {@code T}
- * @param bigEndian true if the endianness of the view array elements, as
- * stored in the underlying {@code ByteBuffer}, is big endian, otherwise
- * little endian (Note this overrides the endianness of a
- * {@code ByteBuffer})
+ * @param byteOrder the endianness of the view array elements, as
+ * stored in the underlying {@code ByteBuffer} (Note this overrides the
+ * endianness of a {@code ByteBuffer})
* @return a VarHandle giving access to elements of a {@code ByteBuffer}
* viewed as if elements corresponding to the components type of the view
* array class
- * @throws NullPointerException if viewArrayClass is null
+ * @throws NullPointerException if viewArrayClass or byteOrder is null
* @throws IllegalArgumentException if viewArrayClass is not an array type
* @throws UnsupportedOperationException if the component type of
* viewArrayClass is not supported as a variable type
@@ -2437,8 +2468,10 @@
*/
public static
VarHandle byteBufferViewVarHandle(Class<?> viewArrayClass,
- boolean bigEndian) throws IllegalArgumentException {
- return VarHandles.makeByteBufferViewHandle(viewArrayClass, bigEndian);
+ ByteOrder byteOrder) throws IllegalArgumentException {
+ Objects.requireNonNull(byteOrder);
+ return VarHandles.makeByteBufferViewHandle(viewArrayClass,
+ byteOrder == ByteOrder.BIG_ENDIAN);
}
@@ -4476,12 +4509,24 @@
* @since 9
*/
public static MethodHandle countedLoop(MethodHandle start, MethodHandle end, MethodHandle init, MethodHandle body) {
- MethodHandle returnVar = dropArguments(init == null || init.type().returnType() == void.class ?
- zero(void.class) : identity(init.type().returnType()), 0, int.class, int.class);
+ Class<?> resultType;
+ MethodHandle actualInit;
+ if (init == null) {
+ resultType = body == null ? void.class : body.type().returnType();
+ actualInit = empty(methodType(resultType));
+ } else {
+ resultType = init.type().returnType();
+ actualInit = init;
+ }
+ MethodHandle defaultResultHandle = resultType == void.class ? zero(void.class) : identity(resultType);
+ MethodHandle actualBody = body == null ? dropArguments(defaultResultHandle, 0, int.class) : body;
+ MethodHandle returnVar = dropArguments(defaultResultHandle, 0, int.class, int.class);
+ MethodHandle actualEnd = end == null ? constant(int.class, 0) : end;
MethodHandle[] indexVar = {start, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopStep)};
- MethodHandle[] loopLimit = {end, null, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopPred), returnVar};
- MethodHandle[] bodyClause = {init,
- filterArgument(dropArguments(body, 1, int.class), 0,
+ MethodHandle[] loopLimit = {actualEnd, null,
+ MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopPred), returnVar};
+ MethodHandle[] bodyClause = {actualInit,
+ filterArgument(dropArguments(actualBody, 1, int.class), 0,
MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_decrementCounter))};
return loop(indexVar, loopLimit, bodyClause);
}
@@ -4572,17 +4617,24 @@
*/
public static MethodHandle iteratedLoop(MethodHandle iterator, MethodHandle init, MethodHandle body) {
checkIteratedLoop(iterator, body);
- final boolean voidInit = init == null || init.type().returnType() == void.class;
+ Class<?> resultType = init == null ?
+ body == null ? void.class : body.type().returnType() :
+ init.type().returnType();
+ boolean voidResult = resultType == void.class;
- MethodHandle initit = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_initIterator);
- MethodHandle initIterator = iterator == null ?
- initit.asType(initit.type().changeParameterType(0, body.type().parameterType(voidInit ? 1 : 2))) :
- iterator;
- Class<?> itype = initIterator.type().returnType();
+ MethodHandle initIterator;
+ if (iterator == null) {
+ MethodHandle initit = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_initIterator);
+ initIterator = initit.asType(initit.type().changeParameterType(0,
+ body.type().parameterType(voidResult ? 1 : 2)));
+ } else {
+ initIterator = iterator.asType(iterator.type().changeReturnType(Iterator.class));
+ }
+
Class<?> ttype = body.type().parameterType(0);
MethodHandle returnVar =
- dropArguments(voidInit ? zero(void.class) : identity(init.type().returnType()), 0, itype);
+ dropArguments(voidResult ? zero(void.class) : identity(resultType), 0, Iterator.class);
MethodHandle initnx = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_iterateNext);
MethodHandle nextVal = initnx.asType(initnx.type().changeReturnType(ttype));
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -284,6 +284,7 @@
* D day-of-year number 189
* M/L month-of-year number/text 7; 07; Jul; July; J
* d day-of-month number 10
+ * g modified-julian-day number 2451334
*
* Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter
* Y week-based-year year 1996; 96
@@ -308,10 +309,10 @@
*
* V time-zone ID zone-id America/Los_Angeles; Z; -08:30
* z time-zone name zone-name Pacific Standard Time; PST
- * O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00;
- * X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15;
- * x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15;
- * Z zone-offset offset-Z +0000; -0800; -08:00;
+ * O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00
+ * X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15
+ * x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15
+ * Z zone-offset offset-Z +0000; -0800; -08:00
*
* p pad next pad modifier 1
*
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java Thu Apr 28 23:08:17 2016 -0700
@@ -90,6 +90,7 @@
import java.time.format.DateTimeTextProvider.LocaleStore;
import java.time.temporal.ChronoField;
import java.time.temporal.IsoFields;
+import java.time.temporal.JulianFields;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
import java.time.temporal.TemporalQueries;
@@ -666,8 +667,11 @@
* No rounding occurs due to the maximum width - digits are simply dropped.
* <p>
* When parsing in strict mode, the number of parsed digits must be between
- * the minimum and maximum width. When parsing in lenient mode, the minimum
- * width is considered to be zero and the maximum is nine.
+ * the minimum and maximum width. In strict mode, if the minimum and maximum widths
+ * are equal and there is no decimal point then the parser will
+ * participate in adjacent value parsing, see
+ * {@link appendValue(java.time.temporal.TemporalField, int)}. When parsing in lenient mode,
+ * the minimum width is considered to be zero and the maximum is nine.
* <p>
* If the value cannot be obtained then an exception will be thrown.
* If the value is negative an exception will be thrown.
@@ -686,7 +690,12 @@
*/
public DateTimeFormatterBuilder appendFraction(
TemporalField field, int minWidth, int maxWidth, boolean decimalPoint) {
- appendInternal(new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint));
+ if (minWidth == maxWidth && decimalPoint == false) {
+ // adjacent parsing
+ appendValue(new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint));
+ } else {
+ appendInternal(new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint));
+ }
return this;
}
@@ -1383,6 +1392,7 @@
* D day-of-year number 189
* M/L month-of-year number/text 7; 07; Jul; July; J
* d day-of-month number 10
+ * g modified-julian-day number 2451334
*
* Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter
* Y week-based-year year 1996; 96
@@ -1408,9 +1418,9 @@
* V time-zone ID zone-id America/Los_Angeles; Z; -08:30
* z time-zone name zone-name Pacific Standard Time; PST
* O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00;
- * X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15;
- * x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15;
- * Z zone-offset offset-Z +0000; -0800; -08:00;
+ * X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15
+ * x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15
+ * Z zone-offset offset-Z +0000; -0800; -08:00
*
* p pad next pad modifier 1
*
@@ -1437,37 +1447,37 @@
* GGGG 4 appendText(ChronoField.ERA, TextStyle.FULL)
* GGGGG 5 appendText(ChronoField.ERA, TextStyle.NARROW)
*
- * u 1 appendValue(ChronoField.YEAR, 1, 19, SignStyle.NORMAL);
- * uu 2 appendValueReduced(ChronoField.YEAR, 2, 2000);
- * uuu 3 appendValue(ChronoField.YEAR, 3, 19, SignStyle.NORMAL);
- * u..u 4..n appendValue(ChronoField.YEAR, n, 19, SignStyle.EXCEEDS_PAD);
- * y 1 appendValue(ChronoField.YEAR_OF_ERA, 1, 19, SignStyle.NORMAL);
- * yy 2 appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2000);
- * yyy 3 appendValue(ChronoField.YEAR_OF_ERA, 3, 19, SignStyle.NORMAL);
- * y..y 4..n appendValue(ChronoField.YEAR_OF_ERA, n, 19, SignStyle.EXCEEDS_PAD);
+ * u 1 appendValue(ChronoField.YEAR, 1, 19, SignStyle.NORMAL)
+ * uu 2 appendValueReduced(ChronoField.YEAR, 2, 2000)
+ * uuu 3 appendValue(ChronoField.YEAR, 3, 19, SignStyle.NORMAL)
+ * u..u 4..n appendValue(ChronoField.YEAR, n, 19, SignStyle.EXCEEDS_PAD)
+ * y 1 appendValue(ChronoField.YEAR_OF_ERA, 1, 19, SignStyle.NORMAL)
+ * yy 2 appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2000)
+ * yyy 3 appendValue(ChronoField.YEAR_OF_ERA, 3, 19, SignStyle.NORMAL)
+ * y..y 4..n appendValue(ChronoField.YEAR_OF_ERA, n, 19, SignStyle.EXCEEDS_PAD)
* Y 1 append special localized WeekFields element for numeric week-based-year
- * YY 2 append special localized WeekFields element for reduced numeric week-based-year 2 digits;
- * YYY 3 append special localized WeekFields element for numeric week-based-year (3, 19, SignStyle.NORMAL);
- * Y..Y 4..n append special localized WeekFields element for numeric week-based-year (n, 19, SignStyle.EXCEEDS_PAD);
+ * YY 2 append special localized WeekFields element for reduced numeric week-based-year 2 digits
+ * YYY 3 append special localized WeekFields element for numeric week-based-year (3, 19, SignStyle.NORMAL)
+ * Y..Y 4..n append special localized WeekFields element for numeric week-based-year (n, 19, SignStyle.EXCEEDS_PAD)
*
- * Q 1 appendValue(IsoFields.QUARTER_OF_YEAR);
- * QQ 2 appendValue(IsoFields.QUARTER_OF_YEAR, 2);
+ * Q 1 appendValue(IsoFields.QUARTER_OF_YEAR)
+ * QQ 2 appendValue(IsoFields.QUARTER_OF_YEAR, 2)
* QQQ 3 appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.SHORT)
* QQQQ 4 appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.FULL)
* QQQQQ 5 appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.NARROW)
- * q 1 appendValue(IsoFields.QUARTER_OF_YEAR);
- * qq 2 appendValue(IsoFields.QUARTER_OF_YEAR, 2);
+ * q 1 appendValue(IsoFields.QUARTER_OF_YEAR)
+ * qq 2 appendValue(IsoFields.QUARTER_OF_YEAR, 2)
* qqq 3 appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.SHORT_STANDALONE)
* qqqq 4 appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.FULL_STANDALONE)
* qqqqq 5 appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.NARROW_STANDALONE)
*
- * M 1 appendValue(ChronoField.MONTH_OF_YEAR);
- * MM 2 appendValue(ChronoField.MONTH_OF_YEAR, 2);
+ * M 1 appendValue(ChronoField.MONTH_OF_YEAR)
+ * MM 2 appendValue(ChronoField.MONTH_OF_YEAR, 2)
* MMM 3 appendText(ChronoField.MONTH_OF_YEAR, TextStyle.SHORT)
* MMMM 4 appendText(ChronoField.MONTH_OF_YEAR, TextStyle.FULL)
* MMMMM 5 appendText(ChronoField.MONTH_OF_YEAR, TextStyle.NARROW)
- * L 1 appendValue(ChronoField.MONTH_OF_YEAR);
- * LL 2 appendValue(ChronoField.MONTH_OF_YEAR, 2);
+ * L 1 appendValue(ChronoField.MONTH_OF_YEAR)
+ * LL 2 appendValue(ChronoField.MONTH_OF_YEAR, 2)
* LLL 3 appendText(ChronoField.MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE)
* LLLL 4 appendText(ChronoField.MONTH_OF_YEAR, TextStyle.FULL_STANDALONE)
* LLLLL 5 appendText(ChronoField.MONTH_OF_YEAR, TextStyle.NARROW_STANDALONE)
@@ -1481,6 +1491,7 @@
* DD 2 appendValue(ChronoField.DAY_OF_YEAR, 2)
* DDD 3 appendValue(ChronoField.DAY_OF_YEAR, 3)
* F 1 appendValue(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH)
+ * g..g 1..n appendValue(JulianFields.MODIFIED_JULIAN_DAY, n, 19, SignStyle.NORMAL)
* E 1 appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
* EE 2 appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
* EEE 3 appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
@@ -1539,8 +1550,8 @@
* <pre>
* Pattern Count Equivalent builder methods
* ------- ----- --------------------------
- * O 1 appendLocalizedOffset(TextStyle.SHORT);
- * OOOO 4 appendLocalizedOffset(TextStyle.FULL);
+ * O 1 appendLocalizedOffset(TextStyle.SHORT)
+ * OOOO 4 appendLocalizedOffset(TextStyle.FULL)
* X 1 appendOffset("+HHmm","Z")
* XX 2 appendOffset("+HHMM","Z")
* XXX 3 appendOffset("+HH:MM","Z")
@@ -1554,7 +1565,7 @@
* Z 1 appendOffset("+HHMM","+0000")
* ZZ 2 appendOffset("+HHMM","+0000")
* ZZZ 3 appendOffset("+HHMM","+0000")
- * ZZZZ 4 appendLocalizedOffset(TextStyle.FULL);
+ * ZZZZ 4 appendLocalizedOffset(TextStyle.FULL)
* ZZZZZ 5 appendOffset("+HH:MM:ss","Z")
* </pre>
* <p>
@@ -1836,6 +1847,9 @@
throw new IllegalArgumentException("Too many pattern letters: " + cur);
}
break;
+ case 'g':
+ appendValue(field, count, 19, SignStyle.NORMAL);
+ break;
default:
if (count == 1) {
appendValue(field);
@@ -1874,6 +1888,7 @@
FIELD_MAP.put('A', ChronoField.MILLI_OF_DAY); // LDML
FIELD_MAP.put('n', ChronoField.NANO_OF_SECOND); // 310 (proposed for LDML)
FIELD_MAP.put('N', ChronoField.NANO_OF_DAY); // 310 (proposed for LDML)
+ FIELD_MAP.put('g', JulianFields.MODIFIED_JULIAN_DAY);
// 310 - z - time-zone names, matches LDML and SimpleDateFormat 1 to 4
// 310 - Z - matches SimpleDateFormat and LDML
// 310 - V - time-zone id, matches LDML
@@ -1884,7 +1899,6 @@
// LDML - U - cycle year name, not supported by 310 yet
// LDML - l - deprecated
// LDML - j - not relevant
- // LDML - g - modified-julian-day
// LDML - v,V - extended time-zone names
}
@@ -2919,11 +2933,8 @@
/**
* Prints and parses a numeric date-time field with optional padding.
*/
- static final class FractionPrinterParser implements DateTimePrinterParser {
- private final TemporalField field;
- private final int minWidth;
- private final int maxWidth;
- private final boolean decimalPoint;
+ static final class FractionPrinterParser extends NumberPrinterParser {
+ private final boolean decimalPoint;
/**
* Constructor.
@@ -2934,6 +2945,7 @@
* @param decimalPoint whether to output the localized decimal point symbol
*/
FractionPrinterParser(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint) {
+ this(field, minWidth, maxWidth, decimalPoint, 0);
Objects.requireNonNull(field, "field");
if (field.range().isFixed() == false) {
throw new IllegalArgumentException("Field must have a fixed set of values: " + field);
@@ -2948,12 +2960,61 @@
throw new IllegalArgumentException("Maximum width must exceed or equal the minimum width but " +
maxWidth + " < " + minWidth);
}
- this.field = field;
- this.minWidth = minWidth;
- this.maxWidth = maxWidth;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param field the field to output, not null
+ * @param minWidth the minimum width to output, from 0 to 9
+ * @param maxWidth the maximum width to output, from 0 to 9
+ * @param decimalPoint whether to output the localized decimal point symbol
+ * @param subsequentWidth the subsequentWidth for this instance
+ */
+ FractionPrinterParser(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint, int subsequentWidth) {
+ super(field, minWidth, maxWidth, SignStyle.NOT_NEGATIVE, subsequentWidth);
this.decimalPoint = decimalPoint;
}
+ /**
+ * Returns a new instance with fixed width flag set.
+ *
+ * @return a new updated printer-parser, not null
+ */
+ @Override
+ FractionPrinterParser withFixedWidth() {
+ if (subsequentWidth == -1) {
+ return this;
+ }
+ return new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint, -1);
+ }
+
+ /**
+ * Returns a new instance with an updated subsequent width.
+ *
+ * @param subsequentWidth the width of subsequent non-negative numbers, 0 or greater
+ * @return a new updated printer-parser, not null
+ */
+ @Override
+ FractionPrinterParser withSubsequentWidth(int subsequentWidth) {
+ return new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint, this.subsequentWidth + subsequentWidth);
+ }
+
+ /**
+ * For FractionPrinterPrinterParser, the width is fixed if context is sttrict,
+ * minWidth equal to maxWidth and decimalpoint is absent.
+ * @param context the context
+ * @return if the field is fixed width
+ * @see DateTimeFormatterBuilder#appendValueFraction(java.time.temporal.TemporalField, int, int, boolean)
+ */
+ @Override
+ boolean isFixedWidth(DateTimeParseContext context) {
+ if (context.isStrict() && minWidth == maxWidth && decimalPoint == false) {
+ return true;
+ }
+ return false;
+ }
+
@Override
public boolean format(DateTimePrintContext context, StringBuilder buf) {
Long value = context.getValue(field);
@@ -2986,8 +3047,8 @@
@Override
public int parse(DateTimeParseContext context, CharSequence text, int position) {
- int effectiveMin = (context.isStrict() ? minWidth : 0);
- int effectiveMax = (context.isStrict() ? maxWidth : 9);
+ int effectiveMin = (context.isStrict() || isFixedWidth(context) ? minWidth : 0);
+ int effectiveMax = (context.isStrict() || isFixedWidth(context) ? maxWidth : 9);
int length = text.length();
if (position == length) {
// valid if whole field is optional, invalid if minimum width
--- a/jdk/src/java.base/share/classes/java/time/temporal/JulianFields.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/time/temporal/JulianFields.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -117,7 +117,13 @@
*
* <h3>Astronomical and Scientific Notes</h3>
* The standard astronomical definition uses a fraction to indicate the time-of-day,
- * thus 3.25 would represent the time 18:00, since days start at midday.
+ * where each day is counted from midday to midday. For example,
+ * a fraction of 0 represents midday, a fraction of 0.25
+ * represents 18:00, a fraction of 0.5 represents midnight and a fraction
+ * of 0.75 represents 06:00.
+ * <p>
+ * By contrast, this implementation has no fractional part, and counts
+ * days from midnight to midnight.
* This implementation uses an integer and days starting at midnight.
* The integer value for the Julian Day Number is the astronomical Julian Day value at midday
* of the date in question.
--- a/jdk/src/java.base/share/classes/java/util/Observable.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/Observable.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,7 +58,19 @@
* @see java.util.Observer
* @see java.util.Observer#update(java.util.Observable, java.lang.Object)
* @since 1.0
+ *
+ * @deprecated
+ * This class and the {@link Observer} interface have been deprecated.
+ * The event model supported by {@code Observer} and {@code Observable}
+ * is quite limited, the order of notifications delivered by
+ * {@code Observable} is unspecified, and state changes are not in
+ * one-for-one correspondence with notifications.
+ * For a richer event model, consider using the
+ * {@link java.beans} package. For reliable and ordered
+ * messaging among threads, consider using one of the concurrent data
+ * structures in the {@link java.util.concurrent} package.
*/
+@Deprecated(since="9")
public class Observable {
private boolean changed = false;
private Vector<Observer> obs;
--- a/jdk/src/java.base/share/classes/java/util/Observer.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/Observer.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,12 @@
* @author Chris Warth
* @see java.util.Observable
* @since 1.0
+ *
+ * @deprecated
+ * This interface has been deprecated. See the {@link Observable}
+ * class for further information.
*/
+@Deprecated(since="9")
public interface Observer {
/**
* This method is called whenever the observed object is changed. An
--- a/jdk/src/java.base/share/classes/jdk/internal/jimage/BasicImageReader.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/BasicImageReader.java Thu Apr 28 23:08:17 2016 -0700
@@ -183,7 +183,9 @@
}
public static void releaseByteBuffer(ByteBuffer buffer) {
- ImageBufferCache.releaseBuffer(buffer);
+ if (!MAP_ALL) {
+ ImageBufferCache.releaseBuffer(buffer);
+ }
}
public String getName() {
--- a/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageReader.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageReader.java Thu Apr 28 23:08:17 2016 -0700
@@ -25,6 +25,7 @@
package jdk.internal.jimage;
import java.io.IOException;
+import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -36,8 +37,11 @@
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.Objects;
+import java.util.Set;
import java.util.function.Consumer;
/**
@@ -47,80 +51,486 @@
* but also compiled and delivered as part of the jrtfs.jar to support access
* to the jimage file provided by the shipped JDK by tools running on JDK 8.
*/
-public class ImageReader extends BasicImageReader {
-
- private static final int SIZE_OF_OFFSET = 4;
-
- // Map of files opened as LITTLE_ENDIAN
- private static final HashMap<Path, ImageReader> OPEN_LE_FILES
- = new HashMap<>();
-
- // Map of files opened as BIG_ENDIAN
- private static final HashMap<Path, ImageReader> OPEN_BE_FILES
- = new HashMap<>();
-
- private int openCount;
+public final class ImageReader implements AutoCloseable {
+ private SharedImageReader reader;
- // attributes of the .jimage file. jimage file does not contain
- // attributes for the individual resources (yet). We use attributes
- // of the jimage file itself (creation, modification, access times).
- // Iniitalized lazily, see {@link #imageFileAttributes()}.
- private BasicFileAttributes imageFileAttributes;
-
- // directory management implementation
- private final HashMap<String, Node> nodes;
- private volatile Directory rootDir;
-
- private Directory packagesDir;
- private Directory modulesDir;
-
- private ImageReader(Path imagePath, ByteOrder byteOrder) throws IOException {
- super(imagePath, byteOrder);
- this.nodes = new HashMap<>();
+ private ImageReader(SharedImageReader reader) {
+ this.reader = reader;
}
public static ImageReader open(Path imagePath, ByteOrder byteOrder) throws IOException {
- HashMap<Path, ImageReader> openFiles = getOpenFilesMap(byteOrder);
- ImageReader reader;
- synchronized (openFiles) {
- reader = openFiles.get(imagePath);
- if (reader == null) {
- reader = new ImageReader(imagePath, byteOrder);
- ImageReader existingReader = openFiles.putIfAbsent(imagePath, reader);
- assert (existingReader == null);
- }
- reader.openCount++;
- }
- return reader;
+ return SharedImageReader.open(imagePath, byteOrder);
}
- private static HashMap<Path, ImageReader> getOpenFilesMap(ByteOrder byteOrder) {
- return (byteOrder == ByteOrder.BIG_ENDIAN) ? OPEN_BE_FILES : OPEN_LE_FILES;
- }
-
- /**
- * Opens the given file path as an image file, returning an {@code ImageReader}.
- */
public static ImageReader open(Path imagePath) throws IOException {
return open(imagePath, ByteOrder.nativeOrder());
}
- private boolean canClose() {
- HashMap<Path, ImageReader> openFiles = getOpenFilesMap(this.getByteOrder());
- synchronized (openFiles) {
- if (--this.openCount == 0) {
- return openFiles.remove(this.getName(), this);
+ @Override
+ public void close() throws IOException {
+ if (reader == null) {
+ throw new IOException("image file already closed");
+ }
+
+ reader.close(this);
+ reader = null;
+ }
+
+ // directory management interface
+ public Directory getRootDirectory() throws IOException {
+ if (reader == null) {
+ throw new IOException("image file closed");
+ }
+ return reader.getRootDirectory();
+ }
+
+ public Node findNode(String name) throws IOException {
+ if (reader == null) {
+ throw new IOException("image file closed");
+ }
+ return reader.findNode(name);
+ }
+
+ public byte[] getResource(Node node) throws IOException {
+ if (reader == null) {
+ throw new IOException("image file closed");
+ }
+ return reader.getResource(node);
+ }
+
+ public byte[] getResource(Resource rs) throws IOException {
+ if (reader == null) {
+ throw new IOException("image file closed");
+ }
+ return reader.getResource(rs);
+ }
+
+ public ImageHeader getHeader() {
+ Objects.requireNonNull(reader, "image file closed");
+ return reader.getHeader();
+ }
+
+ public static void releaseByteBuffer(ByteBuffer buffer) {
+ BasicImageReader.releaseByteBuffer(buffer);
+ }
+
+ public String getName() {
+ Objects.requireNonNull(reader, "image file closed");
+ return reader.getName() ;
+ }
+
+ public ByteOrder getByteOrder() {
+ Objects.requireNonNull(reader, "image file closed");
+ return reader.getByteOrder();
+ }
+
+ public Path getImagePath() {
+ Objects.requireNonNull(reader, "image file closed");
+ return reader.getImagePath();
+ }
+
+ public ImageStringsReader getStrings() {
+ Objects.requireNonNull(reader, "image file closed");
+ return reader.getStrings();
+ }
+
+ public ImageLocation findLocation(String mn, String rn) {
+ Objects.requireNonNull(reader, "image file closed");
+ return reader.findLocation(mn, rn);
+ }
+
+ public ImageLocation findLocation(String name) {
+ Objects.requireNonNull(reader, "image file closed");
+ return reader.findLocation(name);
+ }
+
+ public String[] getEntryNames() {
+ Objects.requireNonNull(reader, "image file closed");
+ return reader.getEntryNames();
+ }
+
+ public long[] getAttributes(int offset) {
+ Objects.requireNonNull(reader, "image file closed");
+ return reader.getAttributes(offset);
+ }
+
+ public String getString(int offset) {
+ Objects.requireNonNull(reader, "image file closed");
+ return reader.getString(offset);
+ }
+
+ public byte[] getResource(String name) {
+ Objects.requireNonNull(reader, "image file closed");
+ return reader.getResource(name);
+ }
+
+ public byte[] getResource(ImageLocation loc) {
+ Objects.requireNonNull(reader, "image file closed");
+ return reader.getResource(loc);
+ }
+
+ public ByteBuffer getResourceBuffer(ImageLocation loc) {
+ Objects.requireNonNull(reader, "image file closed");
+ return reader.getResourceBuffer(loc);
+ }
+
+ public InputStream getResourceStream(ImageLocation loc) {
+ Objects.requireNonNull(reader, "image file closed");
+ return reader.getResourceStream(loc);
+ }
+
+ private final static class SharedImageReader extends BasicImageReader {
+ static final int SIZE_OF_OFFSET = Integer.BYTES;
+
+ static final Map<Path, SharedImageReader> OPEN_FILES = new HashMap<>();
+
+ // List of openers for this shared image.
+ final Set<ImageReader> openers;
+
+ // attributes of the .jimage file. jimage file does not contain
+ // attributes for the individual resources (yet). We use attributes
+ // of the jimage file itself (creation, modification, access times).
+ // Iniitalized lazily, see {@link #imageFileAttributes()}.
+ BasicFileAttributes imageFileAttributes;
+
+ // directory management implementation
+ final HashMap<String, Node> nodes;
+ volatile Directory rootDir;
+
+ Directory packagesDir;
+ Directory modulesDir;
+
+ private SharedImageReader(Path imagePath, ByteOrder byteOrder) throws IOException {
+ super(imagePath, byteOrder);
+ this.openers = new HashSet<>();
+ this.nodes = new HashMap<>();
+ }
+
+ public static ImageReader open(Path imagePath, ByteOrder byteOrder) throws IOException {
+ synchronized (OPEN_FILES) {
+ SharedImageReader reader = OPEN_FILES.get(imagePath);
+
+ if (reader == null) {
+ // Will fail with an IOException if wrong byteOrder.
+ reader = new SharedImageReader(imagePath, byteOrder);
+ OPEN_FILES.put(imagePath, reader);
+ } else if (reader.getByteOrder() != byteOrder) {
+ throw new IOException("\"" + reader.getName() + "\" is not an image file");
+ }
+
+ ImageReader image = new ImageReader(reader);
+ reader.openers.add(image);
+
+ return image;
+ }
+ }
+
+ public void close(ImageReader image) throws IOException {
+ synchronized (OPEN_FILES) {
+ if (!openers.remove(image)) {
+ throw new IOException("image file already closed");
+ }
+
+ if (openers.isEmpty()) {
+ close();
+ nodes.clear();
+ rootDir = null;
+
+ if (!OPEN_FILES.remove(this.getImagePath(), this)) {
+ throw new IOException("image file not found in open list");
+ }
+ }
+ }
+ }
+
+ void addOpener(ImageReader reader) {
+ synchronized (OPEN_FILES) {
+ openers.add(reader);
+ }
+ }
+
+ boolean removeOpener(ImageReader reader) {
+ synchronized (OPEN_FILES) {
+ return openers.remove(reader);
}
}
- return false;
- }
+
+ // directory management interface
+ Directory getRootDirectory() {
+ return buildRootDirectory();
+ }
+
+ /**
+ * Lazily build a node from a name.
+ */
+ synchronized Node buildNode(String name) {
+ Node n;
+ boolean isPackages = name.startsWith("/packages");
+ boolean isModules = !isPackages && name.startsWith("/modules");
+
+ if (!(isModules || isPackages)) {
+ return null;
+ }
+
+ ImageLocation loc = findLocation(name);
+
+ if (loc != null) { // A sub tree node
+ if (isPackages) {
+ n = handlePackages(name, loc);
+ } else { // modules sub tree
+ n = handleModulesSubTree(name, loc);
+ }
+ } else { // Asking for a resource? /modules/java.base/java/lang/Object.class
+ if (isModules) {
+ n = handleResource(name);
+ } else {
+ // Possibly ask for /packages/java.lang/java.base
+ // although /packages/java.base not created
+ n = handleModuleLink(name);
+ }
+ }
+ return n;
+ }
+
+ synchronized Directory buildRootDirectory() {
+ Directory root = rootDir; // volatile read
+ if (root != null) {
+ return root;
+ }
+
+ root = newDirectory(null, "/");
+ root.setIsRootDir();
+
+ // /packages dir
+ packagesDir = newDirectory(root, "/packages");
+ packagesDir.setIsPackagesDir();
+
+ // /modules dir
+ modulesDir = newDirectory(root, "/modules");
+ modulesDir.setIsModulesDir();
+
+ root.setCompleted(true);
+ return rootDir = root;
+ }
+
+ /**
+ * To visit sub tree resources.
+ */
+ interface LocationVisitor {
+ void visit(ImageLocation loc);
+ }
+
+ void visitLocation(ImageLocation loc, LocationVisitor visitor) {
+ byte[] offsets = getResource(loc);
+ ByteBuffer buffer = ByteBuffer.wrap(offsets);
+ buffer.order(getByteOrder());
+ IntBuffer intBuffer = buffer.asIntBuffer();
+ for (int i = 0; i < offsets.length / SIZE_OF_OFFSET; i++) {
+ int offset = intBuffer.get(i);
+ ImageLocation pkgLoc = getLocation(offset);
+ visitor.visit(pkgLoc);
+ }
+ }
+
+ void visitPackageLocation(ImageLocation loc) {
+ // Retrieve package name
+ String pkgName = getBaseExt(loc);
+ // Content is array of offsets in Strings table
+ byte[] stringsOffsets = getResource(loc);
+ ByteBuffer buffer = ByteBuffer.wrap(stringsOffsets);
+ buffer.order(getByteOrder());
+ IntBuffer intBuffer = buffer.asIntBuffer();
+ // For each module, create a link node.
+ for (int i = 0; i < stringsOffsets.length / SIZE_OF_OFFSET; i++) {
+ // skip empty state, useless.
+ intBuffer.get(i);
+ i++;
+ int offset = intBuffer.get(i);
+ String moduleName = getString(offset);
+ Node targetNode = findNode("/modules/" + moduleName);
+ if (targetNode != null) {
+ String pkgDirName = packagesDir.getName() + "/" + pkgName;
+ Directory pkgDir = (Directory) nodes.get(pkgDirName);
+ newLinkNode(pkgDir, pkgDir.getName() + "/" + moduleName, targetNode);
+ }
+ }
+ }
+
+ Node handlePackages(String name, ImageLocation loc) {
+ long size = loc.getUncompressedSize();
+ Node n = null;
+ // Only possiblities are /packages, /packages/package/module
+ if (name.equals("/packages")) {
+ visitLocation(loc, (childloc) -> {
+ findNode(childloc.getFullName());
+ });
+ packagesDir.setCompleted(true);
+ n = packagesDir;
+ } else {
+ if (size != 0) { // children are offsets to module in StringsTable
+ String pkgName = getBaseExt(loc);
+ Directory pkgDir = newDirectory(packagesDir, packagesDir.getName() + "/" + pkgName);
+ visitPackageLocation(loc);
+ pkgDir.setCompleted(true);
+ n = pkgDir;
+ } else { // Link to module
+ String pkgName = loc.getParent();
+ String modName = getBaseExt(loc);
+ Node targetNode = findNode("/modules/" + modName);
+ if (targetNode != null) {
+ String pkgDirName = packagesDir.getName() + "/" + pkgName;
+ Directory pkgDir = (Directory) nodes.get(pkgDirName);
+ Node linkNode = newLinkNode(pkgDir, pkgDir.getName() + "/" + modName, targetNode);
+ n = linkNode;
+ }
+ }
+ }
+ return n;
+ }
- @Override
- public void close() throws IOException {
- if (canClose()) {
- super.close();
- clearNodes();
- }
+ // Asking for /packages/package/module although
+ // /packages/<pkg>/ not yet created, need to create it
+ // prior to return the link to module node.
+ Node handleModuleLink(String name) {
+ // eg: unresolved /packages/package/module
+ // Build /packages/package node
+ Node ret = null;
+ String radical = "/packages/";
+ String path = name;
+ if (path.startsWith(radical)) {
+ int start = radical.length();
+ int pkgEnd = path.indexOf('/', start);
+ if (pkgEnd != -1) {
+ String pkg = path.substring(start, pkgEnd);
+ String pkgPath = radical + pkg;
+ Node n = findNode(pkgPath);
+ // If not found means that this is a symbolic link such as:
+ // /packages/java.util/java.base/java/util/Vector.class
+ // and will be done by a retry of the filesystem
+ for (Node child : n.getChildren()) {
+ if (child.name.equals(name)) {
+ ret = child;
+ break;
+ }
+ }
+ }
+ }
+ return ret;
+ }
+
+ Node handleModulesSubTree(String name, ImageLocation loc) {
+ Node n;
+ assert (name.equals(loc.getFullName()));
+ Directory dir = makeDirectories(name);
+ visitLocation(loc, (childloc) -> {
+ String path = childloc.getFullName();
+ if (path.startsWith("/modules")) { // a package
+ makeDirectories(path);
+ } else { // a resource
+ makeDirectories(childloc.buildName(true, true, false));
+ newResource(dir, childloc);
+ }
+ });
+ dir.setCompleted(true);
+ n = dir;
+ return n;
+ }
+
+ Node handleResource(String name) {
+ Node n = null;
+ String locationPath = name.substring("/modules".length());
+ ImageLocation resourceLoc = findLocation(locationPath);
+ if (resourceLoc != null) {
+ Directory dir = makeDirectories(resourceLoc.buildName(true, true, false));
+ Resource res = newResource(dir, resourceLoc);
+ n = res;
+ }
+ return n;
+ }
+
+ String getBaseExt(ImageLocation loc) {
+ String base = loc.getBase();
+ String ext = loc.getExtension();
+ if (ext != null && !ext.isEmpty()) {
+ base = base + "." + ext;
+ }
+ return base;
+ }
+
+ synchronized Node findNode(String name) {
+ buildRootDirectory();
+ Node n = nodes.get(name);
+ if (n == null || !n.isCompleted()) {
+ n = buildNode(name);
+ }
+ return n;
+ }
+
+ /**
+ * Returns the file attributes of the image file.
+ */
+ BasicFileAttributes imageFileAttributes() {
+ BasicFileAttributes attrs = imageFileAttributes;
+ if (attrs == null) {
+ try {
+ Path file = getImagePath();
+ attrs = Files.readAttributes(file, BasicFileAttributes.class);
+ } catch (IOException ioe) {
+ throw new UncheckedIOException(ioe);
+ }
+ imageFileAttributes = attrs;
+ }
+ return attrs;
+ }
+
+ Directory newDirectory(Directory parent, String name) {
+ Directory dir = Directory.create(parent, name, imageFileAttributes());
+ nodes.put(dir.getName(), dir);
+ return dir;
+ }
+
+ Resource newResource(Directory parent, ImageLocation loc) {
+ Resource res = Resource.create(parent, loc, imageFileAttributes());
+ nodes.put(res.getName(), res);
+ return res;
+ }
+
+ LinkNode newLinkNode(Directory dir, String name, Node link) {
+ LinkNode linkNode = LinkNode.create(dir, name, link);
+ nodes.put(linkNode.getName(), linkNode);
+ return linkNode;
+ }
+
+ Directory makeDirectories(String parent) {
+ Directory last = rootDir;
+ for (int offset = parent.indexOf('/', 1);
+ offset != -1;
+ offset = parent.indexOf('/', offset + 1)) {
+ String dir = parent.substring(0, offset);
+ last = makeDirectory(dir, last);
+ }
+ return makeDirectory(parent, last);
+
+ }
+
+ Directory makeDirectory(String dir, Directory last) {
+ Directory nextDir = (Directory) nodes.get(dir);
+ if (nextDir == null) {
+ nextDir = newDirectory(last, dir);
+ }
+ return nextDir;
+ }
+
+ byte[] getResource(Node node) throws IOException {
+ if (node.isResource()) {
+ return super.getResource(node.getLocation());
+ }
+ throw new IOException("Not a resource: " + node);
+ }
+
+ byte[] getResource(Resource rs) throws IOException {
+ return super.getResource(rs.getLocation());
+ }
}
// jimage file does not store directory structure. We build nodes
@@ -389,7 +799,7 @@
@Override
public Node resolveLink(boolean recursive) {
- return recursive && (link instanceof LinkNode)? ((LinkNode)link).resolveLink(true) : link;
+ return (recursive && link instanceof LinkNode) ? ((LinkNode)link).resolveLink(true) : link;
}
@Override
@@ -397,297 +807,4 @@
return true;
}
}
-
- // directory management interface
- public Directory getRootDirectory() {
- return buildRootDirectory();
- }
-
- /**
- * To visit sub tree resources.
- */
- interface LocationVisitor {
-
- void visit(ImageLocation loc);
- }
-
- /**
- * Lazily build a node from a name.
- */
- private Node buildNode(String name) {
- Node n;
- boolean isPackages = name.startsWith("/packages");
- boolean isModules = !isPackages && name.startsWith("/modules");
-
- if (!(isModules || isPackages)) {
- return null;
- }
-
- ImageLocation loc = findLocation(name);
-
- if (loc != null) { // A sub tree node
- if (isPackages) {
- n = handlePackages(name, loc);
- } else { // modules sub tree
- n = handleModulesSubTree(name, loc);
- }
- } else { // Asking for a resource? /modules/java.base/java/lang/Object.class
- if (isModules) {
- n = handleResource(name);
- } else {
- // Possibly ask for /packages/java.lang/java.base
- // although /packages/java.base not created
- n = handleModuleLink(name);
- }
- }
- return n;
- }
-
- private void visitLocation(ImageLocation loc, LocationVisitor visitor) {
- byte[] offsets = getResource(loc);
- ByteBuffer buffer = ByteBuffer.wrap(offsets);
- buffer.order(getByteOrder());
- IntBuffer intBuffer = buffer.asIntBuffer();
- for (int i = 0; i < offsets.length / SIZE_OF_OFFSET; i++) {
- int offset = intBuffer.get(i);
- ImageLocation pkgLoc = getLocation(offset);
- visitor.visit(pkgLoc);
- }
- }
-
- private void visitPackageLocation(ImageLocation loc) {
- // Retrieve package name
- String pkgName = getBaseExt(loc);
- // Content is array of offsets in Strings table
- byte[] stringsOffsets = getResource(loc);
- ByteBuffer buffer = ByteBuffer.wrap(stringsOffsets);
- buffer.order(getByteOrder());
- IntBuffer intBuffer = buffer.asIntBuffer();
- // For each module, create a link node.
- for (int i = 0; i < stringsOffsets.length / SIZE_OF_OFFSET; i++) {
- // skip empty state, useless.
- intBuffer.get(i);
- i++;
- int offset = intBuffer.get(i);
- String moduleName = getString(offset);
- Node targetNode = findNode("/modules/" + moduleName);
- if (targetNode != null) {
- String pkgDirName = packagesDir.getName() + "/" + pkgName;
- Directory pkgDir = (Directory) nodes.get(pkgDirName);
- newLinkNode(pkgDir, pkgDir.getName() + "/" + moduleName, targetNode);
- }
- }
- }
-
- private Node handlePackages(String name, ImageLocation loc) {
- long size = loc.getUncompressedSize();
- Node n = null;
- // Only possiblities are /packages, /packages/package/module
- if (name.equals("/packages")) {
- visitLocation(loc, (childloc) -> {
- findNode(childloc.getFullName());
- });
- packagesDir.setCompleted(true);
- n = packagesDir;
- } else {
- if (size != 0) { // children are offsets to module in StringsTable
- String pkgName = getBaseExt(loc);
- Directory pkgDir = newDirectory(packagesDir, packagesDir.getName() + "/" + pkgName);
- visitPackageLocation(loc);
- pkgDir.setCompleted(true);
- n = pkgDir;
- } else { // Link to module
- String pkgName = loc.getParent();
- String modName = getBaseExt(loc);
- Node targetNode = findNode("/modules/" + modName);
- if (targetNode != null) {
- String pkgDirName = packagesDir.getName() + "/" + pkgName;
- Directory pkgDir = (Directory) nodes.get(pkgDirName);
- Node linkNode = newLinkNode(pkgDir, pkgDir.getName() + "/" + modName, targetNode);
- n = linkNode;
- }
- }
- }
- return n;
- }
-
- // Asking for /packages/package/module although
- // /packages/<pkg>/ not yet created, need to create it
- // prior to return the link to module node.
- private Node handleModuleLink(String name) {
- // eg: unresolved /packages/package/module
- // Build /packages/package node
- Node ret = null;
- String radical = "/packages/";
- String path = name;
- if (path.startsWith(radical)) {
- int start = radical.length();
- int pkgEnd = path.indexOf('/', start);
- if (pkgEnd != -1) {
- String pkg = path.substring(start, pkgEnd);
- String pkgPath = radical + pkg;
- Node n = findNode(pkgPath);
- // If not found means that this is a symbolic link such as:
- // /packages/java.util/java.base/java/util/Vector.class
- // and will be done by a retry of the filesystem
- for (Node child : n.getChildren()) {
- if (child.name.equals(name)) {
- ret = child;
- break;
- }
- }
- }
- }
- return ret;
- }
-
- private Node handleModulesSubTree(String name, ImageLocation loc) {
- Node n;
- assert (name.equals(loc.getFullName()));
- Directory dir = makeDirectories(name);
- visitLocation(loc, (childloc) -> {
- String path = childloc.getFullName();
- if (path.startsWith("/modules")) { // a package
- makeDirectories(path);
- } else { // a resource
- makeDirectories(childloc.buildName(true, true, false));
- newResource(dir, childloc);
- }
- });
- dir.setCompleted(true);
- n = dir;
- return n;
- }
-
- private Node handleResource(String name) {
- Node n = null;
- String locationPath = name.substring("/modules".length());
- ImageLocation resourceLoc = findLocation(locationPath);
- if (resourceLoc != null) {
- Directory dir = makeDirectories(resourceLoc.buildName(true, true, false));
- Resource res = newResource(dir, resourceLoc);
- n = res;
- }
- return n;
- }
-
- private String getBaseExt(ImageLocation loc) {
- String base = loc.getBase();
- String ext = loc.getExtension();
- if (ext != null && !ext.isEmpty()) {
- base = base + "." + ext;
- }
- return base;
- }
-
- public synchronized Node findNode(String name) {
- buildRootDirectory();
- Node n = nodes.get(name);
- if (n == null || !n.isCompleted()) {
- n = buildNode(name);
- }
- return n;
- }
-
- private synchronized void clearNodes() {
- nodes.clear();
- rootDir = null;
- }
-
- /**
- * Returns the file attributes of the image file.
- */
- private BasicFileAttributes imageFileAttributes() {
- BasicFileAttributes attrs = imageFileAttributes;
- if (attrs == null) {
- try {
- Path file = getImagePath();
- attrs = Files.readAttributes(file, BasicFileAttributes.class);
- } catch (IOException ioe) {
- throw new UncheckedIOException(ioe);
- }
- imageFileAttributes = attrs;
- }
- return attrs;
- }
-
- private Directory buildRootDirectory() {
- Directory root = rootDir; // volatile read
- if (root != null) {
- return root;
- }
-
- synchronized (this) {
- root = rootDir;
- if (root != null) {
- return root;
- }
-
- // FIXME no time information per resource in jimage file (yet?)
- // we use file attributes of jimage itself.
- // root directory
- root = newDirectory(null, "/");
- root.setIsRootDir();
-
- // /packages dir
- packagesDir = newDirectory(root, "/packages");
- packagesDir.setIsPackagesDir();
-
- // /modules dir
- modulesDir = newDirectory(root, "/modules");
- modulesDir.setIsModulesDir();
-
- root.setCompleted(true);
- return rootDir = root;
- }
- }
-
- private Directory newDirectory(Directory parent, String name) {
- Directory dir = Directory.create(parent, name, imageFileAttributes());
- nodes.put(dir.getName(), dir);
- return dir;
- }
-
- private Resource newResource(Directory parent, ImageLocation loc) {
- Resource res = Resource.create(parent, loc, imageFileAttributes());
- nodes.put(res.getName(), res);
- return res;
- }
-
- private LinkNode newLinkNode(Directory dir, String name, Node link) {
- LinkNode linkNode = LinkNode.create(dir, name, link);
- nodes.put(linkNode.getName(), linkNode);
- return linkNode;
- }
-
- private Directory makeDirectories(String parent) {
- Directory last = rootDir;
- for (int offset = parent.indexOf('/', 1);
- offset != -1;
- offset = parent.indexOf('/', offset + 1)) {
- String dir = parent.substring(0, offset);
- last = makeDirectory(dir, last);
- }
- return makeDirectory(parent, last);
-
- }
-
- private Directory makeDirectory(String dir, Directory last) {
- Directory nextDir = (Directory) nodes.get(dir);
- if (nextDir == null) {
- nextDir = newDirectory(last, dir);
- }
- return nextDir;
- }
-
- public byte[] getResource(Node node) throws IOException {
- if (node.isResource()) {
- return super.getResource(node.getLocation());
- }
- throw new IOException("Not a resource: " + node);
- }
-
- public byte[] getResource(Resource rs) throws IOException {
- return super.getResource(rs.getLocation());
- }
}
--- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java Thu Apr 28 23:08:17 2016 -0700
@@ -299,13 +299,9 @@
}
// clean up this file system - called from finalize and close
- void cleanup() throws IOException {
- if (!isOpen) {
- return;
- }
- synchronized (this) {
+ synchronized void cleanup() throws IOException {
+ if (isOpen) {
isOpen = false;
- // close image reader and null out
image.close();
image = null;
}
@@ -461,8 +457,8 @@
private Node lookup(String path) {
try {
return image.findNode(path);
- } catch (RuntimeException re) {
- throw new InvalidPathException(path, re.toString());
+ } catch (RuntimeException | IOException ex) {
+ throw new InvalidPathException(path, ex.toString());
}
}
--- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/SystemImage.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/SystemImage.java Thu Apr 28 23:08:17 2016 -0700
@@ -49,7 +49,7 @@
*/
abstract class SystemImage {
- abstract Node findNode(String path);
+ abstract Node findNode(String path) throws IOException;
abstract byte[] getResource(Node node) throws IOException;
abstract void close() throws IOException;
@@ -60,7 +60,7 @@
image.getRootDirectory();
return new SystemImage() {
@Override
- Node findNode(String path) {
+ Node findNode(String path) throws IOException {
return image.findNode(path);
}
@Override
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/BootLoader.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/BootLoader.java Thu Apr 28 23:08:17 2016 -0700
@@ -30,6 +30,7 @@
import java.lang.reflect.Layer;
import java.lang.reflect.Module;
import java.net.MalformedURLException;
+import java.net.URI;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -184,9 +185,9 @@
/**
* Define the {@code Package} with the given name. The specified
- * location is a jrt URL to a named module in the run-time image, a
- * file path to a module in an exploded run-time image, or the file
- * path to an enty on the boot class path (java agent Boot-Class-Path
+ * location is a jrt URL to a named module in the run-time image,
+ * a file URL to a module in an exploded run-time image, or a file
+ * path to an entry on the boot class path (java agent Boot-Class-Path
* or -Xbootclasspath/a.
*
* <p> If the given location is a JAR file containing a manifest,
@@ -194,7 +195,9 @@
* the manifest, if present.
*
* @param name package name
- * @param location location where the package is (jrt URL or file path)
+ * @param location location where the package is (jrt URL or file URL
+ * for a named module in the run-time or exploded image;
+ * a file path for a package from -Xbootclasspath/a)
*/
static Package definePackage(String name, String location) {
Module module = findModule(location);
@@ -222,9 +225,9 @@
if (location.startsWith("jrt:/")) {
// named module in runtime image ("jrt:/".length() == 5)
mn = location.substring(5, location.length());
- } else {
+ } else if (location.startsWith("file:/")) {
// named module in exploded image
- Path path = Paths.get(location);
+ Path path = Paths.get(URI.create(location));
Path modulesDir = Paths.get(JAVA_HOME, "modules");
if (path.startsWith(modulesDir)) {
mn = path.getFileName().toString();
--- a/jdk/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java Thu Apr 28 23:08:17 2016 -0700
@@ -33,6 +33,9 @@
import java.lang.System.LoggerFinder;
import java.lang.System.Logger;
import java.lang.ref.ReferenceQueue;
+import java.lang.reflect.Module;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.Collection;
import java.util.ResourceBundle;
@@ -129,41 +132,49 @@
return w;
}
-
final static SharedLoggers system = new SharedLoggers();
final static SharedLoggers application = new SharedLoggers();
}
+ public static boolean isSystem(Module m) {
+ ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<>() {
+ @Override
+ public ClassLoader run() {
+ return m.getClassLoader();
+ }
+ });
+ return cl == null;
+ }
+
@Override
- public final Logger getLogger(String name, /* Module */ Class<?> caller) {
+ public final Logger getLogger(String name, Module module) {
checkPermission();
- return demandLoggerFor(name, caller);
+ return demandLoggerFor(name, module);
}
@Override
public final Logger getLocalizedLogger(String name, ResourceBundle bundle,
- /* Module */ Class<?> caller) {
- return super.getLocalizedLogger(name, bundle, caller);
+ Module module) {
+ return super.getLocalizedLogger(name, bundle, module);
}
-
-
/**
- * Returns a {@link Logger logger} suitable for the caller usage.
+ * Returns a {@link Logger logger} suitable for use within the
+ * given {@code module}.
*
* @implSpec The default implementation for this method is to return a
* simple logger that will print all messages of INFO level and above
* to the console. That simple logger is not configurable.
*
* @param name The name of the logger.
- * @param caller The class on behalf of which the logger is created.
+ * @param module The module on behalf of which the logger is created.
* @return A {@link Logger logger} suitable for the application usage.
* @throws SecurityException if the calling code does not have the
* {@code RuntimePermission("loggerFinder")}.
*/
- protected Logger demandLoggerFor(String name, /* Module */ Class<?> caller) {
+ protected Logger demandLoggerFor(String name, Module module) {
checkPermission();
- if (caller.getClassLoader() == null) {
+ if (isSystem(module)) {
return SharedLoggers.system.get(SimpleConsoleLogger::makeSimpleLogger, name);
} else {
return SharedLoggers.application.get(SimpleConsoleLogger::makeSimpleLogger, name);
--- a/jdk/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java Thu Apr 28 23:08:17 2016 -0700
@@ -31,6 +31,7 @@
import java.lang.System.LoggerFinder;
import java.lang.System.Logger;
import java.lang.ref.WeakReference;
+import java.lang.reflect.Module;
import java.util.Objects;
import jdk.internal.misc.VM;
import sun.util.logging.PlatformLogger;
@@ -59,15 +60,15 @@
* A factory method to create an SPI logger.
* Usually, this will be something like LazyLoggers::getSystemLogger.
*/
- final BiFunction<String, Class<?>, L> loggerSupplier;
+ final BiFunction<String, Module, L> loggerSupplier;
- public LazyLoggerFactories(BiFunction<String, Class<?>, L> loggerSupplier) {
+ public LazyLoggerFactories(BiFunction<String, Module, L> loggerSupplier) {
this(Objects.requireNonNull(loggerSupplier),
(Void)null);
}
- private LazyLoggerFactories(BiFunction<String, Class<?>, L> loggerSupplier,
+ private LazyLoggerFactories(BiFunction<String, Module, L> loggerSupplier,
Void unused) {
this.loggerSupplier = loggerSupplier;
}
@@ -107,8 +108,8 @@
// The factories that will be used to create the logger lazyly
final LazyLoggerFactories<? extends Logger> factories;
- // We need to pass the actual caller when creating the logger.
- private final WeakReference<Class<?>> callerRef;
+ // We need to pass the actual caller module when creating the logger.
+ private final WeakReference<Module> moduleRef;
// The name of the logger that will be created lazyly
final String name;
@@ -121,17 +122,17 @@
private LazyLoggerAccessor(String name,
LazyLoggerFactories<? extends Logger> factories,
- Class<?> caller) {
+ Module module) {
this(Objects.requireNonNull(name), Objects.requireNonNull(factories),
- Objects.requireNonNull(caller), null);
+ Objects.requireNonNull(module), null);
}
private LazyLoggerAccessor(String name,
LazyLoggerFactories<? extends Logger> factories,
- Class<?> caller, Void unused) {
+ Module module, Void unused) {
this.name = name;
this.factories = factories;
- this.callerRef = new WeakReference<Class<?>>(caller);
+ this.moduleRef = new WeakReference<>(module);
}
/**
@@ -270,12 +271,12 @@
// Creates the wrapped logger by invoking the SPI.
Logger createLogger() {
- final Class<?> caller = callerRef.get();
- if (caller == null) {
- throw new IllegalStateException("The class for which this logger"
+ final Module module = moduleRef.get();
+ if (module == null) {
+ throw new IllegalStateException("The module for which this logger"
+ " was created has been garbage collected");
}
- return this.factories.loggerSupplier.apply(name, caller);
+ return this.factories.loggerSupplier.apply(name, module);
}
/**
@@ -289,8 +290,8 @@
* @return A new LazyLoggerAccessor.
*/
public static LazyLoggerAccessor makeAccessor(String name,
- LazyLoggerFactories<? extends Logger> factories, Class<?> caller) {
- return new LazyLoggerAccessor(name, factories, caller);
+ LazyLoggerFactories<? extends Logger> factories, Module module) {
+ return new LazyLoggerAccessor(name, factories, module);
}
}
@@ -346,11 +347,11 @@
// Avoid using lambda here as lazy loggers could be created early
// in the bootstrap sequence...
- private static final BiFunction<String, Class<?>, Logger> loggerSupplier =
+ private static final BiFunction<String, Module, Logger> loggerSupplier =
new BiFunction<>() {
@Override
- public Logger apply(String name, Class<?> caller) {
- return LazyLoggers.getLoggerFromFinder(name, caller);
+ public Logger apply(String name, Module module) {
+ return LazyLoggers.getLoggerFromFinder(name, module);
}
};
@@ -367,8 +368,8 @@
// logger provider until the VM has finished booting.
//
private static final class JdkLazyLogger extends LazyLoggerWrapper {
- JdkLazyLogger(String name, Class<?> caller) {
- this(LazyLoggerAccessor.makeAccessor(name, factories, caller),
+ JdkLazyLogger(String name, Module module) {
+ this(LazyLoggerAccessor.makeAccessor(name, factories, module),
(Void)null);
}
private JdkLazyLogger(LazyLoggerAccessor holder, Void unused) {
@@ -380,16 +381,16 @@
* Gets a logger from the LoggerFinder. Creates the actual concrete
* logger.
* @param name name of the logger
- * @param caller class on behalf of which the logger is created
+ * @param module module on behalf of which the logger is created
* @return The logger returned by the LoggerFinder.
*/
- static Logger getLoggerFromFinder(String name, Class<?> caller) {
+ static Logger getLoggerFromFinder(String name, Module module) {
final SecurityManager sm = System.getSecurityManager();
if (sm == null) {
- return accessLoggerFinder().getLogger(name, caller);
+ return accessLoggerFinder().getLogger(name, module);
} else {
return AccessController.doPrivileged((PrivilegedAction<Logger>)
- () -> {return accessLoggerFinder().getLogger(name, caller);},
+ () -> {return accessLoggerFinder().getLogger(name, module);},
null, LOGGERFINDER_PERMISSION);
}
}
@@ -398,22 +399,22 @@
* Returns a (possibly lazy) Logger for the caller.
*
* @param name the logger name
- * @param caller The class on behalf of which the logger is created.
- * If the caller is not loaded from the Boot ClassLoader,
+ * @param module The module on behalf of which the logger is created.
+ * If the module is not loaded from the Boot ClassLoader,
* the LoggerFinder is accessed and the logger returned
- * by {@link LoggerFinder#getLogger(java.lang.String, java.lang.Class)}
+ * by {@link LoggerFinder#getLogger(java.lang.String, java.lang.reflect.Module)}
* is returned to the caller directly.
* Otherwise, the logger returned by
- * {@link #getLazyLogger(java.lang.String, java.lang.Class)}
+ * {@link #getLazyLogger(java.lang.String, java.lang.reflect.Module)}
* is returned to the caller.
*
* @return a (possibly lazy) Logger instance.
*/
- public static final Logger getLogger(String name, Class<?> caller) {
- if (caller.getClassLoader() == null) {
- return getLazyLogger(name, caller);
+ public static final Logger getLogger(String name, Module module) {
+ if (DefaultLoggerFinder.isSystem(module)) {
+ return getLazyLogger(name, module);
} else {
- return getLoggerFromFinder(name, caller);
+ return getLoggerFromFinder(name, module);
}
}
@@ -423,10 +424,10 @@
* returned by {@link BootstrapLogger#useLazyLoggers()}.
*
* @param name the logger name
- * @param caller the class on behalf of which the logger is created.
+ * @param module the module on behalf of which the logger is created.
* @return a (possibly lazy) Logger instance.
*/
- public static final Logger getLazyLogger(String name, Class<?> caller) {
+ public static final Logger getLazyLogger(String name, Module module) {
// BootstrapLogger has the logic to determine whether a LazyLogger
// should be used. Usually, it is worth it only if:
@@ -438,10 +439,10 @@
// configuration, we're not going to delay the creation of loggers...
final boolean useLazyLogger = BootstrapLogger.useLazyLoggers();
if (useLazyLogger) {
- return new JdkLazyLogger(name, caller);
+ return new JdkLazyLogger(name, module);
} else {
// Directly invoke the LoggerFinder.
- return getLoggerFromFinder(name, caller);
+ return getLoggerFromFinder(name, module);
}
}
--- a/jdk/src/java.base/share/classes/jdk/net/ExtendedSocketOptions.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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.net;
-
-import java.net.SocketOption;
-
-/**
- * Defines extended socket options, beyond those defined in
- * {@link java.net.StandardSocketOptions}. These options may be platform
- * specific.
- *
- * @since 1.8
- */
-public final class ExtendedSocketOptions {
-
- private static class ExtSocketOption<T> implements SocketOption<T> {
- private final String name;
- private final Class<T> type;
- ExtSocketOption(String name, Class<T> type) {
- this.name = name;
- this.type = type;
- }
- @Override public String name() { return name; }
- @Override public Class<T> type() { return type; }
- @Override public String toString() { return name; }
- }
-
- private ExtendedSocketOptions() {}
-
- /**
- * Service level properties. When a security manager is installed,
- * setting or getting this option requires a {@link NetworkPermission}
- * {@code ("setOption.SO_FLOW_SLA")} or {@code "getOption.SO_FLOW_SLA"}
- * respectively.
- */
- public static final SocketOption<SocketFlow> SO_FLOW_SLA = new
- ExtSocketOption<SocketFlow>("SO_FLOW_SLA", SocketFlow.class);
-}
--- a/jdk/src/java.base/share/classes/jdk/net/NetworkPermission.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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.net;
-
-import java.security.BasicPermission;
-
-/**
- * Represents permission to access the extended networking capabilities
- * defined in the jdk.net package. These permissions contain a target
- * name, but no actions list. Callers either possess the permission or not.
- * <p>
- * The following targets are defined:
- *
- * <table border=1 cellpadding=5 summary="permission target name,
- * what the target allows,and associated risks">
- * <tr>
- * <th>Permission Target Name</th>
- * <th>What the Permission Allows</th>
- * <th>Risks of Allowing this Permission</th>
- * </tr>
- * <tr>
- * <td>setOption.SO_FLOW_SLA</td>
- * <td>set the {@link ExtendedSocketOptions#SO_FLOW_SLA SO_FLOW_SLA} option
- * on any socket that supports it</td>
- * <td>allows caller to set a higher priority or bandwidth allocation
- * to sockets it creates, than they might otherwise be allowed.</td>
- * </tr>
- * <tr>
- * <td>getOption.SO_FLOW_SLA</td>
- * <td>retrieve the {@link ExtendedSocketOptions#SO_FLOW_SLA SO_FLOW_SLA}
- * setting from any socket that supports the option</td>
- * <td>allows caller access to SLA information that it might not
- * otherwise have</td>
- * </tr></table>
- *
- * @see jdk.net.ExtendedSocketOptions
- *
- * @since 1.8
- */
-
-public final class NetworkPermission extends BasicPermission {
-
- private static final long serialVersionUID = -2012939586906722291L;
-
- /**
- * Creates a NetworkPermission with the given target name.
- *
- * @param name the permission target name
- * @throws NullPointerException if {@code name} is {@code null}.
- * @throws IllegalArgumentException if {@code name} is empty.
- */
- public NetworkPermission(String name)
- {
- super(name);
- }
-
- /**
- * Creates a NetworkPermission with the given target name.
- *
- * @param name the permission target name
- * @param actions should be {@code null}. Is ignored if not.
- * @throws NullPointerException if {@code name} is {@code null}.
- * @throws IllegalArgumentException if {@code name} is empty.
- */
- public NetworkPermission(String name, String actions)
- {
- super(name, actions);
- }
-}
--- a/jdk/src/java.base/share/classes/jdk/net/SocketFlow.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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.net;
-
-import java.lang.annotation.Native;
-
-/**
- * Represents the service level properties for the platform specific socket
- * option {@link ExtendedSocketOptions#SO_FLOW_SLA}.
- * <p>
- * The priority and bandwidth parameters must be set before
- * setting the socket option.
- * <p>
- * When the {@code SO_FLOW_SLA} option is set then it may not take effect
- * immediately. If the value of the socket option is obtained with
- * {@code getOption()} then the status may be returned as {@code INPROGRESS}
- * until it takes effect. The priority and bandwidth values are only valid when
- * the status is returned as OK.
- * <p>
- * When a security manager is installed, a {@link NetworkPermission}
- * is required to set or get this option.
- *
- * @since 1.8
- */
-public class SocketFlow {
-
- private static final int UNSET = -1;
- @Native public static final int NORMAL_PRIORITY = 1;
- @Native public static final int HIGH_PRIORITY = 2;
-
- private int priority = NORMAL_PRIORITY;
-
- private long bandwidth = UNSET;
-
- private Status status = Status.NO_STATUS;
-
- private SocketFlow() {}
-
- /**
- * Enumeration of the return values from the SO_FLOW_SLA
- * socket option. Both setting and getting the option return
- * one of these statuses, which reflect the state of socket's
- * flow.
- *
- * @since 1.8
- */
- public enum Status {
- /**
- * Set or get socket option has not been called yet. Status
- * values can only be retrieved after calling set or get.
- */
- NO_STATUS,
- /**
- * Flow successfully created.
- */
- OK,
- /**
- * Caller has no permission to create flow.
- */
- NO_PERMISSION,
- /**
- * Flow can not be created because socket is not connected.
- */
- NOT_CONNECTED,
- /**
- * Flow creation not supported for this socket.
- */
- NOT_SUPPORTED,
- /**
- * A flow already exists with identical attributes.
- */
- ALREADY_CREATED,
- /**
- * A flow is being created.
- */
- IN_PROGRESS,
- /**
- * Some other unspecified error.
- */
- OTHER
- }
-
- /**
- * Creates a new SocketFlow that can be used to set the SO_FLOW_SLA
- * socket option and create a socket flow.
- */
- public static SocketFlow create() {
- return new SocketFlow();
- }
-
- /**
- * Sets this SocketFlow's priority. Must be either NORMAL_PRIORITY
- * HIGH_PRIORITY. If not set, a flow's priority is normal.
- *
- * @throws IllegalArgumentException if priority is not NORMAL_PRIORITY or
- * HIGH_PRIORITY.
- */
- public SocketFlow priority(int priority) {
- if (priority != NORMAL_PRIORITY && priority != HIGH_PRIORITY) {
- throw new IllegalArgumentException("invalid priority");
- }
- this.priority = priority;
- return this;
- }
-
- /**
- * Sets this SocketFlow's bandwidth. Must be greater than or equal to zero.
- * A value of zero drops all packets for the socket.
- *
- * @throws IllegalArgumentException if bandwidth is less than zero.
- */
- public SocketFlow bandwidth(long bandwidth) {
- if (bandwidth < 0) {
- throw new IllegalArgumentException("invalid bandwidth");
- } else {
- this.bandwidth = bandwidth;
- }
- return this;
- }
-
- /**
- * Returns this SocketFlow's priority.
- */
- public int priority() {
- return priority;
- }
-
- /**
- * Returns this SocketFlow's bandwidth.
- *
- * @return this SocketFlow's bandwidth, or {@code -1} if status is not OK.
- */
- public long bandwidth() {
- return bandwidth;
- }
-
- /**
- * Returns the Status value of this SocketFlow. NO_STATUS is returned
- * if the object was not used in a call to set or get the option.
- */
- public Status status() {
- return status;
- }
-}
--- a/jdk/src/java.base/share/classes/jdk/net/Sockets.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,339 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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.net;
-
-import java.net.*;
-import java.io.IOException;
-import java.io.FileDescriptor;
-import java.security.PrivilegedAction;
-import java.security.AccessController;
-import java.lang.reflect.Field;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Collections;
-import sun.net.ExtendedOptionsImpl;
-
-/**
- * Defines static methods to set and get socket options defined by the
- * {@link java.net.SocketOption} interface. All of the standard options defined
- * by {@link java.net.Socket}, {@link java.net.ServerSocket}, and
- * {@link java.net.DatagramSocket} can be set this way, as well as additional
- * or platform specific options supported by each socket type.
- * <p>
- * The {@link #supportedOptions(Class)} method can be called to determine
- * the complete set of options available (per socket type) on the
- * current system.
- * <p>
- * When a security manager is installed, some non-standard socket options
- * may require a security permission before being set or get.
- * The details are specified in {@link ExtendedSocketOptions}. No permission
- * is required for {@link java.net.StandardSocketOptions}.
- *
- * @see java.nio.channels.NetworkChannel
- */
-public class Sockets {
-
- private static final HashMap<Class<?>,Set<SocketOption<?>>>
- options = new HashMap<>();
-
- static {
- initOptionSets();
- }
-
- private Sockets() {}
-
- /**
- * Sets the value of a socket option on a {@link java.net.Socket}
- *
- * @param s the socket
- * @param name The socket option
- * @param value The value of the socket option. May be null for some
- * options.
- *
- * @throws UnsupportedOperationException if the socket does not support
- * the option.
- *
- * @throws IllegalArgumentException if the value is not valid for
- * the option.
- *
- * @throws IOException if an I/O error occurs, or socket is closed.
- *
- * @throws SecurityException if a security manager is set and the
- * caller does not have any required permission.
- *
- * @throws NullPointerException if name is null
- *
- * @see java.net.StandardSocketOptions
- */
- public static <T> void setOption(Socket s, SocketOption<T> name, T value) throws IOException
- {
- s.setOption(name, value);
- }
-
- /**
- * Returns the value of a socket option from a {@link java.net.Socket}
- *
- * @param s the socket
- * @param name The socket option
- *
- * @return The value of the socket option.
- *
- * @throws UnsupportedOperationException if the socket does not support
- * the option.
- *
- * @throws IOException if an I/O error occurs
- *
- * @throws SecurityException if a security manager is set and the
- * caller does not have any required permission.
- *
- * @throws NullPointerException if name is null
- *
- * @see java.net.StandardSocketOptions
- */
- public static <T> T getOption(Socket s, SocketOption<T> name) throws IOException
- {
- return s.getOption(name);
- }
-
- /**
- * Sets the value of a socket option on a {@link java.net.ServerSocket}
- *
- * @param s the socket
- * @param name The socket option
- * @param value The value of the socket option.
- *
- * @throws UnsupportedOperationException if the socket does not support
- * the option.
- *
- * @throws IllegalArgumentException if the value is not valid for
- * the option.
- *
- * @throws IOException if an I/O error occurs
- *
- * @throws NullPointerException if name is null
- *
- * @throws SecurityException if a security manager is set and the
- * caller does not have any required permission.
- *
- * @see java.net.StandardSocketOptions
- */
- public static <T> void setOption(ServerSocket s, SocketOption<T> name, T value) throws IOException
- {
- s.setOption(name, value);
- }
-
- /**
- * Returns the value of a socket option from a {@link java.net.ServerSocket}
- *
- * @param s the socket
- * @param name The socket option
- *
- * @return The value of the socket option.
- *
- * @throws UnsupportedOperationException if the socket does not support
- * the option.
- *
- * @throws IOException if an I/O error occurs
- *
- * @throws NullPointerException if name is null
- *
- * @throws SecurityException if a security manager is set and the
- * caller does not have any required permission.
- *
- * @see java.net.StandardSocketOptions
- */
- public static <T> T getOption(ServerSocket s, SocketOption<T> name) throws IOException
- {
- return s.getOption(name);
- }
-
- /**
- * Sets the value of a socket option on a {@link java.net.DatagramSocket}
- * or {@link java.net.MulticastSocket}
- *
- * @param s the socket
- * @param name The socket option
- * @param value The value of the socket option.
- *
- * @throws UnsupportedOperationException if the socket does not support
- * the option.
- *
- * @throws IllegalArgumentException if the value is not valid for
- * the option.
- *
- * @throws IOException if an I/O error occurs
- *
- * @throws NullPointerException if name is null
- *
- * @throws SecurityException if a security manager is set and the
- * caller does not have any required permission.
- *
- * @see java.net.StandardSocketOptions
- */
- public static <T> void setOption(DatagramSocket s, SocketOption<T> name, T value) throws IOException
- {
- s.setOption(name, value);
- }
-
- /**
- * Returns the value of a socket option from a
- * {@link java.net.DatagramSocket} or {@link java.net.MulticastSocket}
- *
- * @param s the socket
- * @param name The socket option
- *
- * @return The value of the socket option.
- *
- * @throws UnsupportedOperationException if the socket does not support
- * the option.
- *
- * @throws IOException if an I/O error occurs
- *
- * @throws NullPointerException if name is null
- *
- * @throws SecurityException if a security manager is set and the
- * caller does not have any required permission.
- *
- * @see java.net.StandardSocketOptions
- */
- public static <T> T getOption(DatagramSocket s, SocketOption<T> name) throws IOException
- {
- return s.getOption(name);
- }
-
- /**
- * Returns a set of {@link java.net.SocketOption}s supported by the
- * given socket type. This set may include standard options and also
- * non standard extended options.
- *
- * @param socketType the type of java.net socket
- *
- * @throws IllegalArgumentException if socketType is not a valid
- * socket type from the java.net package.
- */
- public static Set<SocketOption<?>> supportedOptions(Class<?> socketType) {
- Set<SocketOption<?>> set = options.get(socketType);
- if (set == null) {
- throw new IllegalArgumentException("unknown socket type");
- }
- return set;
- }
-
- private static void checkValueType(Object value, Class<?> type) {
- if (!type.isAssignableFrom(value.getClass())) {
- String s = "Found: " + value.getClass().toString() + " Expected: "
- + type.toString();
- throw new IllegalArgumentException(s);
- }
- }
-
- private static volatile boolean checkedReusePort;
- private static volatile boolean isReusePortAvailable;
-
- /**
- * Tells whether SO_REUSEPORT is supported.
- */
- static boolean isReusePortAvailable() {
- if (!checkedReusePort) {
- isReusePortAvailable = isReusePortAvailable0();
- checkedReusePort = true;
- }
- return isReusePortAvailable;
- }
-
- private static void initOptionSets() {
- boolean flowsupported = ExtendedOptionsImpl.flowSupported();
- boolean reuseportsupported = isReusePortAvailable();
- // Socket
-
- Set<SocketOption<?>> set = new HashSet<>();
- set.add(StandardSocketOptions.SO_KEEPALIVE);
- set.add(StandardSocketOptions.SO_SNDBUF);
- set.add(StandardSocketOptions.SO_RCVBUF);
- set.add(StandardSocketOptions.SO_REUSEADDR);
- if (reuseportsupported) {
- set.add(StandardSocketOptions.SO_REUSEPORT);
- }
- set.add(StandardSocketOptions.SO_LINGER);
- set.add(StandardSocketOptions.IP_TOS);
- set.add(StandardSocketOptions.TCP_NODELAY);
- if (flowsupported) {
- set.add(ExtendedSocketOptions.SO_FLOW_SLA);
- }
- set = Collections.unmodifiableSet(set);
- options.put(Socket.class, set);
-
- // ServerSocket
-
- set = new HashSet<>();
- set.add(StandardSocketOptions.SO_RCVBUF);
- set.add(StandardSocketOptions.SO_REUSEADDR);
- if (reuseportsupported) {
- set.add(StandardSocketOptions.SO_REUSEPORT);
- }
- set.add(StandardSocketOptions.IP_TOS);
- set = Collections.unmodifiableSet(set);
- options.put(ServerSocket.class, set);
-
- // DatagramSocket
-
- set = new HashSet<>();
- set.add(StandardSocketOptions.SO_SNDBUF);
- set.add(StandardSocketOptions.SO_RCVBUF);
- set.add(StandardSocketOptions.SO_REUSEADDR);
- if (reuseportsupported) {
- set.add(StandardSocketOptions.SO_REUSEPORT);
- }
- set.add(StandardSocketOptions.IP_TOS);
- if (flowsupported) {
- set.add(ExtendedSocketOptions.SO_FLOW_SLA);
- }
- set = Collections.unmodifiableSet(set);
- options.put(DatagramSocket.class, set);
-
- // MulticastSocket
-
- set = new HashSet<>();
- set.add(StandardSocketOptions.SO_SNDBUF);
- set.add(StandardSocketOptions.SO_RCVBUF);
- set.add(StandardSocketOptions.SO_REUSEADDR);
- if (reuseportsupported) {
- set.add(StandardSocketOptions.SO_REUSEPORT);
- }
- set.add(StandardSocketOptions.IP_TOS);
- set.add(StandardSocketOptions.IP_MULTICAST_IF);
- set.add(StandardSocketOptions.IP_MULTICAST_TTL);
- set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
- if (flowsupported) {
- set.add(ExtendedSocketOptions.SO_FLOW_SLA);
- }
- set = Collections.unmodifiableSet(set);
- options.put(MulticastSocket.class, set);
- }
-
- private static native boolean isReusePortAvailable0();
-}
--- a/jdk/src/java.base/share/classes/jdk/net/package-info.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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.
- */
-
-/**
- * Platform specific socket options for the {@code java.net} and {@code java.nio.channels}
- * socket classes.
- *
- * @since 1.8
- */
-
-package jdk.net;
--- a/jdk/src/java.base/share/classes/module-info.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/module-info.java Thu Apr 28 23:08:17 2016 -0700
@@ -83,8 +83,6 @@
// see JDK-8144062
exports jdk;
- // see JDK-8044773
- exports jdk.net;
// the service types defined by the APIs in this module
@@ -168,6 +166,7 @@
java.sql,
java.xml,
jdk.charsets,
+ jdk.net,
jdk.scripting.nashorn,
jdk.unsupported,
jdk.vm.ci;
@@ -194,6 +193,8 @@
jdk.jvmstat;
exports sun.net to
java.httpclient;
+ exports sun.net.ext to
+ jdk.net;
exports sun.net.dns to
java.security.jgss,
jdk.naming.dns;
--- a/jdk/src/java.base/share/classes/sun/net/ExtendedOptionsImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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.net;
-
-import java.net.*;
-import jdk.net.*;
-import java.io.IOException;
-import java.io.FileDescriptor;
-import java.security.PrivilegedAction;
-import java.security.AccessController;
-import java.lang.reflect.Field;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Collections;
-
-/**
- * Contains the native implementation for extended socket options
- * together with some other static utilities
- */
-public class ExtendedOptionsImpl {
-
- static {
- AccessController.doPrivileged((PrivilegedAction<Void>)() -> {
- System.loadLibrary("net");
- return null;
- });
- init();
- }
-
- private ExtendedOptionsImpl() {}
-
- public static void checkSetOptionPermission(SocketOption<?> option) {
- SecurityManager sm = System.getSecurityManager();
- if (sm == null) {
- return;
- }
- String check = "setOption." + option.name();
- sm.checkPermission(new NetworkPermission(check));
- }
-
- public static void checkGetOptionPermission(SocketOption<?> option) {
- SecurityManager sm = System.getSecurityManager();
- if (sm == null) {
- return;
- }
- String check = "getOption." + option.name();
- sm.checkPermission(new NetworkPermission(check));
- }
-
- public static void checkValueType(Object value, Class<?> type) {
- if (!type.isAssignableFrom(value.getClass())) {
- String s = "Found: " + value.getClass().toString() + " Expected: "
- + type.toString();
- throw new IllegalArgumentException(s);
- }
- }
-
- private static native void init();
-
- /*
- * Extension native implementations
- *
- * SO_FLOW_SLA
- */
- public static native void setFlowOption(FileDescriptor fd, SocketFlow f);
- public static native void getFlowOption(FileDescriptor fd, SocketFlow f);
- public static native boolean flowSupported();
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/net/ext/ExtendedSocketOptions.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.net.ext;
+
+import java.io.FileDescriptor;
+import java.net.SocketException;
+import java.net.SocketOption;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * Defines the infrastructure to support extended socket options, beyond those
+ * defined in {@link java.net.StandardSocketOptions}.
+ *
+ * Extended socket options are accessed through the jdk.net API, which is in
+ * the jdk.net module.
+ */
+public abstract class ExtendedSocketOptions {
+
+ private final Set<SocketOption<?>> options;
+
+ /** Tells whether or not the option is supported. */
+ public final boolean isOptionSupported(SocketOption<?> option) {
+ return options().contains(option);
+ }
+
+ /** Return the, possibly empty, set of extended socket options available. */
+ public final Set<SocketOption<?>> options() { return options; }
+
+ /** Sets the value of a socket option, for the given socket. */
+ public abstract void setOption(FileDescriptor fd, SocketOption<?> option, Object value)
+ throws SocketException;
+
+ /** Returns the value of a socket option, for the given socket. */
+ public abstract Object getOption(FileDescriptor fd, SocketOption<?> option)
+ throws SocketException;
+
+ protected ExtendedSocketOptions(Set<SocketOption<?>> options) {
+ this.options = options;
+ }
+
+ private static volatile ExtendedSocketOptions instance;
+
+ public static final ExtendedSocketOptions getInstance() { return instance; }
+
+ /** Registers support for extended socket options. Invoked by the jdk.net module. */
+ public static final void register(ExtendedSocketOptions extOptions) {
+ if (instance != null)
+ throw new InternalError("Attempting to reregister extended options");
+
+ instance = extOptions;
+ }
+
+ static {
+ try {
+ // If the class is present, it will be initialized which
+ // triggers registration of the extended socket options.
+ Class<?> c = Class.forName("jdk.net.ExtendedSocketOptions");
+ } catch (ClassNotFoundException e) {
+ // the jdk.net module is not present => no extended socket options
+ instance = new NoExtendedSocketOptions();
+ }
+ }
+
+ static final class NoExtendedSocketOptions extends ExtendedSocketOptions {
+
+ NoExtendedSocketOptions() {
+ super(Collections.<SocketOption<?>>emptySet());
+ }
+
+ @Override
+ public void setOption(FileDescriptor fd, SocketOption<?> option, Object value)
+ throws SocketException
+ {
+ throw new UnsupportedOperationException(
+ "no extended options: " + option.name());
+ }
+
+ @Override
+ public Object getOption(FileDescriptor fd, SocketOption<?> option)
+ throws SocketException
+ {
+ throw new UnsupportedOperationException(
+ "no extended options: " + option.name());
+ }
+ }
+}
--- a/jdk/src/java.base/share/classes/sun/nio/ch/AbstractPollSelectorImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/AbstractPollSelectorImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,6 @@
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.util.*;
-import sun.misc.*;
/**
--- a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -39,7 +39,7 @@
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
import sun.net.NetHooks;
-import sun.net.ExtendedOptionsImpl;
+import sun.net.ext.ExtendedSocketOptions;
/**
* Base implementation of AsynchronousSocketChannel
@@ -512,9 +512,9 @@
set.add(StandardSocketOptions.SO_REUSEPORT);
}
set.add(StandardSocketOptions.TCP_NODELAY);
- if (ExtendedOptionsImpl.flowSupported()) {
- set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
- }
+ ExtendedSocketOptions extendedOptions =
+ ExtendedSocketOptions.getInstance();
+ set.addAll(extendedOptions.options());
return Collections.unmodifiableSet(set);
}
}
--- a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -33,7 +33,7 @@
import java.nio.channels.spi.*;
import java.util.*;
import sun.net.ResourceManager;
-import sun.net.ExtendedOptionsImpl;
+import sun.net.ext.ExtendedSocketOptions;
/**
* An implementation of DatagramChannels.
@@ -306,9 +306,9 @@
set.add(StandardSocketOptions.IP_MULTICAST_IF);
set.add(StandardSocketOptions.IP_MULTICAST_TTL);
set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
- if (ExtendedOptionsImpl.flowSupported()) {
- set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
- }
+ ExtendedSocketOptions extendedOptions =
+ ExtendedSocketOptions.getInstance();
+ set.addAll(extendedOptions.options());
return Collections.unmodifiableSet(set);
}
}
--- a/jdk/src/java.base/share/classes/sun/nio/ch/Net.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/Net.java Thu Apr 28 23:08:17 2016 -0700
@@ -27,15 +27,13 @@
import java.io.*;
import java.net.*;
-import jdk.net.*;
import java.nio.channels.*;
import java.util.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import sun.net.ExtendedOptionsImpl;
+import sun.net.ext.ExtendedSocketOptions;
import sun.security.action.GetPropertyAction;
-
public class Net {
private Net() { }
@@ -281,6 +279,9 @@
// -- Socket options
+ static final ExtendedSocketOptions extendedOptions =
+ ExtendedSocketOptions.getInstance();
+
static void setSocketOption(FileDescriptor fd, ProtocolFamily family,
SocketOption<?> name, Object value)
throws IOException
@@ -291,12 +292,8 @@
// only simple values supported by this method
Class<?> type = name.type();
- if (type == SocketFlow.class) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new NetworkPermission("setOption.SO_FLOW_SLA"));
- }
- ExtendedOptionsImpl.setFlowOption(fd, (SocketFlow)value);
+ if (extendedOptions.isOptionSupported(name)) {
+ extendedOptions.setOption(fd, name, value);
return;
}
@@ -353,14 +350,8 @@
{
Class<?> type = name.type();
- if (type == SocketFlow.class) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new NetworkPermission("getOption.SO_FLOW_SLA"));
- }
- SocketFlow flow = SocketFlow.create();
- ExtendedOptionsImpl.getFlowOption(fd, flow);
- return flow;
+ if (extendedOptions.isOptionSupported(name)) {
+ return extendedOptions.getOption(fd, name);
}
// only simple values supported by this method
--- a/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -33,8 +33,7 @@
import java.nio.channels.spi.*;
import java.util.*;
import sun.net.NetHooks;
-import sun.net.ExtendedOptionsImpl;
-
+import sun.net.ext.ExtendedSocketOptions;
/**
* An implementation of SocketChannels
@@ -242,9 +241,9 @@
// additional options required by socket adaptor
set.add(StandardSocketOptions.IP_TOS);
set.add(ExtendedSocketOption.SO_OOBINLINE);
- if (ExtendedOptionsImpl.flowSupported()) {
- set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
- }
+ ExtendedSocketOptions extendedOptions =
+ ExtendedSocketOptions.getInstance();
+ set.addAll(extendedOptions.options());
return Collections.unmodifiableSet(set);
}
}
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -209,6 +209,12 @@
Collection<SNIMatcher> sniMatchers =
Collections.<SNIMatcher>emptyList();
+ // Is the serverNames set to empty with SSLParameters.setServerNames()?
+ private boolean noSniExtension = false;
+
+ // Is the sniMatchers set to empty with SSLParameters.setSNIMatchers()?
+ private boolean noSniMatcher = false;
+
// Configured application protocol values
String[] applicationProtocols = new String[0];
@@ -642,6 +648,11 @@
}
super.connect(endpoint, timeout);
+
+ if (host == null || host.length() == 0) {
+ useImplicitHost(false);
+ }
+
doneConnect();
}
@@ -2098,41 +2109,62 @@
outputRecord.setVersion(protocolVersion);
}
+ //
+ // ONLY used by ClientHandshaker for the server hostname during handshaking
+ //
synchronized String getHost() {
// Note that the host may be null or empty for localhost.
if (host == null || host.length() == 0) {
- if (!trustNameService) {
- // If the local name service is not trustworthy, reverse host
- // name resolution should not be performed for endpoint
- // identification. Use the application original specified
- // hostname or IP address instead.
- host = getOriginalHostname(getInetAddress());
- } else {
- host = getInetAddress().getHostName();
- }
+ useImplicitHost(true);
}
return host;
}
/*
- * Get the original application specified hostname.
+ * Try to set and use the implicit specified hostname
*/
- private static String getOriginalHostname(InetAddress inetAddress) {
- /*
- * Get the original hostname via jdk.internal.misc.SharedSecrets.
- */
- JavaNetInetAddressAccess jna = SharedSecrets.getJavaNetInetAddressAccess();
- String originalHostname = jna.getOriginalHostName(inetAddress);
+ private synchronized void useImplicitHost(boolean noSniUpdate) {
- /*
- * If no application specified hostname, use the IP address.
- */
- if (originalHostname == null || originalHostname.length() == 0) {
- originalHostname = inetAddress.getHostAddress();
+ // Note: If the local name service is not trustworthy, reverse
+ // host name resolution should not be performed for endpoint
+ // identification. Use the application original specified
+ // hostname or IP address instead.
+
+ // Get the original hostname via jdk.internal.misc.SharedSecrets
+ InetAddress inetAddress = getInetAddress();
+ if (inetAddress == null) { // not connected
+ return;
}
- return originalHostname;
+ JavaNetInetAddressAccess jna =
+ SharedSecrets.getJavaNetInetAddressAccess();
+ String originalHostname = jna.getOriginalHostName(inetAddress);
+ if ((originalHostname != null) &&
+ (originalHostname.length() != 0)) {
+
+ host = originalHostname;
+ if (!noSniUpdate && serverNames.isEmpty() && !noSniExtension) {
+ serverNames =
+ Utilities.addToSNIServerNameList(serverNames, host);
+
+ if (!roleIsServer &&
+ (handshaker != null) && !handshaker.started()) {
+ handshaker.setSNIServerNames(serverNames);
+ }
+ }
+
+ return;
+ }
+
+ // No explicitly specified hostname, no server name indication.
+ if (!trustNameService) {
+ // The local name service is not trustworthy, use IP address.
+ host = inetAddress.getHostAddress();
+ } else {
+ // Use the underlying reverse host name resolution service.
+ host = getInetAddress().getHostName();
+ }
}
// ONLY used by HttpsClient to setup the URI specified hostname
@@ -2144,6 +2176,10 @@
this.host = host;
this.serverNames =
Utilities.addToSNIServerNameList(this.serverNames, this.host);
+
+ if (!roleIsServer && (handshaker != null) && !handshaker.started()) {
+ handshaker.setSNIServerNames(serverNames);
+ }
}
/**
@@ -2533,8 +2569,21 @@
// the super implementation does not handle the following parameters
params.setEndpointIdentificationAlgorithm(identificationProtocol);
params.setAlgorithmConstraints(algorithmConstraints);
- params.setSNIMatchers(sniMatchers);
- params.setServerNames(serverNames);
+
+ if (sniMatchers.isEmpty() && !noSniMatcher) {
+ // 'null' indicates none has been set
+ params.setSNIMatchers(null);
+ } else {
+ params.setSNIMatchers(sniMatchers);
+ }
+
+ if (serverNames.isEmpty() && !noSniExtension) {
+ // 'null' indicates none has been set
+ params.setServerNames(null);
+ } else {
+ params.setServerNames(serverNames);
+ }
+
params.setUseCipherSuitesOrder(preferLocalCipherSuites);
params.setMaximumPacketSize(maximumPacketSize);
params.setApplicationProtocols(applicationProtocols);
@@ -2568,11 +2617,13 @@
List<SNIServerName> sniNames = params.getServerNames();
if (sniNames != null) {
+ noSniExtension = sniNames.isEmpty();
serverNames = sniNames;
}
Collection<SNIMatcher> matchers = params.getSNIMatchers();
if (matchers != null) {
+ noSniMatcher = matchers.isEmpty();
sniMatchers = matchers;
}
--- a/jdk/src/java.base/share/classes/sun/util/logging/PlatformLogger.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/util/logging/PlatformLogger.java Thu Apr 28 23:08:17 2016 -0700
@@ -286,12 +286,15 @@
}
if (log == null) {
log = new PlatformLogger(PlatformLogger.Bridge.convert(
- // We pass PlatformLogger.class rather than the actual caller
+ // We pass PlatformLogger.class.getModule() (java.base)
+ // rather than the actual module of the caller
// because we want PlatformLoggers to be system loggers: we
// won't need to resolve any resource bundles anyway.
// Note: Many unit tests depend on the fact that
- // PlatformLogger.getLoggerFromFinder is not caller sensitive.
- LazyLoggers.getLazyLogger(name, PlatformLogger.class)));
+ // PlatformLogger.getLoggerFromFinder is not caller
+ // sensitive, and this strategy ensure that the tests
+ // still pass.
+ LazyLoggers.getLazyLogger(name, PlatformLogger.class.getModule())));
loggers.put(name, new WeakReference<>(log));
}
return log;
--- a/jdk/src/java.base/share/native/libjimage/jimage.cpp Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/native/libjimage/jimage.cpp Thu Apr 28 23:08:17 2016 -0700
@@ -207,7 +207,30 @@
if (!(*visitor)(image, module, "9", parent, base, extension, arg)) {
break;
}
-
}
}
+/*
+ * JIMAGE_ResourcePath- Given an open image file, a location reference, a buffer
+ * and a maximum buffer size, copy the path of the resource into the buffer.
+ * Returns false if not a valid location reference.
+ *
+ * Ex.
+ * JImageLocationRef location = ...
+ * char path[JIMAGE_MAX_PATH];
+ * (*JImageResourcePath)(image, location, path, JIMAGE_MAX_PATH);
+ */
+extern "C" bool JIMAGE_ResourcePath(JImageFile* image, JImageLocationRef locationRef,
+ char* path, size_t max) {
+ ImageFileReader* imageFile = (ImageFileReader*) image;
+
+ u4 offset = (u4) locationRef;
+ if (offset >= imageFile->locations_size()) {
+ return false;
+ }
+
+ ImageLocation location(imageFile->get_location_offset_data(offset));
+ imageFile->location_path(location, path, max);
+
+ return true;
+}
--- a/jdk/src/java.base/share/native/libjimage/jimage.hpp Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/share/native/libjimage/jimage.hpp Thu Apr 28 23:08:17 2016 -0700
@@ -37,11 +37,13 @@
typedef jlong JImageLocationRef;
// Max path length limit independent of platform. Windows max path is 1024,
-// other platforms use 4096. The JCK fails several tests when 1024 is used.
+// other platforms use 4096.
#define JIMAGE_MAX_PATH 4096
// JImage Error Codes
+// Resource was not found
+#define JIMAGE_NOT_FOUND (0)
// The image file is not prefixed with 0xCAFEDADA
#define JIMAGE_BAD_MAGIC (-1)
// The image file does not have a compatible (translatable) version
@@ -184,3 +186,20 @@
typedef void (*JImageResourceIterator_t)(JImageFile* jimage,
JImageResourceVisitor_t visitor, void* arg);
+
+/*
+ * JIMAGE_ResourcePath- Given an open image file, a location reference, a buffer
+ * and a maximum buffer size, copy the path of the resource into the buffer.
+ * Returns false if not a valid location reference.
+ *
+ * Ex.
+ * JImageLocationRef location = ...
+ * char path[JIMAGE_MAX_PATH];
+ * (*JImageResourcePath)(image, location, path, JIMAGE_MAX_PATH);
+ */
+extern "C" bool JIMAGE_ResourcePath(JImageFile* image, JImageLocationRef locationRef,
+ char* path, size_t max);
+
+typedef bool (*JImage_ResourcePath_t)(JImageFile* jimage, JImageLocationRef location,
+ char* buffer, jlong size);
+
--- a/jdk/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -27,9 +27,7 @@
import java.io.IOException;
import java.util.Set;
import java.util.HashSet;
-import java.util.Collections;
-import jdk.net.*;
-import static sun.net.ExtendedOptionsImpl.*;
+import sun.net.ext.ExtendedSocketOptions;
/*
* On Unix systems we simply delegate to native methods.
@@ -43,8 +41,11 @@
init();
}
+ static final ExtendedSocketOptions extendedOptions =
+ ExtendedSocketOptions.getInstance();
+
protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
- if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
+ if (!extendedOptions.isOptionSupported(name)) {
if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
super.setOption(name, value);
} else {
@@ -55,21 +56,16 @@
}
}
} else {
- if (!flowSupported()) {
- throw new UnsupportedOperationException("unsupported option");
- }
if (isClosed()) {
throw new SocketException("Socket closed");
}
- checkSetOptionPermission(name);
- checkValueType(value, SocketFlow.class);
- setFlowOption(getFileDescriptor(), (SocketFlow)value);
+ extendedOptions.setOption(fd, name, value);
}
}
@SuppressWarnings("unchecked")
protected <T> T getOption(SocketOption<T> name) throws IOException {
- if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
+ if (!extendedOptions.isOptionSupported(name)) {
if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
return super.getOption(name);
} else {
@@ -79,31 +75,23 @@
throw new UnsupportedOperationException("unsupported option");
}
}
- }
- if (!flowSupported()) {
- throw new UnsupportedOperationException("unsupported option");
+ } else {
+ if (isClosed()) {
+ throw new SocketException("Socket closed");
+ }
+ return (T) extendedOptions.getOption(fd, name);
}
- if (isClosed()) {
- throw new SocketException("Socket closed");
- }
- checkGetOptionPermission(name);
- SocketFlow flow = SocketFlow.create();
- getFlowOption(getFileDescriptor(), flow);
- return (T)flow;
}
protected Set<SocketOption<?>> supportedOptions() {
- HashSet<SocketOption<?>> options = new HashSet<>(
- super.supportedOptions());
-
- if (flowSupported()) {
- options.add(ExtendedSocketOptions.SO_FLOW_SLA);
- }
+ HashSet<SocketOption<?>> options = new HashSet<>(super.supportedOptions());
+ options.addAll(extendedOptions.options());
return options;
}
protected void socketSetOption(int opt, Object val) throws SocketException {
- if (opt == SocketOptions.SO_REUSEPORT && !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
+ if (opt == SocketOptions.SO_REUSEPORT &&
+ !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
throw new UnsupportedOperationException("unsupported option");
}
try {
--- a/jdk/src/java.base/unix/classes/java/net/PlainSocketImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/unix/classes/java/net/PlainSocketImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -28,10 +28,7 @@
import java.io.FileDescriptor;
import java.util.Set;
import java.util.HashSet;
-import java.util.Collections;
-import jdk.net.*;
-
-import static sun.net.ExtendedOptionsImpl.*;
+import sun.net.ext.ExtendedSocketOptions;
/*
* On Unix systems we simply delegate to native methods.
@@ -57,8 +54,11 @@
this.fd = fd;
}
+ static final ExtendedSocketOptions extendedOptions =
+ ExtendedSocketOptions.getInstance();
+
protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
- if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
+ if (!extendedOptions.isOptionSupported(name)) {
if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
super.setOption(name, value);
} else {
@@ -69,21 +69,19 @@
}
}
} else {
- if (getSocket() == null || !flowSupported()) {
+ if (getSocket() == null) {
throw new UnsupportedOperationException("unsupported option");
}
if (isClosedOrPending()) {
throw new SocketException("Socket closed");
}
- checkSetOptionPermission(name);
- checkValueType(value, SocketFlow.class);
- setFlowOption(getFileDescriptor(), (SocketFlow)value);
+ extendedOptions.setOption(fd, name, value);
}
}
@SuppressWarnings("unchecked")
protected <T> T getOption(SocketOption<T> name) throws IOException {
- if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
+ if (!extendedOptions.isOptionSupported(name)) {
if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
return super.getOption(name);
} else {
@@ -93,31 +91,28 @@
throw new UnsupportedOperationException("unsupported option");
}
}
- }
- if (getSocket() == null || !flowSupported()) {
- throw new UnsupportedOperationException("unsupported option");
+ } else {
+ if (getSocket() == null) {
+ throw new UnsupportedOperationException("unsupported option");
+ }
+ if (isClosedOrPending()) {
+ throw new SocketException("Socket closed");
+ }
+ return (T) extendedOptions.getOption(fd, name);
}
- if (isClosedOrPending()) {
- throw new SocketException("Socket closed");
- }
- checkGetOptionPermission(name);
- SocketFlow flow = SocketFlow.create();
- getFlowOption(getFileDescriptor(), flow);
- return (T)flow;
}
protected Set<SocketOption<?>> supportedOptions() {
- HashSet<SocketOption<?>> options = new HashSet<>(
- super.supportedOptions());
-
- if (getSocket() != null && flowSupported()) {
- options.add(ExtendedSocketOptions.SO_FLOW_SLA);
+ HashSet<SocketOption<?>> options = new HashSet<>(super.supportedOptions());
+ if (getSocket() != null) {
+ options.addAll(extendedOptions.options());
}
return options;
}
protected void socketSetOption(int opt, boolean b, Object val) throws SocketException {
- if (opt == SocketOptions.SO_REUSEPORT && !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
+ if (opt == SocketOptions.SO_REUSEPORT &&
+ !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
throw new UnsupportedOperationException("unsupported option");
}
try {
--- a/jdk/src/java.base/unix/classes/sun/nio/ch/PollSelectorImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/unix/classes/sun/nio/ch/PollSelectorImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,6 @@
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.util.*;
-import sun.misc.*;
/**
--- a/jdk/src/java.base/unix/native/libnet/ExtendedOptionsImpl.c Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,344 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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.
- */
-
-#include <jni.h>
-#include <string.h>
-
-#include "net_util.h"
-#include "jdk_net_SocketFlow.h"
-
-static jclass sf_status_class; /* Status enum type */
-
-static jfieldID sf_status;
-static jfieldID sf_priority;
-static jfieldID sf_bandwidth;
-
-static jfieldID sf_fd_fdID; /* FileDescriptor.fd */
-
-/* References to the literal enum values */
-
-static jobject sfs_NOSTATUS;
-static jobject sfs_OK;
-static jobject sfs_NOPERMISSION;
-static jobject sfs_NOTCONNECTED;
-static jobject sfs_NOTSUPPORTED;
-static jobject sfs_ALREADYCREATED;
-static jobject sfs_INPROGRESS;
-static jobject sfs_OTHER;
-
-static jobject getEnumField(JNIEnv *env, char *name);
-static void setStatus(JNIEnv *env, jobject obj, int errval);
-
-/* OS specific code is implemented in these three functions */
-
-static jboolean flowSupported0() ;
-
-/*
- * Class: sun_net_ExtendedOptionsImpl
- * Method: init
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_init
- (JNIEnv *env, jclass UNUSED)
-{
- static int initialized = 0;
- jclass c;
-
- /* Global class references */
-
- if (initialized) {
- return;
- }
-
- c = (*env)->FindClass(env, "jdk/net/SocketFlow$Status");
- CHECK_NULL(c);
- sf_status_class = (*env)->NewGlobalRef(env, c);
- CHECK_NULL(sf_status_class);
-
- /* int "fd" field of java.io.FileDescriptor */
-
- c = (*env)->FindClass(env, "java/io/FileDescriptor");
- CHECK_NULL(c);
- sf_fd_fdID = (*env)->GetFieldID(env, c, "fd", "I");
- CHECK_NULL(sf_fd_fdID);
-
-
- /* SocketFlow fields */
-
- c = (*env)->FindClass(env, "jdk/net/SocketFlow");
- CHECK_NULL(c);
-
- /* status */
-
- sf_status = (*env)->GetFieldID(env, c, "status",
- "Ljdk/net/SocketFlow$Status;");
- CHECK_NULL(sf_status);
-
- /* priority */
-
- sf_priority = (*env)->GetFieldID(env, c, "priority", "I");
- CHECK_NULL(sf_priority);
-
- /* bandwidth */
-
- sf_bandwidth = (*env)->GetFieldID(env, c, "bandwidth", "J");
- CHECK_NULL(sf_bandwidth);
-
- /* Initialize the static enum values */
-
- sfs_NOSTATUS = getEnumField(env, "NO_STATUS");
- CHECK_NULL(sfs_NOSTATUS);
- sfs_OK = getEnumField(env, "OK");
- CHECK_NULL(sfs_OK);
- sfs_NOPERMISSION = getEnumField(env, "NO_PERMISSION");
- CHECK_NULL(sfs_NOPERMISSION);
- sfs_NOTCONNECTED = getEnumField(env, "NOT_CONNECTED");
- CHECK_NULL(sfs_NOTCONNECTED);
- sfs_NOTSUPPORTED = getEnumField(env, "NOT_SUPPORTED");
- CHECK_NULL(sfs_NOTSUPPORTED);
- sfs_ALREADYCREATED = getEnumField(env, "ALREADY_CREATED");
- CHECK_NULL(sfs_ALREADYCREATED);
- sfs_INPROGRESS = getEnumField(env, "IN_PROGRESS");
- CHECK_NULL(sfs_INPROGRESS);
- sfs_OTHER = getEnumField(env, "OTHER");
- CHECK_NULL(sfs_OTHER);
- initialized = JNI_TRUE;
-}
-
-static jobject getEnumField(JNIEnv *env, char *name)
-{
- jobject f;
- jfieldID fID = (*env)->GetStaticFieldID(env, sf_status_class, name,
- "Ljdk/net/SocketFlow$Status;");
- CHECK_NULL_RETURN(fID, NULL);
-
- f = (*env)->GetStaticObjectField(env, sf_status_class, fID);
- CHECK_NULL_RETURN(f, NULL);
- f = (*env)->NewGlobalRef(env, f);
- CHECK_NULL_RETURN(f, NULL);
- return f;
-}
-
-/*
- * Retrieve the int file-descriptor from a public socket type object.
- * Gets impl, then the FileDescriptor from the impl, and then the fd
- * from that.
- */
-static int getFD(JNIEnv *env, jobject fileDesc) {
- return (*env)->GetIntField(env, fileDesc, sf_fd_fdID);
-}
-
-/**
- * Sets the status field of a SocketFlow to one of the
- * canned enum values
- */
-static void setStatus (JNIEnv *env, jobject obj, int errval)
-{
- switch (errval) {
- case 0: /* OK */
- (*env)->SetObjectField(env, obj, sf_status, sfs_OK);
- break;
- case EPERM:
- (*env)->SetObjectField(env, obj, sf_status, sfs_NOPERMISSION);
- break;
- case ENOTCONN:
- (*env)->SetObjectField(env, obj, sf_status, sfs_NOTCONNECTED);
- break;
- case EOPNOTSUPP:
- (*env)->SetObjectField(env, obj, sf_status, sfs_NOTSUPPORTED);
- break;
- case EALREADY:
- (*env)->SetObjectField(env, obj, sf_status, sfs_ALREADYCREATED);
- break;
- case EINPROGRESS:
- (*env)->SetObjectField(env, obj, sf_status, sfs_INPROGRESS);
- break;
- default:
- (*env)->SetObjectField(env, obj, sf_status, sfs_OTHER);
- break;
- }
-}
-
-#ifdef __solaris__
-
-/*
- * Class: sun_net_ExtendedOptionsImpl
- * Method: setFlowOption
- * Signature: (Ljava/io/FileDescriptor;Ljdk/net/SocketFlow;)V
- */
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setFlowOption
- (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
-{
- int fd = getFD(env, fileDesc);
-
- if (fd < 0) {
- NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed");
- return;
- } else {
- sock_flow_props_t props;
- jlong bandwidth;
- int rv;
-
- jint priority = (*env)->GetIntField(env, flow, sf_priority);
- memset(&props, 0, sizeof(props));
- props.sfp_version = SOCK_FLOW_PROP_VERSION1;
-
- if (priority != jdk_net_SocketFlow_UNSET) {
- props.sfp_mask |= SFP_PRIORITY;
- props.sfp_priority = priority;
- }
- bandwidth = (*env)->GetLongField(env, flow, sf_bandwidth);
- if (bandwidth > -1) {
- props.sfp_mask |= SFP_MAXBW;
- props.sfp_maxbw = (uint64_t) bandwidth;
- }
- rv = setsockopt(fd, SOL_SOCKET, SO_FLOW_SLA, &props, sizeof(props));
- if (rv < 0) {
- if (errno == ENOPROTOOPT) {
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- "unsupported socket option");
- } else if (errno == EACCES || errno == EPERM) {
- NET_ERROR(env, JNU_JAVANETPKG "SocketException",
- "Permission denied");
- } else {
- NET_ERROR(env, JNU_JAVANETPKG "SocketException",
- "set option SO_FLOW_SLA failed");
- }
- return;
- }
- setStatus(env, flow, props.sfp_status);
- }
-}
-
-/*
- * Class: sun_net_ExtendedOptionsImpl
- * Method: getFlowOption
- * Signature: (Ljava/io/FileDescriptor;Ljdk/net/SocketFlow;)V
- */
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_getFlowOption
- (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
-{
- int fd = getFD(env, fileDesc);
-
- if (fd < 0) {
- NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed");
- return;
- } else {
- sock_flow_props_t props;
- int status;
- socklen_t sz = sizeof(props);
-
- int rv = getsockopt(fd, SOL_SOCKET, SO_FLOW_SLA, &props, &sz);
- if (rv < 0) {
- if (errno == ENOPROTOOPT) {
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- "unsupported socket option");
- } else if (errno == EACCES || errno == EPERM) {
- NET_ERROR(env, JNU_JAVANETPKG "SocketException",
- "Permission denied");
- } else {
- NET_ERROR(env, JNU_JAVANETPKG "SocketException",
- "set option SO_FLOW_SLA failed");
- }
- return;
- }
- /* first check status to see if flow exists */
- status = props.sfp_status;
- setStatus(env, flow, status);
- if (status == 0) { /* OK */
- /* can set the other fields now */
- if (props.sfp_mask & SFP_PRIORITY) {
- (*env)->SetIntField(env, flow, sf_priority, props.sfp_priority);
- }
- if (props.sfp_mask & SFP_MAXBW) {
- (*env)->SetLongField(env, flow, sf_bandwidth,
- (jlong)props.sfp_maxbw);
- }
- }
- }
-}
-
-static jboolean flowsupported;
-static jboolean flowsupported_set = JNI_FALSE;
-
-static jboolean flowSupported0()
-{
- /* Do a simple dummy call, and try to figure out from that */
- sock_flow_props_t props;
- int rv, s;
- if (flowsupported_set) {
- return flowsupported;
- }
- s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (s < 0) {
- flowsupported = JNI_FALSE;
- flowsupported_set = JNI_TRUE;
- return JNI_FALSE;
- }
- memset(&props, 0, sizeof(props));
- props.sfp_version = SOCK_FLOW_PROP_VERSION1;
- props.sfp_mask |= SFP_PRIORITY;
- props.sfp_priority = SFP_PRIO_NORMAL;
- rv = setsockopt(s, SOL_SOCKET, SO_FLOW_SLA, &props, sizeof(props));
- if (rv != 0 && errno == ENOPROTOOPT) {
- rv = JNI_FALSE;
- } else {
- rv = JNI_TRUE;
- }
- close(s);
- flowsupported = rv;
- flowsupported_set = JNI_TRUE;
- return flowsupported;
-}
-
-#else /* __solaris__ */
-
-/* Non Solaris. Functionality is not supported. So, throw UnsupportedOpExc */
-
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setFlowOption
- (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
-{
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- "unsupported socket option");
-}
-
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_getFlowOption
- (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
-{
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- "unsupported socket option");
-}
-
-static jboolean flowSupported0() {
- return JNI_FALSE;
-}
-
-#endif /* __solaris__ */
-
-JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_flowSupported
- (JNIEnv *env, jclass UNUSED)
-{
- return flowSupported0();
-}
--- a/jdk/src/java.base/unix/native/libnet/net_util_md.h Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.base/unix/native/libnet/net_util_md.h Thu Apr 28 23:08:17 2016 -0700
@@ -120,47 +120,6 @@
#ifdef __solaris__
int net_getParam(char *driver, char *param);
-
-#ifndef SO_FLOW_SLA
-#define SO_FLOW_SLA 0x1018
-
-#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
-#pragma pack(4)
#endif
-/*
- * Used with the setsockopt(SO_FLOW_SLA, ...) call to set
- * per socket service level properties.
- * When the application uses per-socket API, we will enforce the properties
- * on both outbound and inbound packets.
- *
- * For now, only priority and maxbw are supported in SOCK_FLOW_PROP_VERSION1.
- */
-typedef struct sock_flow_props_s {
- int sfp_version;
- uint32_t sfp_mask;
- int sfp_priority; /* flow priority */
- uint64_t sfp_maxbw; /* bandwidth limit in bps */
- int sfp_status; /* flow create status for getsockopt */
-} sock_flow_props_t;
-
-#define SOCK_FLOW_PROP_VERSION1 1
-
-/* bit mask values for sfp_mask */
-#define SFP_MAXBW 0x00000001 /* Flow Bandwidth Limit */
-#define SFP_PRIORITY 0x00000008 /* Flow priority */
-
-/* possible values for sfp_priority */
-#define SFP_PRIO_NORMAL 1
-#define SFP_PRIO_HIGH 2
-
-#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
-#pragma pack()
-#endif /* _LONG_LONG_ALIGNMENT */
-
-#endif /* SO_FLOW_SLA */
-#endif /* __solaris__ */
-
-JNIEXPORT jboolean JNICALL NET_IsFlowSupported();
-
#endif /* NET_UTILS_MD_H */
--- a/jdk/src/java.base/windows/native/libnet/ExtendedOptionsImpl.c Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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.
- */
-
-#include <jni.h>
-#include <string.h>
-
-#include "net_util.h"
-
-/*
- * Class: sun_net_ExtendedOptionsImpl
- * Method: init
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_init
- (JNIEnv *env, jclass UNUSED)
-{
-}
-
-/* Non Solaris. Functionality is not supported. So, throw UnsupportedOpExc */
-
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setFlowOption
- (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
-{
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- "unsupported socket option");
-}
-
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_getFlowOption
- (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
-{
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- "unsupported socket option");
-}
-
-static jboolean flowSupported0() {
- return JNI_FALSE;
-}
-
-JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_flowSupported
- (JNIEnv *env, jclass UNUSED)
-{
- return JNI_FALSE;
-}
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java Thu Apr 28 23:08:17 2016 -0700
@@ -52,7 +52,6 @@
import sun.awt.datatransfer.DataTransferer;
import sun.font.FontConfigManager;
import sun.java2d.SunGraphicsEnvironment;
-import sun.misc.*;
import sun.awt.util.PerformanceLogger;
import sun.awt.util.ThreadGroupUtils;
import sun.print.PrintJob2D;
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/java2d/x11/XRBackendNative.c Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/java2d/x11/XRBackendNative.c Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -72,8 +72,8 @@
#include <dlfcn.h>
-#if defined(__solaris__) || defined(_AIX)
-/* Solaris 10 and AIX will not have these symbols at runtime */
+#if defined(__solaris__)
+/* Solaris 10 will not have these symbols at compile time */
typedef Picture (*XRenderCreateLinearGradientFuncType)
(Display *dpy,
@@ -147,7 +147,22 @@
return JNI_FALSE;
}
-#if defined(__solaris__) || defined(_AIX)
+#if defined(_AIX)
+ // On AIX we have to use a special syntax because the shared libraries are packed in
+ // multi-architecture archives. We first try to load the system default libXrender
+ // which is contained in the 'X11.base.lib' fileset starting with AIX 6.1
+ xrenderlib = dlopen("libXrender.a(shr_64.o)", RTLD_GLOBAL | RTLD_LAZY | RTLD_MEMBER);
+ if (xrenderlib == NULL) {
+ // If the latter wasn't successful, we also try to load the version under /opt/freeware
+ // This may be downloaded from the "AIX Toolbox for Linux Applications" even for AIX 5.3
+ xrenderlib = dlopen("libXrender.a(libXrender.so.0)", RTLD_GLOBAL | RTLD_LAZY | RTLD_MEMBER);
+ }
+ if (xrenderlib != NULL) {
+ dlclose(xrenderlib);
+ } else {
+ available = JNI_FALSE;
+ }
+#elif defined(__solaris__)
xrenderlib = dlopen("libXrender.so",RTLD_GLOBAL|RTLD_LAZY);
if (xrenderlib != NULL) {
--- a/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java Thu Apr 28 23:08:17 2016 -0700
@@ -43,6 +43,8 @@
import jdk.internal.misc.JavaAWTAccess;
import jdk.internal.misc.SharedSecrets;
import sun.util.logging.internal.LoggingProviderImpl;
+import java.lang.reflect.Module;
+import static jdk.internal.logger.DefaultLoggerFinder.isSystem;
/**
* There is a single global LogManager object that is used to
@@ -503,10 +505,16 @@
// as a LogManager subclass may override the addLogger, getLogger,
// readConfiguration, and other methods.
Logger demandLogger(String name, String resourceBundleName, Class<?> caller) {
+ final Module module = caller == null ? null : caller.getModule();
+ return demandLogger(name, resourceBundleName, module);
+ }
+
+ Logger demandLogger(String name, String resourceBundleName, Module module) {
Logger result = getLogger(name);
if (result == null) {
// only allocate the new logger once
- Logger newLogger = new Logger(name, resourceBundleName, caller, this, false);
+ Logger newLogger = new Logger(name, resourceBundleName,
+ module == null ? null : module, this, false);
do {
if (addLogger(newLogger)) {
// We successfully added the new Logger that we
@@ -532,9 +540,14 @@
}
Logger demandSystemLogger(String name, String resourceBundleName, Class<?> caller) {
+ final Module module = caller == null ? null : caller.getModule();
+ return demandSystemLogger(name, resourceBundleName, module);
+ }
+
+ Logger demandSystemLogger(String name, String resourceBundleName, Module module) {
// Add a system logger in the system context's namespace
final Logger sysLogger = getSystemContext()
- .demandLogger(name, resourceBundleName, caller);
+ .demandLogger(name, resourceBundleName, module);
// Add the system logger to the LogManager's namespace if not exist
// so that there is only one single logger of the given name.
@@ -619,11 +632,11 @@
return global;
}
- Logger demandLogger(String name, String resourceBundleName, Class<?> caller) {
+ Logger demandLogger(String name, String resourceBundleName, Module module) {
// a LogManager subclass may have its own implementation to add and
// get a Logger. So delegate to the LogManager to do the work.
final LogManager owner = getOwner();
- return owner.demandLogger(name, resourceBundleName, caller);
+ return owner.demandLogger(name, resourceBundleName, module);
}
@@ -907,11 +920,13 @@
// one single logger of the given name. System loggers are visible
// to applications unless a logger of the same name has been added.
@Override
- Logger demandLogger(String name, String resourceBundleName, Class<?> caller) {
+ Logger demandLogger(String name, String resourceBundleName,
+ Module module) {
Logger result = findLogger(name);
if (result == null) {
// only allocate the new system logger once
- Logger newLogger = new Logger(name, resourceBundleName, caller, getOwner(), true);
+ Logger newLogger = new Logger(name, resourceBundleName,
+ module, getOwner(), true);
do {
if (addLocalLogger(newLogger)) {
// We successfully added the new Logger that we
@@ -2622,18 +2637,18 @@
}
/**
- * Demands a logger on behalf of the given {@code caller}.
+ * Demands a logger on behalf of the given {@code module}.
* <p>
- * If a named logger suitable for the given caller is found
+ * If a named logger suitable for the given module is found
* returns it.
- * Otherwise, creates a new logger suitable for the given caller.
+ * Otherwise, creates a new logger suitable for the given module.
*
* @param name The logger name.
- * @param caller The caller on which behalf the logger is created/retrieved.
- * @return A logger for the given {@code caller}.
+ * @param module The module on which behalf the logger is created/retrieved.
+ * @return A logger for the given {@code module}.
*
* @throws NullPointerException if {@code name} is {@code null}
- * or {@code caller} is {@code null}.
+ * or {@code module} is {@code null}.
* @throws IllegalArgumentException if {@code manager} is not the default
* LogManager.
* @throws SecurityException if a security manager is present and the
@@ -2641,7 +2656,7 @@
* {@link LoggingPermission LoggingPermission("demandLogger", null)}.
*/
@Override
- public Logger demandLoggerFor(LogManager manager, String name, /* Module */ Class<?> caller) {
+ public Logger demandLoggerFor(LogManager manager, String name, Module module) {
if (manager != getLogManager()) {
// having LogManager as parameter just ensures that the
// caller will have initialized the LogManager before reaching
@@ -2649,15 +2664,16 @@
throw new IllegalArgumentException("manager");
}
Objects.requireNonNull(name);
+ Objects.requireNonNull(module);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(controlPermission);
}
- if (caller.getClassLoader() == null) {
+ if (isSystem(module)) {
return manager.demandSystemLogger(name,
- Logger.SYSTEM_LOGGER_RB_NAME, caller);
+ Logger.SYSTEM_LOGGER_RB_NAME, module);
} else {
- return manager.demandLogger(name, null, caller);
+ return manager.demandLogger(name, null, module);
}
}
--- a/jdk/src/java.logging/share/classes/java/util/logging/Logger.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.logging/share/classes/java/util/logging/Logger.java Thu Apr 28 23:08:17 2016 -0700
@@ -40,6 +40,7 @@
import java.util.function.Supplier;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
+import static jdk.internal.logger.DefaultLoggerFinder.isSystem;
/**
* A Logger object is used to log messages for a specific
@@ -379,7 +380,8 @@
this(name, resourceBundleName, null, LogManager.getLogManager(), false);
}
- Logger(String name, String resourceBundleName, Class<?> caller, LogManager manager, boolean isSystemLogger) {
+ Logger(String name, String resourceBundleName, Module caller,
+ LogManager manager, boolean isSystemLogger) {
this.manager = manager;
this.isSystemLogger = isSystemLogger;
setupResourceInfo(resourceBundleName, caller);
@@ -387,10 +389,7 @@
levelValue = Level.INFO.intValue();
}
- private void setCallerModuleRef(Class<?> caller) {
- Module callerModule = ((caller != null)
- ? caller.getModule()
- : null);
+ private void setCallerModuleRef(Module callerModule) {
if (callerModule != null) {
this.callerModuleRef = new WeakReference<>(callerModule);
}
@@ -618,7 +617,7 @@
// all loggers in the system context will default to
// the system logger's resource bundle - therefore the caller won't
// be needed and can be null.
- Logger result = manager.demandSystemLogger(name, SYSTEM_LOGGER_RB_NAME, null);
+ Logger result = manager.demandSystemLogger(name, SYSTEM_LOGGER_RB_NAME, (Module)null);
return result;
}
@@ -681,8 +680,10 @@
LogManager manager = LogManager.getLogManager();
// cleanup some Loggers that have been GC'ed
manager.drainLoggerRefQueueBounded();
+ final Class<?> callerClass = Reflection.getCallerClass();
+ final Module module = callerClass.getModule();
Logger result = new Logger(null, resourceBundleName,
- Reflection.getCallerClass(), manager, false);
+ module, manager, false);
result.anonymous = true;
Logger root = manager.getLogger("");
result.doSetParent(root);
@@ -2046,6 +2047,11 @@
}
}
+ private void setupResourceInfo(String name, Class<?> caller) {
+ final Module module = caller == null ? null : caller.getModule();
+ setupResourceInfo(name, module);
+ }
+
// Private utility method to initialize our one entry
// resource bundle name cache and the callers Module
// Note: for consistency reasons, we are careful to check
@@ -2053,7 +2059,7 @@
// resourceBundleName field.
// Synchronized to prevent races in setting the fields.
private synchronized void setupResourceInfo(String name,
- Class<?> callerClass) {
+ Module callerModule) {
final LoggerBundle lb = loggerBundle;
if (lb.resourceBundleName != null) {
// this Logger already has a ResourceBundle
@@ -2072,8 +2078,9 @@
return;
}
- setCallerModuleRef(callerClass);
- if (isSystemLogger && (callerClass != null && callerClass.getClassLoader() != null)) {
+ setCallerModuleRef(callerModule);
+
+ if (isSystemLogger && (callerModule != null && !isSystem(callerModule))) {
checkPermission();
}
--- a/jdk/src/java.logging/share/classes/sun/util/logging/internal/LoggingProviderImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/java.logging/share/classes/sun/util/logging/internal/LoggingProviderImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -32,6 +32,7 @@
import java.util.function.Supplier;
import java.lang.System.LoggerFinder;
import java.lang.System.Logger;
+import java.lang.reflect.Module;
import java.util.Objects;
import java.util.logging.LogManager;
import jdk.internal.logger.DefaultLoggerFinder;
@@ -398,21 +399,20 @@
}
/**
- * Creates a java.util.logging.Logger for the given caller.
+ * Creates a java.util.logging.Logger for the given module.
* @param name the logger name.
- * @param caller the caller for which the logger should be created.
- * @return a Logger suitable for use in the given caller.
+ * @param module the module for which the logger should be created.
+ * @return a Logger suitable for use in the given module.
*/
private static java.util.logging.Logger demandJULLoggerFor(final String name,
- /* Module */
- final Class<?> caller) {
+ Module module) {
final LogManager manager = LogManager.getLogManager();
final SecurityManager sm = System.getSecurityManager();
if (sm == null) {
- return logManagerAccess.demandLoggerFor(manager, name, caller);
+ return logManagerAccess.demandLoggerFor(manager, name, module);
} else {
final PrivilegedAction<java.util.logging.Logger> pa =
- () -> logManagerAccess.demandLoggerFor(manager, name, caller);
+ () -> logManagerAccess.demandLoggerFor(manager, name, module);
return AccessController.doPrivileged(pa, null, LOGGING_CONTROL_PERMISSION);
}
}
@@ -429,17 +429,17 @@
* {@code RuntimePermission("loggerFinder")}.
*/
@Override
- protected Logger demandLoggerFor(String name, /* Module */ Class<?> caller) {
+ protected Logger demandLoggerFor(String name, Module module) {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOGGERFINDER_PERMISSION);
}
- return JULWrapper.of(demandJULLoggerFor(name,caller));
+ return JULWrapper.of(demandJULLoggerFor(name,module));
}
public static interface LogManagerAccess {
java.util.logging.Logger demandLoggerFor(LogManager manager,
- String name, /* Module */ Class<?> caller);
+ String name, Module module);
}
// Hook for tests
--- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java Thu Apr 28 23:08:17 2016 -0700
@@ -257,11 +257,11 @@
* delegate to the {@link com.sun.jdi.connect.spi.TransportService#description()
* description()} method of the underlying transport service. Both
* the AttachingConnector and the ListeningConnector will have two
- * Connector {@link com.sun.jdi.connect.Connector$Argument Arguments}.
- * A {@link com.sun.jdi.connect.Connector$StringArgument StringArgument}
+ * Connector {@link com.sun.jdi.connect.Connector.Argument Arguments}.
+ * A {@link com.sun.jdi.connect.Connector.StringArgument StringArgument}
* named {@code address} is the connector argument to specify the
* address to attach too, or to listen on. A
- * {@link com.sun.jdi.connect.Connector$IntegerArgument IntegerArgument}
+ * {@link com.sun.jdi.connect.Connector.IntegerArgument IntegerArgument}
* named {@code timeout} is the connector argument to specify the
* timeout when attaching, or accepting. The timeout connector may be
* ignored depending on if the transport service supports an attach
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/ExtractedImage.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.tools.jimage;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.function.Consumer;
-import jdk.tools.jlink.internal.ImageFileCreator;
-import jdk.tools.jlink.internal.Archive;
-import jdk.tools.jlink.internal.ImagePluginStack;
-import jdk.tools.jlink.internal.DirArchive;
-/**
- *
- * Support for extracted image.
- */
-public final class ExtractedImage {
-
- private Set<Archive> archives = new HashSet<>();
- private final ImagePluginStack plugins;
-
- ExtractedImage(Path dirPath, ImagePluginStack plugins, PrintWriter log,
- boolean verbose) throws IOException {
- if (!Files.isDirectory(dirPath)) {
- throw new IOException("Not a directory");
- }
- Consumer<String> cons = (String t) -> {
- if (verbose) {
- log.println(t);
- }
- };
- this.plugins = plugins;
- Files.walk(dirPath, 1).forEach((p) -> {
- if (!dirPath.equals(p)) {
- if (Files.isDirectory(p)) {
- Archive a = new DirArchive(p, cons);
- archives.add(a);
- }
- }
- });
- archives = Collections.unmodifiableSet(archives);
- }
-
- void recreateJImage(Path path) throws IOException {
- ImageFileCreator.recreateJimage(path, archives, plugins);
- }
-
- private static String getPathName(Path path) {
- return path.toString().replace(File.separatorChar, '/');
- }
-}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java Thu Apr 28 23:08:17 2016 -0700
@@ -32,7 +32,6 @@
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
-import java.nio.file.Path;
import static java.nio.file.StandardOpenOption.READ;
import static java.nio.file.StandardOpenOption.WRITE;
import java.util.LinkedList;
@@ -44,8 +43,6 @@
import static jdk.internal.jimage.ImageHeader.MINOR_VERSION;
import jdk.internal.jimage.ImageLocation;
import jdk.tools.jlink.internal.ImageResourcesTree;
-import jdk.tools.jlink.internal.ImagePluginConfiguration;
-import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.TaskHelper;
import jdk.tools.jlink.internal.TaskHelper.BadArgs;
import static jdk.tools.jlink.internal.TaskHelper.JIMAGE_BUNDLE;
@@ -97,7 +94,6 @@
EXTRACT,
INFO,
LIST,
- RECREATE,
SET,
VERIFY
};
@@ -152,21 +148,28 @@
setLog(new PrintWriter(System.out));
}
+ if (args.length == 0) {
+ log.println(taskHelper.getMessage("main.usage.summary", PROGNAME));
+ return EXIT_ABNORMAL;
+ }
+
try {
List<String> unhandled = optionsHelper.handleOptions(this, args);
if(!unhandled.isEmpty()) {
- options.task = Enum.valueOf(Task.class, unhandled.get(0).toUpperCase());
+ try {
+ options.task = Enum.valueOf(Task.class, unhandled.get(0).toUpperCase());
+ } catch (IllegalArgumentException ex) {
+ throw taskHelper.newBadArgs("err.not.a.task", unhandled.get(0));
+ }
for(int i = 1; i < unhandled.size(); i++) {
options.jimages.add(new File(unhandled.get(i)));
}
+ } else {
+ throw taskHelper.newBadArgs("err.not.a.task", "<unspecified>");
}
if (options.help) {
optionsHelper.showHelp(PROGNAME);
}
- if(optionsHelper.listPlugins()) {
- optionsHelper.listPlugins(true);
- return EXIT_OK;
- }
if (options.version || options.fullVersion) {
taskHelper.showVersion(options.fullVersion);
}
@@ -186,49 +189,19 @@
}
}
- private void recreate() throws Exception, BadArgs {
- File directory = new File(options.directory);
- if (!directory.isDirectory()) {
- throw taskHelper.newBadArgs("err.not.a.dir", directory.getAbsolutePath());
- }
- Path dirPath = directory.toPath();
- if (options.jimages.isEmpty()) {
- throw taskHelper.newBadArgs("err.jimage.not.specified");
- } else if (options.jimages.size() != 1) {
- throw taskHelper.newBadArgs("err.only.one.jimage");
- }
-
- Path jimage = options.jimages.get(0).toPath();
-
- if (jimage.toFile().createNewFile()) {
- ImagePluginStack pc = ImagePluginConfiguration.parseConfiguration(taskHelper.
- getPluginsConfig(null, false));
- ExtractedImage img = new ExtractedImage(dirPath, pc, log, options.verbose);
- img.recreateJImage(jimage);
- } else {
- throw taskHelper.newBadArgs("err.jimage.already.exists", jimage.getFileName());
- }
- }
-
- private void title(File file, BasicImageReader reader) {
- log.println("jimage: " + file.getName());
- }
-
private void listTitle(File file, BasicImageReader reader) {
- title(file, reader);
-
- if (options.verbose) {
- log.print(pad("Offset", OFFSET_WIDTH + 1));
- log.print(pad("Size", SIZE_WIDTH + 1));
- log.print(pad("Compressed", COMPRESSEDSIZE_WIDTH + 1));
- log.println(" Entry");
- }
+ log.println("jimage: " + file);
}
private interface JImageAction {
public void apply(File file, BasicImageReader reader) throws IOException, BadArgs;
}
+ private interface ModuleAction {
+ public void apply(BasicImageReader reader,
+ String oldModule, String newModule) throws IOException, BadArgs;
+ }
+
private interface ResourceAction {
public void apply(BasicImageReader reader, String name,
ImageLocation location) throws IOException, BadArgs;
@@ -254,23 +227,32 @@
}
}
- private static final int NUMBER_WIDTH = 12;
- private static final int OFFSET_WIDTH = NUMBER_WIDTH;
- private static final int SIZE_WIDTH = NUMBER_WIDTH;
- private static final int COMPRESSEDSIZE_WIDTH = NUMBER_WIDTH;
+ private static final int OFFSET_WIDTH = 12;
+ private static final int SIZE_WIDTH = 10;
+ private static final int COMPRESSEDSIZE_WIDTH = 10;
+
+ private String trimModule(String name) {
+ int offset = name.indexOf('/', 1);
- private void print(String entry, ImageLocation location) {
+ if (offset != -1 && offset + 1 < name.length()) {
+ return name.substring(offset + 1);
+ }
+
+ return name;
+ }
+
+ private void print(String name, ImageLocation location) {
log.print(pad(location.getContentOffset(), OFFSET_WIDTH) + " ");
log.print(pad(location.getUncompressedSize(), SIZE_WIDTH) + " ");
log.print(pad(location.getCompressedSize(), COMPRESSEDSIZE_WIDTH) + " ");
- log.println(entry);
+ log.println(trimModule(name));
}
- private void print(BasicImageReader reader, String entry) {
+ private void print(BasicImageReader reader, String name) {
if (options.verbose) {
- print(entry, reader.findLocation(entry));
+ print(name, reader.findLocation(name));
} else {
- log.println(entry);
+ log.println(" " + trimModule(name));
}
}
@@ -289,6 +271,18 @@
log.println(" Index Size: " + header.getIndexSize());
}
+ private void listModule(BasicImageReader reader, String oldModule, String newModule) {
+ log.println();
+ log.println("Module: " + newModule);
+
+ if (options.verbose) {
+ log.print(pad("Offset", OFFSET_WIDTH) + " ");
+ log.print(pad("Size", SIZE_WIDTH) + " ");
+ log.print(pad("Compressed", COMPRESSEDSIZE_WIDTH) + " ");
+ log.println("Entry");
+ }
+ }
+
private void list(BasicImageReader reader, String name, ImageLocation location) {
print(reader, name);
}
@@ -338,7 +332,12 @@
}
private void iterate(JImageAction jimageAction,
+ ModuleAction moduleAction,
ResourceAction resourceAction) throws IOException, BadArgs {
+ if (options.jimages.isEmpty()) {
+ throw taskHelper.newBadArgs("err.no.jimage");
+ }
+
for (File file : options.jimages) {
if (!file.exists() || !file.isFile()) {
throw taskHelper.newBadArgs("err.not.a.jimage", file.getName());
@@ -351,9 +350,23 @@
if (resourceAction != null) {
String[] entryNames = reader.getEntryNames();
+ String oldModule = "";
for (String name : entryNames) {
if (!ImageResourcesTree.isTreeInfoResource(name)) {
+ if (moduleAction != null) {
+ int offset = name.indexOf('/', 1);
+
+ String newModule = offset != -1 ?
+ name.substring(1, offset) :
+ "<unknown>";
+
+ if (!oldModule.equals(newModule)) {
+ moduleAction.apply(reader, oldModule, newModule);
+ oldModule = newModule;
+ }
+ }
+
ImageLocation location = reader.findLocation(name);
resourceAction.apply(reader, name, location);
}
@@ -366,22 +379,19 @@
private boolean run() throws Exception, BadArgs {
switch (options.task) {
case EXTRACT:
- iterate(null, this::extract);
+ iterate(null, null, this::extract);
break;
case INFO:
- iterate(this::info, null);
+ iterate(this::info, null, null);
break;
case LIST:
- iterate(this::listTitle, this::list);
- break;
- case RECREATE:
- recreate();
+ iterate(this::listTitle, this::listModule, this::list);
break;
case SET:
- iterate(this::set, null);
+ iterate(this::set, null, null);
break;
case VERIFY:
- iterate(this::title, this::verify);
+ iterate(this::listTitle, null, this::verify);
break;
default:
throw taskHelper.newBadArgs("err.invalid.task", options.task.name()).showUsage(true);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/resources/jimage.properties Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/resources/jimage.properties Thu Apr 28 23:08:17 2016 -0700
@@ -1,30 +1,25 @@
main.usage.summary=\
-Usage: {0} <extract|info|list|recreate|set|verify> <options> jimage...\n\
+Usage: {0} <extract|info|list|set|verify> <options> jimage...\n\
use --help for a list of possible options
main.usage=\
-Usage: {0} <extract|info|list|recreate|set|verify> <options> jimage...\n\
+Usage: {0} <extract|info|list|set|verify> <options> jimage...\n\
\n\
\ extract - Extract all jimage entries into separate files into the directory\n\
\ specified by --dir=<directory> (default='.')\n\
\ info - Prints information specified in the jimage header.\n\
\ list - Prints the names of all the entries in the jimage. When used with\n\
\ --verbose will also print entry attributes ex. size and offset.\n\
-\ recreate - Reconstructs a jimage from an extracted directory (--dir)\n\
\ set - sets the value of specific jimage header entries\n\
\ verify - Reports errors on any .class entries that don't verify as classes.\n\
\n\
Possible options include:
-main.extended.help=\
-jimage recreate is extensible by the main of plugins. Following plugins have been discovered \
-thanks to ServiceLoader and can be used when re-creating a jimage.
-
error.prefix=Error:
warn.prefix=Warning:
main.opt.dir=\
-\ --dir Target directory for extract/recreate
+\ --dir Target directory for extract
main.opt.flags=\
\ --flags=value Set the jimage flags to value
@@ -38,14 +33,8 @@
main.opt.version=\
\ --version Version information
-main.opt.configuration=\
-\ --configuration <path> Path to properties file containing defaults\
-\ options for recreate
-
main.command.files=\
\ @<filename> Read options from file
-
-err.cannot.create.dir=cannot create directory: {0}
err.cannot.read.file=cannot read file: {0}
err.cannot.update.file=cannot update file: {0}
err.file.not.found=cannot find file: {0}
@@ -53,12 +42,11 @@
err.flags.not.int=--flags value not integer: {0}
err.internal.error=internal error: {0} {1} {2}
err.invalid.arg.for.option=invalid argument for option: {0}
-err.invalid.task=task must be extract|recreate|info|list|verify: {0}
-err.jimage.already.exists=jimage already exists: {0}
-err.jimage.not.specified=no jimage specified
+err.invalid.task=task must be extract|info|list|verify: {0}
err.missing.arg=no value given for {0}
err.not.a.dir=not a directory: {0}
err.not.a.jimage=not a jimage file: {0}
-err.only.one.jimage=only one jimage should be specified
+err.no.jimage=no jimage provided
+err.not.a.task=not a valid task: {0}
err.option.unsupported={0} not supported: {1}
err.unknown.option=unknown option: {0}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageLocationWriter.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageLocationWriter.java Thu Apr 28 23:08:17 2016 -0700
@@ -61,24 +61,32 @@
String baseName;
String extensionName = "";
- int offset = fullName.indexOf('/', 1);
- if (fullName.length() >= 2 && fullName.charAt(0) == '/' && offset != -1) {
- moduleName = fullName.substring(1, offset);
- fullName = fullName.substring(offset + 1);
- }
+ if (fullName.startsWith("/modules/")) {
+ moduleName = "modules";
+ baseName = fullName.substring("/modules/".length());
+ } else if ( fullName.startsWith("/packages/")) {
+ moduleName = "packages";
+ baseName = fullName.substring("/packages/".length());
+ } else {
+ int offset = fullName.indexOf('/', 1);
+ if (fullName.length() >= 2 && fullName.charAt(0) == '/' && offset != -1) {
+ moduleName = fullName.substring(1, offset);
+ fullName = fullName.substring(offset + 1);
+ }
- offset = fullName.lastIndexOf('/');
- if (1 < offset) {
- parentName = fullName.substring(0, offset);
- fullName = fullName.substring(offset + 1);
- }
+ offset = fullName.lastIndexOf('/');
+ if (1 < offset) {
+ parentName = fullName.substring(0, offset);
+ fullName = fullName.substring(offset + 1);
+ }
- offset = fullName.lastIndexOf('.');
- if (offset != -1) {
- baseName = fullName.substring(0, offset);
- extensionName = fullName.substring(offset + 1);
- } else {
- baseName = fullName;
+ offset = fullName.lastIndexOf('.');
+ if (offset != -1) {
+ baseName = fullName.substring(0, offset);
+ extensionName = fullName.substring(offset + 1);
+ } else {
+ baseName = fullName;
+ }
}
return new ImageLocationWriter(strings)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.tools.jlink.internal.packager;
+
+
+import jdk.tools.jlink.Jlink;
+import jdk.tools.jlink.builder.ImageBuilder;
+import jdk.tools.jlink.plugin.Plugin;
+import jdk.tools.jlink.builder.*;
+import jdk.tools.jlink.plugin.Pool;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+/**
+ * AppRuntimeImageBuilder is a private API used only by the Java Packager to generate
+ * a Java runtime image using jlink. AppRuntimeImageBuilder encapsulates the
+ * arguments that jlink requires to generate this image. To create the image call the
+ * build() method.
+ */
+public final class AppRuntimeImageBuilder {
+ private Path outputDir = null;
+ private List<Path> modulePath = null;
+ private Set<String> addModules = null;
+ private Set<String> limitModules = null;
+ private String excludeFileList = null;
+ private Map<String, String> userArguments = null;
+ private Boolean stripNativeCommands = null;
+
+ public AppRuntimeImageBuilder() {}
+
+ public void setOutputDir(Path value) {
+ outputDir = value;
+ }
+
+ public void setModulePath(List<Path> value) {
+ modulePath = value;
+ }
+
+ public void setAddModules(Set<String> value) {
+ addModules = value;
+ }
+
+ public void setLimitModules(Set<String> value) {
+ limitModules = value;
+ }
+
+ public void setExcludeFileList(String value) {
+ excludeFileList = value;
+ }
+
+ public void setStripNativeCommands(boolean value) {
+ stripNativeCommands = value;
+ }
+
+ public void setUserArguments(Map<String, String> value) {
+ userArguments = value;
+ }
+
+ public void build() throws IOException {
+ // jlink main arguments
+ Jlink.JlinkConfiguration jlinkConfig = new Jlink.JlinkConfiguration(
+ new File("").toPath(), // Unused
+ modulePath, addModules, limitModules);
+
+ // plugin configuration
+ List<Plugin> plugins = new ArrayList<Plugin>();
+
+ if (stripNativeCommands) {
+ plugins.add(Jlink.newPlugin(
+ "strip-native-commands",
+ Collections.singletonMap("strip-native-commands", "on"),
+ null));
+ }
+
+ if (excludeFileList != null && !excludeFileList.isEmpty()) {
+ plugins.add(Jlink.newPlugin(
+ "exclude-files",
+ Collections.singletonMap("exclude-files", excludeFileList),
+ null));
+ }
+
+ // add user supplied jlink arguments
+ for (Map.Entry<String, String> entry : userArguments.entrySet()) {
+ String key = entry.getKey();
+ String value = entry.getValue();
+ plugins.add(Jlink.newPlugin(key,
+ Collections.singletonMap(key, value),
+ null));
+ }
+
+ plugins.add(Jlink.newPlugin("installed-modules", Collections.emptyMap(), null));
+
+ // build the image
+ Jlink.PluginsConfiguration pluginConfig = new Jlink.PluginsConfiguration(
+ plugins, new DefaultImageBuilder(true, outputDir), null);
+ Jlink jlink = new Jlink();
+ jlink.build(jlinkConfig, pluginConfig);
+ }
+}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Pool.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Pool.java Thu Apr 28 23:08:17 2016 -0700
@@ -226,7 +226,7 @@
* <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file
* name}</li>
* <li>For other files (shared lib, launchers, config, ...):/{module name}/
- * {@literal bin|conf|native}/{dir1}>/.../{dirN}/{file name}</li>
+ * {@literal bin|conf|native}/{dir1}/.../{dirN}/{file name}</li>
* </ul>
*/
public static class ModuleData {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/module-info.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+module jdk.jstatd {
+ requires java.rmi;
+ requires jdk.jvmstat;
+
+ // RMI needs to serialize types in this package
+ exports sun.jvmstat.monitor.remote to java.rmi;
+
+ provides sun.jvmstat.monitor.MonitoredHostService with sun.jvmstat.perfdata.monitor.protocol.rmi.MonitoredHostRmiService;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/jvmstat/monitor/remote/RemoteHost.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * 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.jvmstat.monitor.remote;
+
+import sun.jvmstat.monitor.*;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.io.IOException;
+
+/**
+ * Remote Interface for discovering and attaching to remote
+ * monitorable Java Virtual Machines.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public interface RemoteHost extends Remote {
+
+ /**
+ * Remote method to attach to a remote HotSpot Java Virtual Machine
+ * identified by <code>vmid</code>.
+ *
+ * @param vmid The identifier for the target virtual machine.
+ * @return RemoteVm - A remote object for accessing the remote Java
+ * Virtual Machine.
+ *
+ * @throws MonitorException Thrown when any other error is encountered
+ * while communicating with the target virtual
+ * machine.
+ * @throws RemoteException
+ *
+ */
+ RemoteVm attachVm(int vmid, String mode) throws RemoteException,
+ MonitorException;
+
+ /**
+ * Remote method to detach from a remote HotSpot Java Virtual Machine
+ * identified by <code>vmid</code>.
+ *
+ * @param rvm The remote object for the target Java Virtual
+ * Machine.
+ *
+ * @throws MonitorException Thrown when any other error is encountered
+ * while communicating with the target virtual
+ * machine.
+ * @throws RemoteException
+ */
+ void detachVm(RemoteVm rvm) throws RemoteException, MonitorException;
+
+ /**
+ * Get a list of Local Virtual Machine Identifiers for the active
+ * Java Virtual Machine the remote system. A Local Virtual Machine
+ * Identifier is also known as an <em>lvmid</em>.
+ *
+ * @return int[] - A array of <em>lvmid</em>s.
+ * @throws MonitorException Thrown when any other error is encountered
+ * while communicating with the target virtual
+ * machine.
+ * @throws RemoteException
+ */
+ int[] activeVms() throws RemoteException, MonitorException;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/jvmstat/monitor/remote/RemoteVm.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * 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.jvmstat.monitor.remote;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+/**
+ * Interface for accessing the instrumentation exported by a
+ * Java Virtual Machine running on a remote host.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public interface RemoteVm extends Remote {
+
+ /**
+ * Interface to get the bytes associated with the instrumentation
+ * for the remote Java Virtual Machine.
+ *
+ * @return byte[] - a byte array containing the current bytes
+ * for the instrumentation exported by the
+ * remote Java Virtual Machine.
+ * @throws RemoteException Thrown on any communication error
+ */
+ byte[] getBytes() throws RemoteException;
+
+ /**
+ * Interface to get the size of the instrumentation buffer
+ * for the target Java Virtual Machine.
+ *
+ * @return int - the size of the instrumentation buffer for the
+ * remote Java Virtual Machine.
+ * @throws RemoteException Thrown on any communication error
+ */
+ int getCapacity() throws RemoteException;
+
+ /**
+ * Interface to return the Local Virtual Machine Identifier for
+ * the remote Java Virtual Machine. The Local Virtual Machine
+ * Identifier is also know as the <em>lvmid</em>.
+ *
+ * @throws RemoteException Thrown on any communication error
+ */
+ int getLocalVmId() throws RemoteException;
+
+ /**
+ * Interface to detach from the remote Java Virtual Machine.
+ *
+ * @throws RemoteException Thrown on any communication error
+ */
+ void detach() throws RemoteException;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/jvmstat/monitor/remote/package.html Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,39 @@
+<!doctype html public "-//IETF//DTD HTML/EN">
+<html>
+<head>
+<!--
+
+
+ Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ 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.
+
+
+-->
+</head>
+<body bgcolor="white">
+<p>
+Provides interfaces supporting remote monitoring for instrumented
+HotSpot Java Virtual Machines.
+</p>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostProvider.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+import sun.jvmstat.perfdata.monitor.*;
+import java.util.*;
+import java.net.*;
+import java.io.*;
+import java.rmi.*;
+import java.util.HashMap;
+
+/**
+ * Concrete implementation of the MonitoredHost interface for the
+ * <em>rmi</em> protocol of the HotSpot PerfData monitoring implementation.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class MonitoredHostProvider extends MonitoredHost {
+ private static final String serverName = "/JStatRemoteHost";
+ private static final int DEFAULT_POLLING_INTERVAL = 1000;
+
+ private ArrayList<HostListener> listeners;
+ private NotifierTask task;
+ private HashSet<Integer> activeVms;
+ private RemoteVmManager vmManager;
+ private RemoteHost remoteHost;
+ private Timer timer;
+
+ /**
+ * Create a MonitoredHostProvider instance using the given HostIdentifier.
+ *
+ * @param hostId the host identifier for this MonitoredHost
+ * @throws MonitorException Thrown on any error encountered while
+ * communicating with the remote host.
+ */
+ public MonitoredHostProvider(HostIdentifier hostId)
+ throws MonitorException {
+ this.hostId = hostId;
+ this.listeners = new ArrayList<HostListener>();
+ this.interval = DEFAULT_POLLING_INTERVAL;
+ this.activeVms = new HashSet<Integer>();
+
+ String rmiName;
+ String sn = serverName;
+ String path = hostId.getPath();
+
+ if ((path != null) && (path.length() > 0)) {
+ sn = path;
+ }
+
+ if (hostId.getPort() != -1) {
+ rmiName = "rmi://" + hostId.getHost() + ":" + hostId.getPort() + sn;
+ } else {
+ rmiName = "rmi://" + hostId.getHost() + sn;
+ }
+
+ try {
+ remoteHost = (RemoteHost)Naming.lookup(rmiName);
+
+ } catch (RemoteException e) {
+ /*
+ * rmi registry not available
+ *
+ * Access control exceptions, where the rmi server refuses a
+ * connection based on policy file configuration, come through
+ * here on the client side. Unfortunately, the RemoteException
+ * doesn't contain enough information to determine the true cause
+ * of the exception. So, we have to output a rather generic message.
+ */
+ String message = "RMI Registry not available at "
+ + hostId.getHost();
+
+ if (hostId.getPort() == -1) {
+ message = message + ":"
+ + java.rmi.registry.Registry.REGISTRY_PORT;
+ } else {
+ message = message + ":" + hostId.getPort();
+ }
+
+ if (e.getMessage() != null) {
+ throw new MonitorException(message + "\n" + e.getMessage(), e);
+ } else {
+ throw new MonitorException(message, e);
+ }
+
+ } catch (NotBoundException e) {
+ // no server with given name
+ String message = e.getMessage();
+ if (message == null) message = rmiName;
+ throw new MonitorException("RMI Server " + message
+ + " not available", e);
+ } catch (MalformedURLException e) {
+ // this is a programming problem
+ e.printStackTrace();
+ throw new IllegalArgumentException("Malformed URL: " + rmiName);
+ }
+ this.vmManager = new RemoteVmManager(remoteHost);
+ this.timer = new Timer(true);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public MonitoredVm getMonitoredVm(VmIdentifier vmid)
+ throws MonitorException {
+ return getMonitoredVm(vmid, DEFAULT_POLLING_INTERVAL);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public MonitoredVm getMonitoredVm(VmIdentifier vmid, int interval)
+ throws MonitorException {
+ VmIdentifier nvmid = null;
+ try {
+ nvmid = hostId.resolve(vmid);
+ RemoteVm rvm = remoteHost.attachVm(vmid.getLocalVmId(),
+ vmid.getMode());
+ RemoteMonitoredVm rmvm = new RemoteMonitoredVm(rvm, nvmid, timer,
+ interval);
+ rmvm.attach();
+ return rmvm;
+
+ } catch (RemoteException e) {
+ throw new MonitorException("Remote Exception attaching to "
+ + nvmid.toString(), e);
+ } catch (URISyntaxException e) {
+ /*
+ * the VmIdentifier is expected to be a valid and should resolve
+ * easonably against the host identifier. A URISyntaxException
+ * here is most likely a programming error.
+ */
+ throw new IllegalArgumentException("Malformed URI: "
+ + vmid.toString(), e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void detach(MonitoredVm vm) throws MonitorException {
+ RemoteMonitoredVm rmvm = (RemoteMonitoredVm)vm;
+ rmvm.detach();
+ try {
+ remoteHost.detachVm(rmvm.getRemoteVm());
+
+ } catch (RemoteException e) {
+ throw new MonitorException("Remote Exception detaching from "
+ + vm.getVmIdentifier().toString(), e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addHostListener(HostListener listener) {
+ synchronized(listeners) {
+ listeners.add(listener);
+ if (task == null) {
+ task = new NotifierTask();
+ timer.schedule(task, 0, interval);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removeHostListener(HostListener listener) {
+ /*
+ * XXX: if a disconnect method is added, make sure it calls
+ * this method to unregister this object from the watcher. otherwise,
+ * an unused MonitoredHostProvider instance may go uncollected.
+ */
+ synchronized(listeners) {
+ listeners.remove(listener);
+ if (listeners.isEmpty() && (task != null)) {
+ task.cancel();
+ task = null;
+ }
+ }
+ }
+
+ public void setInterval(int newInterval) {
+ synchronized(listeners) {
+ if (newInterval == interval) {
+ return;
+ }
+
+ int oldInterval = interval;
+ super.setInterval(newInterval);
+
+ if (task != null) {
+ task.cancel();
+ NotifierTask oldTask = task;
+ task = new NotifierTask();
+ CountedTimerTaskUtils.reschedule(timer, oldTask, task,
+ oldInterval, newInterval);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Set<Integer> activeVms() throws MonitorException {
+ return vmManager.activeVms();
+ }
+
+ /**
+ * Fire VmStatusChangeEvent events to HostListener objects
+ *
+ * @param active Set of Integer objects containing the local
+ * Vm Identifiers of the active JVMs
+ * @param started Set of Integer objects containing the local
+ * Vm Identifiers of new JVMs started since last
+ * interval.
+ * @param terminated Set of Integer objects containing the local
+ * Vm Identifiers of terminated JVMs since last
+ * interval.
+ */
+ @SuppressWarnings("unchecked") // Cast of result of clone
+ private void fireVmStatusChangedEvents(Set<Integer> active, Set<Integer> started,
+ Set<Integer> terminated) {
+ ArrayList<HostListener> registered = null;
+ VmStatusChangeEvent ev = null;
+
+ synchronized(listeners) {
+ registered = (ArrayList)listeners.clone();
+ }
+
+ for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+ HostListener l = i.next();
+ if (ev == null) {
+ ev = new VmStatusChangeEvent(this, active, started, terminated);
+ }
+ l.vmStatusChanged(ev);
+ }
+ }
+
+ /**
+ * Fire hostDisconnectEvent events.
+ */
+ @SuppressWarnings("unchecked") // Cast of result of clone
+ void fireDisconnectedEvents() {
+ ArrayList<HostListener> registered = null;
+ HostEvent ev = null;
+
+ synchronized(listeners) {
+ registered = (ArrayList)listeners.clone();
+ }
+
+ for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+ HostListener l = i.next();
+ if (ev == null) {
+ ev = new HostEvent(this);
+ }
+ l.disconnected(ev);
+ }
+ }
+
+ /**
+ * class to poll the remote machine and generate local event notifications.
+ */
+ private class NotifierTask extends CountedTimerTask {
+ public void run() {
+ super.run();
+
+ // save the last set of active JVMs
+ Set<Integer> lastActiveVms = activeVms;
+
+ try {
+ // get the current set of active JVMs
+ activeVms = (HashSet<Integer>)vmManager.activeVms();
+
+ } catch (MonitorException e) {
+ // XXX: use logging api
+ System.err.println("MonitoredHostProvider: polling task "
+ + "caught MonitorException:");
+ e.printStackTrace();
+
+ // mark the HostManager as errored and notify listeners
+ setLastException(e);
+ fireDisconnectedEvents();
+ }
+
+ if (activeVms.isEmpty()) {
+ return;
+ }
+
+ Set<Integer> startedVms = new HashSet<>();
+ Set<Integer> terminatedVms = new HashSet<>();
+
+ for (Iterator<Integer> i = activeVms.iterator(); i.hasNext(); /* empty */ ) {
+ Integer vmid = i.next();
+ if (!lastActiveVms.contains(vmid)) {
+ // a new file has been detected, add to set
+ startedVms.add(vmid);
+ }
+ }
+
+ for (Iterator<Integer> i = lastActiveVms.iterator(); i.hasNext();
+ /* empty */ ) {
+ Integer o = i.next();
+ if (!activeVms.contains(o)) {
+ // JVM has terminated, remove it from the active list
+ terminatedVms.add(o);
+ }
+ }
+
+ if (!startedVms.isEmpty() || !terminatedVms.isEmpty()) {
+ fireVmStatusChangedEvents(activeVms, startedVms, terminatedVms);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostRmiService.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.HostIdentifier;
+import sun.jvmstat.monitor.MonitorException;
+import sun.jvmstat.monitor.MonitoredHost;
+import sun.jvmstat.monitor.MonitoredHostService;
+
+public final class MonitoredHostRmiService implements MonitoredHostService {
+
+ @Override
+ public MonitoredHost getMonitoredHost(HostIdentifier hostId) throws MonitorException {
+ return new MonitoredHostProvider(hostId);
+ }
+
+ @Override
+ public String getScheme() {
+ return "rmi";
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/PerfDataBuffer.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * 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.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.remote.*;
+import sun.jvmstat.perfdata.monitor.*;
+import java.io.*;
+import java.rmi.RemoteException;
+import java.nio.ByteBuffer;
+
+/**
+ * The concrete PerfDataBuffer implementation for the <em>rmi:</em>
+ * protocol for the HotSpot PerfData monitoring implementation.
+ * <p>
+ * This class is responsible for acquiring the instrumentation buffer
+ * data for a remote target HotSpot Java Virtual Machine.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class PerfDataBuffer extends AbstractPerfDataBuffer {
+
+ private RemoteVm rvm;
+
+ /**
+ * Create a PerfDataBuffer instance for accessing the specified
+ * instrumentation buffer.
+ *
+ * @param rvm the proxy to the remote MonitredVm object
+ * @param lvmid the local Java Virtual Machine Identifier of the
+ * remote target.
+ *
+ * @throws MonitorException
+ */
+ public PerfDataBuffer(RemoteVm rvm, int lvmid) throws MonitorException {
+
+ this.rvm = rvm;
+ try {
+ ByteBuffer buffer = ByteBuffer.allocate(rvm.getCapacity());
+ sample(buffer);
+ createPerfDataBuffer(buffer, lvmid);
+
+ } catch (RemoteException e) {
+ throw new MonitorException("Could not read data for remote JVM "
+ + lvmid, e);
+ }
+ }
+
+ /**
+ * Get a copy of the remote instrumentation buffer.
+ *<p>
+ * The data in the remote instrumentation buffer is copied into
+ * the local byte buffer.
+ *
+ * @param buffer the buffer to receive the copy of the remote
+ * instrumentation buffer.
+ * @throws RemoteException Thrown on any communications errors with
+ * the remote system.
+ */
+ public void sample(ByteBuffer buffer) throws RemoteException {
+ assert buffer != null;
+ assert rvm != null;
+ synchronized(buffer) {
+ buffer.clear();
+ buffer.put(rvm.getBytes());
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+import sun.jvmstat.perfdata.monitor.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.rmi.*;
+
+/**
+ * Concrete implementation of the AbstractMonitoredVm class for the
+ * <em>rmi:</em> protocol for the HotSpot PerfData monitoring implementation.
+ * <p>
+ * This class provides the ability to acquire to the instrumentation buffer
+ * of a live, remote target Java Virtual Machine through an RMI server.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteMonitoredVm extends AbstractMonitoredVm {
+
+ private ArrayList<VmListener> listeners;
+ private NotifierTask notifierTask;
+ private SamplerTask samplerTask;
+ private Timer timer;
+
+ private RemoteVm rvm;
+ private ByteBuffer updateBuffer;
+
+ /**
+ * Create a RemoteMonitoredVm instance.
+ *
+ * @param rvm the proxy to the remote MonitoredVm instance.
+ * @param vmid the vm identifier specifying the remot target JVM
+ * @param timer the timer used to run polling tasks
+ * @param interval the sampling interval
+ */
+ public RemoteMonitoredVm(RemoteVm rvm, VmIdentifier vmid,
+ Timer timer, int interval)
+ throws MonitorException {
+ super(vmid, interval);
+ this.rvm = rvm;
+ pdb = new PerfDataBuffer(rvm, vmid.getLocalVmId());
+ this.listeners = new ArrayList<VmListener>();
+ this.timer = timer;
+ }
+
+ /**
+ * Method to attach to the remote MonitoredVm.
+ */
+ public void attach() throws MonitorException {
+ updateBuffer = pdb.getByteBuffer().duplicate();
+
+ // if continuous sampling is requested, register with the sampler thread
+ if (interval > 0) {
+ samplerTask = new SamplerTask();
+ timer.schedule(samplerTask, 0, interval);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void detach() {
+ try {
+ if (interval > 0) {
+ if (samplerTask != null) {
+ samplerTask.cancel();
+ samplerTask = null;
+ }
+ if (notifierTask != null) {
+ notifierTask.cancel();
+ notifierTask = null;
+ }
+ sample();
+ }
+ } catch (RemoteException e) {
+ // XXX: - use logging api? throw an exception instead?
+ System.err.println("Could not read data for remote JVM " + vmid);
+ e.printStackTrace();
+
+ } finally {
+ super.detach();
+ }
+ }
+
+ /**
+ * Get a copy of the remote instrumentation buffer.
+ *<p>
+ * The data in the remote instrumentation buffer is copied into
+ * a local byte buffer.
+ *
+ * @throws RemoteException Thrown on any communications errors with
+ * the remote system.
+ */
+ public void sample() throws RemoteException {
+ assert updateBuffer != null;
+ ((PerfDataBuffer)pdb).sample(updateBuffer);
+ }
+
+ /**
+ * Get the proxy to the remote MonitoredVm.
+ *
+ * @return RemoteVm - the proxy to the remote MonitoredVm.
+ */
+ public RemoteVm getRemoteVm() {
+ return rvm;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addVmListener(VmListener l) {
+ synchronized(listeners) {
+ listeners.add(l);
+ if (notifierTask == null) {
+ notifierTask = new NotifierTask();
+ timer.schedule(notifierTask, 0, interval);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removeVmListener(VmListener l) {
+ synchronized(listeners) {
+ listeners.remove(l);
+ if (listeners.isEmpty() && (notifierTask != null)) {
+ notifierTask.cancel();
+ notifierTask = null;
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setInterval(int newInterval) {
+ synchronized(listeners) {
+ if (newInterval == interval) {
+ return;
+ }
+
+ int oldInterval = interval;
+ super.setInterval(newInterval);
+
+ if (samplerTask != null) {
+ samplerTask.cancel();
+ SamplerTask oldSamplerTask = samplerTask;
+ samplerTask = new SamplerTask();
+ CountedTimerTaskUtils.reschedule(timer, oldSamplerTask,
+ samplerTask, oldInterval,
+ newInterval);
+ }
+ if (notifierTask != null) {
+ notifierTask.cancel();
+ NotifierTask oldNotifierTask = notifierTask;
+ notifierTask = new NotifierTask();
+ CountedTimerTaskUtils.reschedule(timer, oldNotifierTask,
+ notifierTask, oldInterval,
+ newInterval);
+ }
+ }
+ }
+
+ /**
+ * Fire MonitoredVmStructureChanged events.
+ *
+ * @param inserted List of Monitor objects inserted.
+ * @param removed List of Monitor objects removed.
+ */
+ @SuppressWarnings("unchecked") // Cast of result of clone
+ void fireMonitorStatusChangedEvents(List<Monitor> inserted, List<Monitor> removed) {
+ ArrayList<VmListener> registered = null;
+ MonitorStatusChangeEvent ev = null;
+
+ synchronized(listeners) {
+ registered = (ArrayList)listeners.clone();
+ }
+
+ for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+ VmListener l = i.next();
+ if (ev == null) {
+ ev = new MonitorStatusChangeEvent(this, inserted, removed);
+ }
+ l.monitorStatusChanged(ev);
+ }
+ }
+
+ /**
+ * Fire MonitoredVmStructureChanged events.
+ */
+ @SuppressWarnings("unchecked") // Cast of result of clone
+ void fireMonitorsUpdatedEvents() {
+ ArrayList<VmListener> registered = null;
+ VmEvent ev = null;
+
+ synchronized(listeners) {
+ registered = (ArrayList)listeners.clone();
+ }
+
+ for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+ VmListener l = i.next();
+ if (ev == null) {
+ ev = new VmEvent(this);
+ }
+ l.monitorsUpdated(ev);
+ }
+ }
+
+ /*
+ * Timer Tasks. There are two separate timer tasks here. The SamplerTask
+ * is active whenever we are attached to the remote JVM with a periodic
+ * sampling interval > 0. The NotifierTask is only active if a VmListener
+ * has registered with this RemoteMonitoredVm instance. Also, in the future
+ * we may want to run these tasks at different intervals. Currently,
+ * they run at the same interval and some significant work may
+ * need to be done to complete the separation of these two intervals.
+ */
+
+ /**
+ * Class to periodically check the state of the defined monitors
+ * for the remote MonitoredVm instance and to notify listeners of
+ * any detected changes.
+ */
+ private class NotifierTask extends CountedTimerTask {
+ public void run() {
+ super.run();
+ try {
+ MonitorStatus status = getMonitorStatus();
+
+ List<Monitor> inserted = status.getInserted();
+ List<Monitor> removed = status.getRemoved();
+
+ if (!inserted.isEmpty() || !removed.isEmpty()) {
+ fireMonitorStatusChangedEvents(inserted, removed);
+ }
+ } catch (MonitorException e) {
+ // XXX: use logging api? fire disconnect events? mark errored?
+ // fireDisconnectedEvents();
+ System.err.println("Exception updating monitors for "
+ + getVmIdentifier());
+ e.printStackTrace();
+ // XXX: should we cancle the notifierTask here?
+ // this.cancel();
+ }
+ }
+ }
+
+ /**
+ * Class to periodically sample the remote instrumentation byte buffer
+ * and refresh the local copy. Registered listeners are notified of
+ * the completion of a sampling event.
+ */
+ private class SamplerTask extends CountedTimerTask {
+ public void run() {
+ super.run();
+ try {
+ sample();
+ fireMonitorsUpdatedEvents();
+
+ } catch (RemoteException e) {
+ // XXX: use logging api, mark vm as errored.
+ System.err.println("Exception taking sample for "
+ + getVmIdentifier());
+ e.printStackTrace();
+ this.cancel();
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteVmManager.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * 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.jvmstat.perfdata.monitor.protocol.rmi;
+
+import java.util.*;
+import java.util.regex.*;
+import java.io.*;
+import java.rmi.RemoteException;
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Class for managing the RemoteMonitoredVm instances on a remote system.
+ * <p>
+ * This class is responsible for the mechanism that detects the active
+ * HotSpot Java Virtual Machines on the remote host and possibly for a
+ * specific user. The ability to detect all possible HotSpot Java Virtual
+ * Machines on the remote host may be limited by the permissions of the
+ * principal running the RMI server application on the remote host.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteVmManager {
+
+ private RemoteHost remoteHost;
+ private String user;
+
+ /**
+ * Creates a RemoteVmManager instance for the remote system.
+ * <p>
+ * Manages RemoteMonitordVm instances for which the principal
+ * running the remote server has appropriate permissions.
+ *
+ * @param remoteHost the remote proxy object to the RMI server on
+ * the remote system.
+ */
+ public RemoteVmManager(RemoteHost remoteHost) {
+ this(remoteHost, null);
+ }
+
+ /**
+ * Creates a RemoteVmManager instance for the given user.
+ * <p>
+ * Manages RemoteMonitoredVm instances for all remote Java Virtual
+ * machines owned by the specified user on the remote system. The
+ * RMI server on the remote system must have the appropriate permissions
+ * to access the named users Java Virtual Machines.
+ *
+ * @param remoteHost the remote proxy object to the RMI server on
+ * the remote system.
+ * @param user the name of the user
+ */
+ public RemoteVmManager(RemoteHost remoteHost, String user) {
+ this.user = user;
+ this.remoteHost = remoteHost;
+ }
+
+ /**
+ * Return the current set of monitorable Java Virtual Machines.
+ * <p>
+ * The set returned by this method depends on the user name passed
+ * to the constructor. If no user name was specified, then this
+ * method will return all candidate JVMs on the system. Otherwise,
+ * only the JVMs for the given user will be returned. This assumes
+ * that the RMI server process has the appropriate permissions to
+ * access the target set of JVMs.
+ *
+ * @return Set - the Set of monitorable Java Virtual Machines
+ */
+ public Set<Integer> activeVms() throws MonitorException {
+ int[] active = null;
+
+ try {
+ active = remoteHost.activeVms();
+
+ } catch (RemoteException e) {
+ throw new MonitorException("Error communicating with remote host: "
+ + e.getMessage(), e);
+ }
+
+ Set<Integer> activeSet = new HashSet<Integer>(active.length);
+
+ for (int i = 0; i < active.length; i++) {
+ activeSet.add(active[i]);
+ }
+
+ return activeSet;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/package.html Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,47 @@
+<!doctype html public "-//IETF//DTD HTML/EN">
+<html>
+<head>
+<!--
+
+
+ Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ 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.
+
+-->
+</head>
+<body bgcolor="white">
+<p>
+Provides the implementation classes for the <em>rmi:</em> protocol for
+the HotSpot PerfData instrumentation buffer monitoring implementation.
+</p>
+<p>
+The <em>rmi:</em> protocol is the default protocol for the PerfData
+implementation when a hostname is specified as part of a HostIdentifier
+or VMIdentifier. It communicates with an RMI server on the remote machine
+that provides functions to get a list of available Java Virtual Machines
+and to acquire a copy of a Java Virtual Machine's instrumentation buffer.
+The RMI server may or may not use the PerfData implementation on the
+remote host to acquire this information. The <em>jstatd</em> server
+provides a PerfData implementation of the RMI server.
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/tools/jstatd/Jstatd.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.tools.jstatd;
+
+import java.rmi.*;
+import java.rmi.server.*;
+import java.rmi.registry.Registry;
+import java.rmi.registry.LocateRegistry;
+import java.net.MalformedURLException;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Application providing remote access to the jvmstat instrumentation
+ * exported by local Java Virtual Machine processes. Remote access is
+ * provided through an RMI interface.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class Jstatd {
+
+ private static Registry registry;
+ private static int port = -1;
+ private static boolean startRegistry = true;
+
+ private static void printUsage() {
+ System.err.println("usage: jstatd [-nr] [-p port] [-n rminame]");
+ }
+
+ static void bind(String name, RemoteHostImpl remoteHost)
+ throws RemoteException, MalformedURLException, Exception {
+
+ try {
+ Naming.rebind(name, remoteHost);
+ } catch (java.rmi.ConnectException e) {
+ /*
+ * either the registry is not running or we cannot contact it.
+ * start an internal registry if requested.
+ */
+ if (startRegistry && registry == null) {
+ int localport = (port < 0) ? Registry.REGISTRY_PORT : port;
+ registry = LocateRegistry.createRegistry(localport);
+ bind(name, remoteHost);
+ } else {
+ throw e;
+ }
+ }
+ }
+
+ @SuppressWarnings("deprecation") // Use of RMISecurityManager
+ public static void main(String[] args) {
+ String rminame = null;
+ int argc = 0;
+
+ for ( ; (argc < args.length) && (args[argc].startsWith("-")); argc++) {
+ String arg = args[argc];
+
+ if (arg.compareTo("-nr") == 0) {
+ startRegistry = false;
+ } else if (arg.startsWith("-p")) {
+ if (arg.compareTo("-p") != 0) {
+ port = Integer.parseInt(arg.substring(2));
+ } else {
+ argc++;
+ if (argc >= args.length) {
+ printUsage();
+ System.exit(1);
+ }
+ port = Integer.parseInt(args[argc]);
+ }
+ } else if (arg.startsWith("-n")) {
+ if (arg.compareTo("-n") != 0) {
+ rminame = arg.substring(2);
+ } else {
+ argc++;
+ if (argc >= args.length) {
+ printUsage();
+ System.exit(1);
+ }
+ rminame = args[argc];
+ }
+ } else {
+ printUsage();
+ System.exit(1);
+ }
+ }
+
+ if (argc < args.length) {
+ printUsage();
+ System.exit(1);
+ }
+
+ if (System.getSecurityManager() == null) {
+ System.setSecurityManager(new RMISecurityManager());
+ }
+
+ StringBuilder name = new StringBuilder();
+
+ if (port >= 0) {
+ name.append("//:").append(port);
+ }
+
+ if (rminame == null) {
+ rminame = "JStatRemoteHost";
+ }
+
+ name.append("/").append(rminame);
+
+ try {
+ // use 1.5.0 dynamically generated subs.
+ System.setProperty("java.rmi.server.ignoreSubClasses", "true");
+ RemoteHostImpl remoteHost = new RemoteHostImpl();
+ RemoteHost stub = (RemoteHost) UnicastRemoteObject.exportObject(
+ remoteHost, 0);
+ bind(name.toString(), remoteHost);
+ System.out.println("jstatd started (bound to " + name.toString() + ")");
+ System.out.flush();
+ } catch (MalformedURLException e) {
+ if (rminame != null) {
+ System.out.println("Bad RMI server name: " + rminame);
+ } else {
+ System.out.println("Bad RMI URL: " + name);
+ }
+ e.printStackTrace(System.out);
+ System.exit(1);
+ } catch (java.rmi.ConnectException e) {
+ // could not attach to or create a registry
+ System.out.println("Could not contact RMI registry");
+ e.printStackTrace(System.out);
+ System.exit(1);
+ } catch (RemoteException e) {
+ System.out.println("Could not bind " + name + " to RMI Registry");
+ e.printStackTrace(System.out);
+ System.exit(1);
+ } catch (Exception e) {
+ System.out.println("Could not create remote object");
+ e.printStackTrace(System.out);
+ System.exit(1);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/tools/jstatd/RemoteHostImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.tools.jstatd;
+
+import java.util.*;
+import java.nio.*;
+import java.io.*;
+import java.net.*;
+import java.rmi.*;
+import java.rmi.server.*;
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Concrete implementation of the RemoteHost interface for the HotSpot
+ * PerfData <em>rmi:</em> protocol.
+ * <p>
+ * This class provides remote access to the instrumentation exported
+ * by HotSpot Java Virtual Machines through the PerfData shared memory
+ * interface.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteHostImpl implements RemoteHost, HostListener {
+
+ private MonitoredHost monitoredHost;
+ private Set<Integer> activeVms;
+
+ public RemoteHostImpl() throws MonitorException {
+ try {
+ monitoredHost = MonitoredHost.getMonitoredHost("localhost");
+ } catch (URISyntaxException e) { }
+
+ activeVms = monitoredHost.activeVms();
+ monitoredHost.addHostListener(this);
+ }
+
+ public RemoteVm attachVm(int lvmid, String mode)
+ throws RemoteException, MonitorException {
+ Integer v = lvmid;
+ RemoteVm stub = null;
+ StringBuilder sb = new StringBuilder();
+
+ sb.append("local://").append(lvmid).append("@localhost");
+ if (mode != null) {
+ sb.append("?mode=").append(mode);
+ }
+
+ String vmidStr = sb.toString();
+
+ try {
+ VmIdentifier vmid = new VmIdentifier(vmidStr);
+ MonitoredVm mvm = monitoredHost.getMonitoredVm(vmid);
+ RemoteVmImpl rvm = new RemoteVmImpl((BufferedMonitoredVm)mvm);
+ stub = (RemoteVm) UnicastRemoteObject.exportObject(rvm, 0);
+ }
+ catch (URISyntaxException e) {
+ throw new RuntimeException("Malformed VmIdentifier URI: "
+ + vmidStr, e);
+ }
+ return stub;
+ }
+
+ public void detachVm(RemoteVm rvm) throws RemoteException {
+ rvm.detach();
+ }
+
+ public int[] activeVms() throws MonitorException {
+ Object[] vms = null;
+ int[] vmids = null;
+
+ vms = monitoredHost.activeVms().toArray();
+ vmids = new int[vms.length];
+
+ for (int i = 0; i < vmids.length; i++) {
+ vmids[i] = ((Integer)vms[i]).intValue();
+ }
+ return vmids;
+ }
+
+ public void vmStatusChanged(VmStatusChangeEvent ev) {
+ synchronized(this.activeVms) {
+ activeVms.retainAll(ev.getActive());
+ }
+ }
+
+ public void disconnected(HostEvent ev) {
+ // we only monitor the local host, so this event shouldn't occur.
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/tools/jstatd/RemoteVmImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.tools.jstatd;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Concrete implementation of the RemoteVm interface for the HotSpot PerfData
+ * shared memory implementation of the jvmstat monitoring APIs. This class
+ * providing remote access to the instrumentation exported by a local HotSpot
+ * Java Virtual Machine. The instrumentation buffer is shipped in whole to
+ * the remote machine, which is responsible for parsing and provide access
+ * to the contained data.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteVmImpl implements RemoteVm {
+
+ private BufferedMonitoredVm mvm;
+
+ RemoteVmImpl(BufferedMonitoredVm mvm) {
+ this.mvm = mvm;
+ }
+
+ public byte[] getBytes() {
+ return mvm.getBytes();
+ }
+
+ public int getCapacity() {
+ return mvm.getCapacity();
+ }
+
+ public void detach() {
+ mvm.detach();
+ }
+
+ public int getLocalVmId() {
+ return mvm.getVmIdentifier().getLocalVmId();
+ }
+}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/module-info.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-module jdk.jvmstat.rmi {
- requires java.rmi;
- requires jdk.jvmstat;
-
- // RMI needs to serialize types in this package
- exports sun.jvmstat.monitor.remote to java.rmi;
-
- provides sun.jvmstat.monitor.MonitoredHostService with sun.jvmstat.perfdata.monitor.protocol.rmi.MonitoredHostRmiService;
-}
-
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteHost.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * 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.jvmstat.monitor.remote;
-
-import sun.jvmstat.monitor.*;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.io.IOException;
-
-/**
- * Remote Interface for discovering and attaching to remote
- * monitorable Java Virtual Machines.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public interface RemoteHost extends Remote {
-
- /**
- * Remote method to attach to a remote HotSpot Java Virtual Machine
- * identified by <code>vmid</code>.
- *
- * @param vmid The identifier for the target virtual machine.
- * @return RemoteVm - A remote object for accessing the remote Java
- * Virtual Machine.
- *
- * @throws MonitorException Thrown when any other error is encountered
- * while communicating with the target virtual
- * machine.
- * @throws RemoteException
- *
- */
- RemoteVm attachVm(int vmid, String mode) throws RemoteException,
- MonitorException;
-
- /**
- * Remote method to detach from a remote HotSpot Java Virtual Machine
- * identified by <code>vmid</code>.
- *
- * @param rvm The remote object for the target Java Virtual
- * Machine.
- *
- * @throws MonitorException Thrown when any other error is encountered
- * while communicating with the target virtual
- * machine.
- * @throws RemoteException
- */
- void detachVm(RemoteVm rvm) throws RemoteException, MonitorException;
-
- /**
- * Get a list of Local Virtual Machine Identifiers for the active
- * Java Virtual Machine the remote system. A Local Virtual Machine
- * Identifier is also known as an <em>lvmid</em>.
- *
- * @return int[] - A array of <em>lvmid</em>s.
- * @throws MonitorException Thrown when any other error is encountered
- * while communicating with the target virtual
- * machine.
- * @throws RemoteException
- */
- int[] activeVms() throws RemoteException, MonitorException;
-}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteVm.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * 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.jvmstat.monitor.remote;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-/**
- * Interface for accessing the instrumentation exported by a
- * Java Virtual Machine running on a remote host.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public interface RemoteVm extends Remote {
-
- /**
- * Interface to get the bytes associated with the instrumentation
- * for the remote Java Virtual Machine.
- *
- * @return byte[] - a byte array containing the current bytes
- * for the instrumentation exported by the
- * remote Java Virtual Machine.
- * @throws RemoteException Thrown on any communication error
- */
- byte[] getBytes() throws RemoteException;
-
- /**
- * Interface to get the size of the instrumentation buffer
- * for the target Java Virtual Machine.
- *
- * @return int - the size of the instrumentation buffer for the
- * remote Java Virtual Machine.
- * @throws RemoteException Thrown on any communication error
- */
- int getCapacity() throws RemoteException;
-
- /**
- * Interface to return the Local Virtual Machine Identifier for
- * the remote Java Virtual Machine. The Local Virtual Machine
- * Identifier is also know as the <em>lvmid</em>.
- *
- * @throws RemoteException Thrown on any communication error
- */
- int getLocalVmId() throws RemoteException;
-
- /**
- * Interface to detach from the remote Java Virtual Machine.
- *
- * @throws RemoteException Thrown on any communication error
- */
- void detach() throws RemoteException;
-}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/package.html Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-<!doctype html public "-//IETF//DTD HTML/EN">
-<html>
-<head>
-<!--
-
-
- Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- 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.
-
-
--->
-</head>
-<body bgcolor="white">
-<p>
-Provides interfaces supporting remote monitoring for instrumented
-HotSpot Java Virtual Machines.
-</p>
-</body>
-</html>
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostProvider.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,343 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-import sun.jvmstat.perfdata.monitor.*;
-import java.util.*;
-import java.net.*;
-import java.io.*;
-import java.rmi.*;
-import java.util.HashMap;
-
-/**
- * Concrete implementation of the MonitoredHost interface for the
- * <em>rmi</em> protocol of the HotSpot PerfData monitoring implementation.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class MonitoredHostProvider extends MonitoredHost {
- private static final String serverName = "/JStatRemoteHost";
- private static final int DEFAULT_POLLING_INTERVAL = 1000;
-
- private ArrayList<HostListener> listeners;
- private NotifierTask task;
- private HashSet<Integer> activeVms;
- private RemoteVmManager vmManager;
- private RemoteHost remoteHost;
- private Timer timer;
-
- /**
- * Create a MonitoredHostProvider instance using the given HostIdentifier.
- *
- * @param hostId the host identifier for this MonitoredHost
- * @throws MonitorException Thrown on any error encountered while
- * communicating with the remote host.
- */
- public MonitoredHostProvider(HostIdentifier hostId)
- throws MonitorException {
- this.hostId = hostId;
- this.listeners = new ArrayList<HostListener>();
- this.interval = DEFAULT_POLLING_INTERVAL;
- this.activeVms = new HashSet<Integer>();
-
- String rmiName;
- String sn = serverName;
- String path = hostId.getPath();
-
- if ((path != null) && (path.length() > 0)) {
- sn = path;
- }
-
- if (hostId.getPort() != -1) {
- rmiName = "rmi://" + hostId.getHost() + ":" + hostId.getPort() + sn;
- } else {
- rmiName = "rmi://" + hostId.getHost() + sn;
- }
-
- try {
- remoteHost = (RemoteHost)Naming.lookup(rmiName);
-
- } catch (RemoteException e) {
- /*
- * rmi registry not available
- *
- * Access control exceptions, where the rmi server refuses a
- * connection based on policy file configuration, come through
- * here on the client side. Unfortunately, the RemoteException
- * doesn't contain enough information to determine the true cause
- * of the exception. So, we have to output a rather generic message.
- */
- String message = "RMI Registry not available at "
- + hostId.getHost();
-
- if (hostId.getPort() == -1) {
- message = message + ":"
- + java.rmi.registry.Registry.REGISTRY_PORT;
- } else {
- message = message + ":" + hostId.getPort();
- }
-
- if (e.getMessage() != null) {
- throw new MonitorException(message + "\n" + e.getMessage(), e);
- } else {
- throw new MonitorException(message, e);
- }
-
- } catch (NotBoundException e) {
- // no server with given name
- String message = e.getMessage();
- if (message == null) message = rmiName;
- throw new MonitorException("RMI Server " + message
- + " not available", e);
- } catch (MalformedURLException e) {
- // this is a programming problem
- e.printStackTrace();
- throw new IllegalArgumentException("Malformed URL: " + rmiName);
- }
- this.vmManager = new RemoteVmManager(remoteHost);
- this.timer = new Timer(true);
- }
-
- /**
- * {@inheritDoc}
- */
- public MonitoredVm getMonitoredVm(VmIdentifier vmid)
- throws MonitorException {
- return getMonitoredVm(vmid, DEFAULT_POLLING_INTERVAL);
- }
-
- /**
- * {@inheritDoc}
- */
- public MonitoredVm getMonitoredVm(VmIdentifier vmid, int interval)
- throws MonitorException {
- VmIdentifier nvmid = null;
- try {
- nvmid = hostId.resolve(vmid);
- RemoteVm rvm = remoteHost.attachVm(vmid.getLocalVmId(),
- vmid.getMode());
- RemoteMonitoredVm rmvm = new RemoteMonitoredVm(rvm, nvmid, timer,
- interval);
- rmvm.attach();
- return rmvm;
-
- } catch (RemoteException e) {
- throw new MonitorException("Remote Exception attaching to "
- + nvmid.toString(), e);
- } catch (URISyntaxException e) {
- /*
- * the VmIdentifier is expected to be a valid and should resolve
- * easonably against the host identifier. A URISyntaxException
- * here is most likely a programming error.
- */
- throw new IllegalArgumentException("Malformed URI: "
- + vmid.toString(), e);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void detach(MonitoredVm vm) throws MonitorException {
- RemoteMonitoredVm rmvm = (RemoteMonitoredVm)vm;
- rmvm.detach();
- try {
- remoteHost.detachVm(rmvm.getRemoteVm());
-
- } catch (RemoteException e) {
- throw new MonitorException("Remote Exception detaching from "
- + vm.getVmIdentifier().toString(), e);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void addHostListener(HostListener listener) {
- synchronized(listeners) {
- listeners.add(listener);
- if (task == null) {
- task = new NotifierTask();
- timer.schedule(task, 0, interval);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void removeHostListener(HostListener listener) {
- /*
- * XXX: if a disconnect method is added, make sure it calls
- * this method to unregister this object from the watcher. otherwise,
- * an unused MonitoredHostProvider instance may go uncollected.
- */
- synchronized(listeners) {
- listeners.remove(listener);
- if (listeners.isEmpty() && (task != null)) {
- task.cancel();
- task = null;
- }
- }
- }
-
- public void setInterval(int newInterval) {
- synchronized(listeners) {
- if (newInterval == interval) {
- return;
- }
-
- int oldInterval = interval;
- super.setInterval(newInterval);
-
- if (task != null) {
- task.cancel();
- NotifierTask oldTask = task;
- task = new NotifierTask();
- CountedTimerTaskUtils.reschedule(timer, oldTask, task,
- oldInterval, newInterval);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public Set<Integer> activeVms() throws MonitorException {
- return vmManager.activeVms();
- }
-
- /**
- * Fire VmStatusChangeEvent events to HostListener objects
- *
- * @param active Set of Integer objects containing the local
- * Vm Identifiers of the active JVMs
- * @param started Set of Integer objects containing the local
- * Vm Identifiers of new JVMs started since last
- * interval.
- * @param terminated Set of Integer objects containing the local
- * Vm Identifiers of terminated JVMs since last
- * interval.
- */
- @SuppressWarnings("unchecked") // Cast of result of clone
- private void fireVmStatusChangedEvents(Set<Integer> active, Set<Integer> started,
- Set<Integer> terminated) {
- ArrayList<HostListener> registered = null;
- VmStatusChangeEvent ev = null;
-
- synchronized(listeners) {
- registered = (ArrayList)listeners.clone();
- }
-
- for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
- HostListener l = i.next();
- if (ev == null) {
- ev = new VmStatusChangeEvent(this, active, started, terminated);
- }
- l.vmStatusChanged(ev);
- }
- }
-
- /**
- * Fire hostDisconnectEvent events.
- */
- @SuppressWarnings("unchecked") // Cast of result of clone
- void fireDisconnectedEvents() {
- ArrayList<HostListener> registered = null;
- HostEvent ev = null;
-
- synchronized(listeners) {
- registered = (ArrayList)listeners.clone();
- }
-
- for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
- HostListener l = i.next();
- if (ev == null) {
- ev = new HostEvent(this);
- }
- l.disconnected(ev);
- }
- }
-
- /**
- * class to poll the remote machine and generate local event notifications.
- */
- private class NotifierTask extends CountedTimerTask {
- public void run() {
- super.run();
-
- // save the last set of active JVMs
- Set<Integer> lastActiveVms = activeVms;
-
- try {
- // get the current set of active JVMs
- activeVms = (HashSet<Integer>)vmManager.activeVms();
-
- } catch (MonitorException e) {
- // XXX: use logging api
- System.err.println("MonitoredHostProvider: polling task "
- + "caught MonitorException:");
- e.printStackTrace();
-
- // mark the HostManager as errored and notify listeners
- setLastException(e);
- fireDisconnectedEvents();
- }
-
- if (activeVms.isEmpty()) {
- return;
- }
-
- Set<Integer> startedVms = new HashSet<>();
- Set<Integer> terminatedVms = new HashSet<>();
-
- for (Iterator<Integer> i = activeVms.iterator(); i.hasNext(); /* empty */ ) {
- Integer vmid = i.next();
- if (!lastActiveVms.contains(vmid)) {
- // a new file has been detected, add to set
- startedVms.add(vmid);
- }
- }
-
- for (Iterator<Integer> i = lastActiveVms.iterator(); i.hasNext();
- /* empty */ ) {
- Integer o = i.next();
- if (!activeVms.contains(o)) {
- // JVM has terminated, remove it from the active list
- terminatedVms.add(o);
- }
- }
-
- if (!startedVms.isEmpty() || !terminatedVms.isEmpty()) {
- fireVmStatusChangedEvents(activeVms, startedVms, terminatedVms);
- }
- }
- }
-}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostRmiService.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.HostIdentifier;
-import sun.jvmstat.monitor.MonitorException;
-import sun.jvmstat.monitor.MonitoredHost;
-import sun.jvmstat.monitor.MonitoredHostService;
-
-public final class MonitoredHostRmiService implements MonitoredHostService {
-
- @Override
- public MonitoredHost getMonitoredHost(HostIdentifier hostId) throws MonitorException {
- return new MonitoredHostProvider(hostId);
- }
-
- @Override
- public String getScheme() {
- return "rmi";
- }
-
-}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/PerfDataBuffer.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * 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.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.remote.*;
-import sun.jvmstat.perfdata.monitor.*;
-import java.io.*;
-import java.rmi.RemoteException;
-import java.nio.ByteBuffer;
-
-/**
- * The concrete PerfDataBuffer implementation for the <em>rmi:</em>
- * protocol for the HotSpot PerfData monitoring implementation.
- * <p>
- * This class is responsible for acquiring the instrumentation buffer
- * data for a remote target HotSpot Java Virtual Machine.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class PerfDataBuffer extends AbstractPerfDataBuffer {
-
- private RemoteVm rvm;
-
- /**
- * Create a PerfDataBuffer instance for accessing the specified
- * instrumentation buffer.
- *
- * @param rvm the proxy to the remote MonitredVm object
- * @param lvmid the local Java Virtual Machine Identifier of the
- * remote target.
- *
- * @throws MonitorException
- */
- public PerfDataBuffer(RemoteVm rvm, int lvmid) throws MonitorException {
-
- this.rvm = rvm;
- try {
- ByteBuffer buffer = ByteBuffer.allocate(rvm.getCapacity());
- sample(buffer);
- createPerfDataBuffer(buffer, lvmid);
-
- } catch (RemoteException e) {
- throw new MonitorException("Could not read data for remote JVM "
- + lvmid, e);
- }
- }
-
- /**
- * Get a copy of the remote instrumentation buffer.
- *<p>
- * The data in the remote instrumentation buffer is copied into
- * the local byte buffer.
- *
- * @param buffer the buffer to receive the copy of the remote
- * instrumentation buffer.
- * @throws RemoteException Thrown on any communications errors with
- * the remote system.
- */
- public void sample(ByteBuffer buffer) throws RemoteException {
- assert buffer != null;
- assert rvm != null;
- synchronized(buffer) {
- buffer.clear();
- buffer.put(rvm.getBytes());
- }
- }
-}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,300 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-import sun.jvmstat.perfdata.monitor.*;
-import java.lang.reflect.*;
-import java.util.*;
-import java.io.*;
-import java.nio.ByteBuffer;
-import java.rmi.*;
-
-/**
- * Concrete implementation of the AbstractMonitoredVm class for the
- * <em>rmi:</em> protocol for the HotSpot PerfData monitoring implementation.
- * <p>
- * This class provides the ability to acquire to the instrumentation buffer
- * of a live, remote target Java Virtual Machine through an RMI server.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteMonitoredVm extends AbstractMonitoredVm {
-
- private ArrayList<VmListener> listeners;
- private NotifierTask notifierTask;
- private SamplerTask samplerTask;
- private Timer timer;
-
- private RemoteVm rvm;
- private ByteBuffer updateBuffer;
-
- /**
- * Create a RemoteMonitoredVm instance.
- *
- * @param rvm the proxy to the remote MonitoredVm instance.
- * @param vmid the vm identifier specifying the remot target JVM
- * @param timer the timer used to run polling tasks
- * @param interval the sampling interval
- */
- public RemoteMonitoredVm(RemoteVm rvm, VmIdentifier vmid,
- Timer timer, int interval)
- throws MonitorException {
- super(vmid, interval);
- this.rvm = rvm;
- pdb = new PerfDataBuffer(rvm, vmid.getLocalVmId());
- this.listeners = new ArrayList<VmListener>();
- this.timer = timer;
- }
-
- /**
- * Method to attach to the remote MonitoredVm.
- */
- public void attach() throws MonitorException {
- updateBuffer = pdb.getByteBuffer().duplicate();
-
- // if continuous sampling is requested, register with the sampler thread
- if (interval > 0) {
- samplerTask = new SamplerTask();
- timer.schedule(samplerTask, 0, interval);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void detach() {
- try {
- if (interval > 0) {
- if (samplerTask != null) {
- samplerTask.cancel();
- samplerTask = null;
- }
- if (notifierTask != null) {
- notifierTask.cancel();
- notifierTask = null;
- }
- sample();
- }
- } catch (RemoteException e) {
- // XXX: - use logging api? throw an exception instead?
- System.err.println("Could not read data for remote JVM " + vmid);
- e.printStackTrace();
-
- } finally {
- super.detach();
- }
- }
-
- /**
- * Get a copy of the remote instrumentation buffer.
- *<p>
- * The data in the remote instrumentation buffer is copied into
- * a local byte buffer.
- *
- * @throws RemoteException Thrown on any communications errors with
- * the remote system.
- */
- public void sample() throws RemoteException {
- assert updateBuffer != null;
- ((PerfDataBuffer)pdb).sample(updateBuffer);
- }
-
- /**
- * Get the proxy to the remote MonitoredVm.
- *
- * @return RemoteVm - the proxy to the remote MonitoredVm.
- */
- public RemoteVm getRemoteVm() {
- return rvm;
- }
-
- /**
- * {@inheritDoc}
- */
- public void addVmListener(VmListener l) {
- synchronized(listeners) {
- listeners.add(l);
- if (notifierTask == null) {
- notifierTask = new NotifierTask();
- timer.schedule(notifierTask, 0, interval);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void removeVmListener(VmListener l) {
- synchronized(listeners) {
- listeners.remove(l);
- if (listeners.isEmpty() && (notifierTask != null)) {
- notifierTask.cancel();
- notifierTask = null;
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void setInterval(int newInterval) {
- synchronized(listeners) {
- if (newInterval == interval) {
- return;
- }
-
- int oldInterval = interval;
- super.setInterval(newInterval);
-
- if (samplerTask != null) {
- samplerTask.cancel();
- SamplerTask oldSamplerTask = samplerTask;
- samplerTask = new SamplerTask();
- CountedTimerTaskUtils.reschedule(timer, oldSamplerTask,
- samplerTask, oldInterval,
- newInterval);
- }
- if (notifierTask != null) {
- notifierTask.cancel();
- NotifierTask oldNotifierTask = notifierTask;
- notifierTask = new NotifierTask();
- CountedTimerTaskUtils.reschedule(timer, oldNotifierTask,
- notifierTask, oldInterval,
- newInterval);
- }
- }
- }
-
- /**
- * Fire MonitoredVmStructureChanged events.
- *
- * @param inserted List of Monitor objects inserted.
- * @param removed List of Monitor objects removed.
- */
- @SuppressWarnings("unchecked") // Cast of result of clone
- void fireMonitorStatusChangedEvents(List<Monitor> inserted, List<Monitor> removed) {
- ArrayList<VmListener> registered = null;
- MonitorStatusChangeEvent ev = null;
-
- synchronized(listeners) {
- registered = (ArrayList)listeners.clone();
- }
-
- for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
- VmListener l = i.next();
- if (ev == null) {
- ev = new MonitorStatusChangeEvent(this, inserted, removed);
- }
- l.monitorStatusChanged(ev);
- }
- }
-
- /**
- * Fire MonitoredVmStructureChanged events.
- */
- @SuppressWarnings("unchecked") // Cast of result of clone
- void fireMonitorsUpdatedEvents() {
- ArrayList<VmListener> registered = null;
- VmEvent ev = null;
-
- synchronized(listeners) {
- registered = (ArrayList)listeners.clone();
- }
-
- for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
- VmListener l = i.next();
- if (ev == null) {
- ev = new VmEvent(this);
- }
- l.monitorsUpdated(ev);
- }
- }
-
- /*
- * Timer Tasks. There are two separate timer tasks here. The SamplerTask
- * is active whenever we are attached to the remote JVM with a periodic
- * sampling interval > 0. The NotifierTask is only active if a VmListener
- * has registered with this RemoteMonitoredVm instance. Also, in the future
- * we may want to run these tasks at different intervals. Currently,
- * they run at the same interval and some significant work may
- * need to be done to complete the separation of these two intervals.
- */
-
- /**
- * Class to periodically check the state of the defined monitors
- * for the remote MonitoredVm instance and to notify listeners of
- * any detected changes.
- */
- private class NotifierTask extends CountedTimerTask {
- public void run() {
- super.run();
- try {
- MonitorStatus status = getMonitorStatus();
-
- List<Monitor> inserted = status.getInserted();
- List<Monitor> removed = status.getRemoved();
-
- if (!inserted.isEmpty() || !removed.isEmpty()) {
- fireMonitorStatusChangedEvents(inserted, removed);
- }
- } catch (MonitorException e) {
- // XXX: use logging api? fire disconnect events? mark errored?
- // fireDisconnectedEvents();
- System.err.println("Exception updating monitors for "
- + getVmIdentifier());
- e.printStackTrace();
- // XXX: should we cancle the notifierTask here?
- // this.cancel();
- }
- }
- }
-
- /**
- * Class to periodically sample the remote instrumentation byte buffer
- * and refresh the local copy. Registered listeners are notified of
- * the completion of a sampling event.
- */
- private class SamplerTask extends CountedTimerTask {
- public void run() {
- super.run();
- try {
- sample();
- fireMonitorsUpdatedEvents();
-
- } catch (RemoteException e) {
- // XXX: use logging api, mark vm as errored.
- System.err.println("Exception taking sample for "
- + getVmIdentifier());
- e.printStackTrace();
- this.cancel();
- }
- }
- }
-}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteVmManager.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * 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.jvmstat.perfdata.monitor.protocol.rmi;
-
-import java.util.*;
-import java.util.regex.*;
-import java.io.*;
-import java.rmi.RemoteException;
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Class for managing the RemoteMonitoredVm instances on a remote system.
- * <p>
- * This class is responsible for the mechanism that detects the active
- * HotSpot Java Virtual Machines on the remote host and possibly for a
- * specific user. The ability to detect all possible HotSpot Java Virtual
- * Machines on the remote host may be limited by the permissions of the
- * principal running the RMI server application on the remote host.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteVmManager {
-
- private RemoteHost remoteHost;
- private String user;
-
- /**
- * Creates a RemoteVmManager instance for the remote system.
- * <p>
- * Manages RemoteMonitordVm instances for which the principal
- * running the remote server has appropriate permissions.
- *
- * @param remoteHost the remote proxy object to the RMI server on
- * the remote system.
- */
- public RemoteVmManager(RemoteHost remoteHost) {
- this(remoteHost, null);
- }
-
- /**
- * Creates a RemoteVmManager instance for the given user.
- * <p>
- * Manages RemoteMonitoredVm instances for all remote Java Virtual
- * machines owned by the specified user on the remote system. The
- * RMI server on the remote system must have the appropriate permissions
- * to access the named users Java Virtual Machines.
- *
- * @param remoteHost the remote proxy object to the RMI server on
- * the remote system.
- * @param user the name of the user
- */
- public RemoteVmManager(RemoteHost remoteHost, String user) {
- this.user = user;
- this.remoteHost = remoteHost;
- }
-
- /**
- * Return the current set of monitorable Java Virtual Machines.
- * <p>
- * The set returned by this method depends on the user name passed
- * to the constructor. If no user name was specified, then this
- * method will return all candidate JVMs on the system. Otherwise,
- * only the JVMs for the given user will be returned. This assumes
- * that the RMI server process has the appropriate permissions to
- * access the target set of JVMs.
- *
- * @return Set - the Set of monitorable Java Virtual Machines
- */
- public Set<Integer> activeVms() throws MonitorException {
- int[] active = null;
-
- try {
- active = remoteHost.activeVms();
-
- } catch (RemoteException e) {
- throw new MonitorException("Error communicating with remote host: "
- + e.getMessage(), e);
- }
-
- Set<Integer> activeSet = new HashSet<Integer>(active.length);
-
- for (int i = 0; i < active.length; i++) {
- activeSet.add(active[i]);
- }
-
- return activeSet;
- }
-}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/package.html Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-<!doctype html public "-//IETF//DTD HTML/EN">
-<html>
-<head>
-<!--
-
-
- Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- 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.
-
--->
-</head>
-<body bgcolor="white">
-<p>
-Provides the implementation classes for the <em>rmi:</em> protocol for
-the HotSpot PerfData instrumentation buffer monitoring implementation.
-</p>
-<p>
-The <em>rmi:</em> protocol is the default protocol for the PerfData
-implementation when a hostname is specified as part of a HostIdentifier
-or VMIdentifier. It communicates with an RMI server on the remote machine
-that provides functions to get a list of available Java Virtual Machines
-and to acquire a copy of a Java Virtual Machine's instrumentation buffer.
-The RMI server may or may not use the PerfData implementation on the
-remote host to acquire this information. The <em>jstatd</em> server
-provides a PerfData implementation of the RMI server.
-</body>
-</html>
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/Jstatd.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.tools.jstatd;
-
-import java.rmi.*;
-import java.rmi.server.*;
-import java.rmi.registry.Registry;
-import java.rmi.registry.LocateRegistry;
-import java.net.MalformedURLException;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Application providing remote access to the jvmstat instrumentation
- * exported by local Java Virtual Machine processes. Remote access is
- * provided through an RMI interface.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class Jstatd {
-
- private static Registry registry;
- private static int port = -1;
- private static boolean startRegistry = true;
-
- private static void printUsage() {
- System.err.println("usage: jstatd [-nr] [-p port] [-n rminame]");
- }
-
- static void bind(String name, RemoteHostImpl remoteHost)
- throws RemoteException, MalformedURLException, Exception {
-
- try {
- Naming.rebind(name, remoteHost);
- } catch (java.rmi.ConnectException e) {
- /*
- * either the registry is not running or we cannot contact it.
- * start an internal registry if requested.
- */
- if (startRegistry && registry == null) {
- int localport = (port < 0) ? Registry.REGISTRY_PORT : port;
- registry = LocateRegistry.createRegistry(localport);
- bind(name, remoteHost);
- } else {
- throw e;
- }
- }
- }
-
- @SuppressWarnings("deprecation") // Use of RMISecurityManager
- public static void main(String[] args) {
- String rminame = null;
- int argc = 0;
-
- for ( ; (argc < args.length) && (args[argc].startsWith("-")); argc++) {
- String arg = args[argc];
-
- if (arg.compareTo("-nr") == 0) {
- startRegistry = false;
- } else if (arg.startsWith("-p")) {
- if (arg.compareTo("-p") != 0) {
- port = Integer.parseInt(arg.substring(2));
- } else {
- argc++;
- if (argc >= args.length) {
- printUsage();
- System.exit(1);
- }
- port = Integer.parseInt(args[argc]);
- }
- } else if (arg.startsWith("-n")) {
- if (arg.compareTo("-n") != 0) {
- rminame = arg.substring(2);
- } else {
- argc++;
- if (argc >= args.length) {
- printUsage();
- System.exit(1);
- }
- rminame = args[argc];
- }
- } else {
- printUsage();
- System.exit(1);
- }
- }
-
- if (argc < args.length) {
- printUsage();
- System.exit(1);
- }
-
- if (System.getSecurityManager() == null) {
- System.setSecurityManager(new RMISecurityManager());
- }
-
- StringBuilder name = new StringBuilder();
-
- if (port >= 0) {
- name.append("//:").append(port);
- }
-
- if (rminame == null) {
- rminame = "JStatRemoteHost";
- }
-
- name.append("/").append(rminame);
-
- try {
- // use 1.5.0 dynamically generated subs.
- System.setProperty("java.rmi.server.ignoreSubClasses", "true");
- RemoteHostImpl remoteHost = new RemoteHostImpl();
- RemoteHost stub = (RemoteHost) UnicastRemoteObject.exportObject(
- remoteHost, 0);
- bind(name.toString(), remoteHost);
- System.out.println("jstatd started (bound to " + name.toString() + ")");
- System.out.flush();
- } catch (MalformedURLException e) {
- if (rminame != null) {
- System.out.println("Bad RMI server name: " + rminame);
- } else {
- System.out.println("Bad RMI URL: " + name);
- }
- e.printStackTrace(System.out);
- System.exit(1);
- } catch (java.rmi.ConnectException e) {
- // could not attach to or create a registry
- System.out.println("Could not contact RMI registry");
- e.printStackTrace(System.out);
- System.exit(1);
- } catch (RemoteException e) {
- System.out.println("Could not bind " + name + " to RMI Registry");
- e.printStackTrace(System.out);
- System.exit(1);
- } catch (Exception e) {
- System.out.println("Could not create remote object");
- e.printStackTrace(System.out);
- System.exit(1);
- }
- }
-}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteHostImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.tools.jstatd;
-
-import java.util.*;
-import java.nio.*;
-import java.io.*;
-import java.net.*;
-import java.rmi.*;
-import java.rmi.server.*;
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Concrete implementation of the RemoteHost interface for the HotSpot
- * PerfData <em>rmi:</em> protocol.
- * <p>
- * This class provides remote access to the instrumentation exported
- * by HotSpot Java Virtual Machines through the PerfData shared memory
- * interface.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteHostImpl implements RemoteHost, HostListener {
-
- private MonitoredHost monitoredHost;
- private Set<Integer> activeVms;
-
- public RemoteHostImpl() throws MonitorException {
- try {
- monitoredHost = MonitoredHost.getMonitoredHost("localhost");
- } catch (URISyntaxException e) { }
-
- activeVms = monitoredHost.activeVms();
- monitoredHost.addHostListener(this);
- }
-
- public RemoteVm attachVm(int lvmid, String mode)
- throws RemoteException, MonitorException {
- Integer v = lvmid;
- RemoteVm stub = null;
- StringBuilder sb = new StringBuilder();
-
- sb.append("local://").append(lvmid).append("@localhost");
- if (mode != null) {
- sb.append("?mode=").append(mode);
- }
-
- String vmidStr = sb.toString();
-
- try {
- VmIdentifier vmid = new VmIdentifier(vmidStr);
- MonitoredVm mvm = monitoredHost.getMonitoredVm(vmid);
- RemoteVmImpl rvm = new RemoteVmImpl((BufferedMonitoredVm)mvm);
- stub = (RemoteVm) UnicastRemoteObject.exportObject(rvm, 0);
- }
- catch (URISyntaxException e) {
- throw new RuntimeException("Malformed VmIdentifier URI: "
- + vmidStr, e);
- }
- return stub;
- }
-
- public void detachVm(RemoteVm rvm) throws RemoteException {
- rvm.detach();
- }
-
- public int[] activeVms() throws MonitorException {
- Object[] vms = null;
- int[] vmids = null;
-
- vms = monitoredHost.activeVms().toArray();
- vmids = new int[vms.length];
-
- for (int i = 0; i < vmids.length; i++) {
- vmids[i] = ((Integer)vms[i]).intValue();
- }
- return vmids;
- }
-
- public void vmStatusChanged(VmStatusChangeEvent ev) {
- synchronized(this.activeVms) {
- activeVms.retainAll(ev.getActive());
- }
- }
-
- public void disconnected(HostEvent ev) {
- // we only monitor the local host, so this event shouldn't occur.
- }
-}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteVmImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.tools.jstatd;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Concrete implementation of the RemoteVm interface for the HotSpot PerfData
- * shared memory implementation of the jvmstat monitoring APIs. This class
- * providing remote access to the instrumentation exported by a local HotSpot
- * Java Virtual Machine. The instrumentation buffer is shipped in whole to
- * the remote machine, which is responsible for parsing and provide access
- * to the contained data.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteVmImpl implements RemoteVm {
-
- private BufferedMonitoredVm mvm;
-
- RemoteVmImpl(BufferedMonitoredVm mvm) {
- this.mvm = mvm;
- }
-
- public byte[] getBytes() {
- return mvm.getBytes();
- }
-
- public int getCapacity() {
- return mvm.getCapacity();
- }
-
- public void detach() {
- mvm.detach();
- }
-
- public int getLocalVmId() {
- return mvm.getVmIdentifier().getLocalVmId();
- }
-}
--- a/jdk/src/jdk.jvmstat/share/classes/module-info.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/jdk.jvmstat/share/classes/module-info.java Thu Apr 28 23:08:17 2016 -0700
@@ -28,12 +28,12 @@
jdk.attach,
jdk.jcmd,
jdk.jconsole,
- jdk.jvmstat.rmi;
+ jdk.jstatd;
exports sun.jvmstat.monitor.event to
jdk.jcmd,
- jdk.jvmstat.rmi;
+ jdk.jstatd;
exports sun.jvmstat.perfdata.monitor to
- jdk.jvmstat.rmi;
+ jdk.jstatd;
uses sun.jvmstat.monitor.MonitoredHostService;
provides sun.jvmstat.monitor.MonitoredHostService with sun.jvmstat.perfdata.monitor.protocol.file.MonitoredHostFileService;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/share/classes/jdk/net/ExtendedSocketOptions.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.net;
+
+import java.io.FileDescriptor;
+import java.net.SocketException;
+import java.net.SocketOption;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.Set;
+import jdk.internal.misc.JavaIOFileDescriptorAccess;
+import jdk.internal.misc.SharedSecrets;
+
+/**
+ * Defines extended socket options, beyond those defined in
+ * {@link java.net.StandardSocketOptions}. These options may be platform
+ * specific.
+ *
+ * @since 1.8
+ */
+public final class ExtendedSocketOptions {
+
+ private static class ExtSocketOption<T> implements SocketOption<T> {
+ private final String name;
+ private final Class<T> type;
+ ExtSocketOption(String name, Class<T> type) {
+ this.name = name;
+ this.type = type;
+ }
+ @Override public String name() { return name; }
+ @Override public Class<T> type() { return type; }
+ @Override public String toString() { return name; }
+ }
+
+ private ExtendedSocketOptions() { }
+
+ /**
+ * Service level properties. When a security manager is installed,
+ * setting or getting this option requires a {@link NetworkPermission}
+ * {@code ("setOption.SO_FLOW_SLA")} or {@code "getOption.SO_FLOW_SLA"}
+ * respectively.
+ */
+ public static final SocketOption<SocketFlow> SO_FLOW_SLA = new
+ ExtSocketOption<SocketFlow>("SO_FLOW_SLA", SocketFlow.class);
+
+
+ private static final PlatformSocketOptions platformSocketOptions =
+ PlatformSocketOptions.get();
+
+ private static final boolean flowSupported =
+ platformSocketOptions.flowSupported();
+
+ private static final Set<SocketOption<?>> extendedOptions = options();
+
+ static Set<SocketOption<?>> options() {
+ if (flowSupported)
+ return Set.of(SO_FLOW_SLA);
+ else
+ return Collections.<SocketOption<?>>emptySet();
+ }
+
+ static {
+ // Registers the extended socket options with the base module.
+ sun.net.ext.ExtendedSocketOptions.register(
+ new sun.net.ext.ExtendedSocketOptions(extendedOptions) {
+
+ @Override
+ public void setOption(FileDescriptor fd,
+ SocketOption<?> option,
+ Object value)
+ throws SocketException
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new NetworkPermission("setOption." + option.name()));
+
+ if (fd == null || !fd.valid())
+ throw new SocketException("socket closed");
+
+ if (option == SO_FLOW_SLA) {
+ assert flowSupported;
+ SocketFlow flow = checkValueType(value, option.type());
+ setFlowOption(fd, flow);
+ } else {
+ throw new InternalError("Unexpected option " + option);
+ }
+ }
+
+ @Override
+ public Object getOption(FileDescriptor fd,
+ SocketOption<?> option)
+ throws SocketException
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new NetworkPermission("getOption." + option.name()));
+
+ if (fd == null || !fd.valid())
+ throw new SocketException("socket closed");
+
+ if (option == SO_FLOW_SLA) {
+ assert flowSupported;
+ SocketFlow flow = SocketFlow.create();
+ getFlowOption(fd, flow);
+ return flow;
+ } else {
+ throw new InternalError("Unexpected option " + option);
+ }
+ }
+ });
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> T checkValueType(Object value, Class<?> type) {
+ if (!type.isAssignableFrom(value.getClass())) {
+ String s = "Found: " + value.getClass() + ", Expected: " + type;
+ throw new IllegalArgumentException(s);
+ }
+ return (T) value;
+ }
+
+ private static final JavaIOFileDescriptorAccess fdAccess =
+ SharedSecrets.getJavaIOFileDescriptorAccess();
+
+ private static void setFlowOption(FileDescriptor fd, SocketFlow f)
+ throws SocketException
+ {
+ int status = platformSocketOptions.setFlowOption(fdAccess.get(fd),
+ f.priority(),
+ f.bandwidth());
+ f.status(status); // augment the given flow with the status
+ }
+
+ private static void getFlowOption(FileDescriptor fd, SocketFlow f)
+ throws SocketException
+ {
+ int status = platformSocketOptions.getFlowOption(fdAccess.get(fd), f);
+ f.status(status); // augment the given flow with the status
+ }
+
+ static class PlatformSocketOptions {
+
+ protected PlatformSocketOptions() {}
+
+ @SuppressWarnings("unchecked")
+ private static PlatformSocketOptions newInstance(String cn) {
+ Class<PlatformSocketOptions> c;
+ try {
+ c = (Class<PlatformSocketOptions>)Class.forName(cn);
+ return c.getConstructor(new Class<?>[] { }).newInstance();
+ } catch (ReflectiveOperationException x) {
+ throw new AssertionError(x);
+ }
+ }
+
+ private static PlatformSocketOptions create() {
+ String osname = AccessController.doPrivileged(
+ new PrivilegedAction<String>() {
+ public String run() {
+ return System.getProperty("os.name");
+ }
+ });
+ if ("SunOS".equals(osname))
+ return newInstance("jdk.net.SolarisSocketOptions");
+ return new PlatformSocketOptions();
+ }
+
+ private static final PlatformSocketOptions instance = create();
+
+ static PlatformSocketOptions get() {
+ return instance;
+ }
+
+ int setFlowOption(int fd, int priority, long bandwidth)
+ throws SocketException
+ {
+ throw new UnsupportedOperationException("unsupported socket option");
+ }
+
+ int getFlowOption(int fd, SocketFlow f) throws SocketException {
+ throw new UnsupportedOperationException("unsupported socket option");
+ }
+
+ boolean flowSupported() {
+ return false;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/share/classes/jdk/net/NetworkPermission.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.net;
+
+import java.security.BasicPermission;
+
+/**
+ * Represents permission to access the extended networking capabilities
+ * defined in the jdk.net package. These permissions contain a target
+ * name, but no actions list. Callers either possess the permission or not.
+ * <p>
+ * The following targets are defined:
+ *
+ * <table border=1 cellpadding=5 summary="permission target name,
+ * what the target allows,and associated risks">
+ * <tr>
+ * <th>Permission Target Name</th>
+ * <th>What the Permission Allows</th>
+ * <th>Risks of Allowing this Permission</th>
+ * </tr>
+ * <tr>
+ * <td>setOption.SO_FLOW_SLA</td>
+ * <td>set the {@link ExtendedSocketOptions#SO_FLOW_SLA SO_FLOW_SLA} option
+ * on any socket that supports it</td>
+ * <td>allows caller to set a higher priority or bandwidth allocation
+ * to sockets it creates, than they might otherwise be allowed.</td>
+ * </tr>
+ * <tr>
+ * <td>getOption.SO_FLOW_SLA</td>
+ * <td>retrieve the {@link ExtendedSocketOptions#SO_FLOW_SLA SO_FLOW_SLA}
+ * setting from any socket that supports the option</td>
+ * <td>allows caller access to SLA information that it might not
+ * otherwise have</td>
+ * </tr></table>
+ *
+ * @see jdk.net.ExtendedSocketOptions
+ *
+ * @since 1.8
+ */
+
+public final class NetworkPermission extends BasicPermission {
+
+ private static final long serialVersionUID = -2012939586906722291L;
+
+ /**
+ * Creates a NetworkPermission with the given target name.
+ *
+ * @param name the permission target name
+ * @throws NullPointerException if {@code name} is {@code null}.
+ * @throws IllegalArgumentException if {@code name} is empty.
+ */
+ public NetworkPermission(String name)
+ {
+ super(name);
+ }
+
+ /**
+ * Creates a NetworkPermission with the given target name.
+ *
+ * @param name the permission target name
+ * @param actions should be {@code null}. Is ignored if not.
+ * @throws NullPointerException if {@code name} is {@code null}.
+ * @throws IllegalArgumentException if {@code name} is empty.
+ */
+ public NetworkPermission(String name, String actions)
+ {
+ super(name, actions);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/share/classes/jdk/net/SocketFlow.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.net;
+
+import java.lang.annotation.Native;
+
+/**
+ * Represents the service level properties for the platform specific socket
+ * option {@link ExtendedSocketOptions#SO_FLOW_SLA}.
+ * <p>
+ * The priority and bandwidth parameters must be set before
+ * setting the socket option.
+ * <p>
+ * When the {@code SO_FLOW_SLA} option is set then it may not take effect
+ * immediately. If the value of the socket option is obtained with
+ * {@code getOption()} then the status may be returned as {@code INPROGRESS}
+ * until it takes effect. The priority and bandwidth values are only valid when
+ * the status is returned as OK.
+ * <p>
+ * When a security manager is installed, a {@link NetworkPermission}
+ * is required to set or get this option.
+ *
+ * @since 1.8
+ */
+public class SocketFlow {
+
+ @Native public static final int UNSET = -1;
+ @Native public static final int NORMAL_PRIORITY = 1;
+ @Native public static final int HIGH_PRIORITY = 2;
+
+ @Native private static final int NO_STATUS_VALUE = 0;
+ @Native private static final int OK_VALUE = 1;
+ @Native private static final int NO_PERMISSION_VALUE = 2;
+ @Native private static final int NOT_CONNECTED_VALUE = 3;
+ @Native private static final int NOT_SUPPORTED_VALUE = 4;
+ @Native private static final int ALREADY_CREATED_VALUE = 5;
+ @Native private static final int IN_PROGRESS_VALUE = 6;
+ @Native private static final int OTHER_VALUE = 7;
+
+ /**
+ * Enumeration of the return values from the SO_FLOW_SLA
+ * socket option. Both setting and getting the option return
+ * one of these statuses, which reflect the state of socket's
+ * flow.
+ *
+ * @since 1.8
+ */
+ public enum Status {
+ /**
+ * Set or get socket option has not been called yet. Status
+ * values can only be retrieved after calling set or get.
+ */
+ NO_STATUS(NO_STATUS_VALUE),
+ /**
+ * Flow successfully created.
+ */
+ OK(OK_VALUE),
+ /**
+ * Caller has no permission to create flow.
+ */
+ NO_PERMISSION(NO_PERMISSION_VALUE),
+ /**
+ * Flow can not be created because socket is not connected.
+ */
+ NOT_CONNECTED(NOT_CONNECTED_VALUE),
+ /**
+ * Flow creation not supported for this socket.
+ */
+ NOT_SUPPORTED(NOT_SUPPORTED_VALUE),
+ /**
+ * A flow already exists with identical attributes.
+ */
+ ALREADY_CREATED(ALREADY_CREATED_VALUE),
+ /**
+ * A flow is being created.
+ */
+ IN_PROGRESS(IN_PROGRESS_VALUE),
+ /**
+ * Some other unspecified error.
+ */
+ OTHER(OTHER_VALUE);
+
+ private final int value;
+ Status(int value) { this.value = value; }
+
+ static Status from(int value) {
+ if (value == NO_STATUS.value) return NO_STATUS;
+ else if (value == OK.value) return OK;
+ else if (value == NO_PERMISSION.value) return NO_PERMISSION;
+ else if (value == NOT_CONNECTED.value) return NOT_CONNECTED;
+ else if (value == NOT_SUPPORTED.value) return NOT_SUPPORTED;
+ else if (value == ALREADY_CREATED.value) return ALREADY_CREATED;
+ else if (value == IN_PROGRESS.value) return IN_PROGRESS;
+ else if (value == OTHER.value) return OTHER;
+ else throw new InternalError("Unknown value: " + value);
+ }
+ }
+
+ private int priority = NORMAL_PRIORITY;
+ private long bandwidth = UNSET;
+ private Status status = Status.NO_STATUS;
+
+ /**
+ * Creates a new SocketFlow that can be used to set the SO_FLOW_SLA
+ * socket option and create a socket flow.
+ */
+ public static SocketFlow create() {
+ return new SocketFlow();
+ }
+
+ private SocketFlow() { }
+
+ /**
+ * Sets this SocketFlow's priority. Must be either NORMAL_PRIORITY
+ * HIGH_PRIORITY. If not set, a flow's priority is normal.
+ *
+ * @throws IllegalArgumentException if priority is not NORMAL_PRIORITY or
+ * HIGH_PRIORITY.
+ */
+ public SocketFlow priority(int priority) {
+ if (priority != NORMAL_PRIORITY && priority != HIGH_PRIORITY)
+ throw new IllegalArgumentException("invalid priority :" + priority);
+ this.priority = priority;
+ return this;
+ }
+
+ /**
+ * Sets this SocketFlow's bandwidth. Must be greater than or equal to zero.
+ * A value of zero drops all packets for the socket.
+ *
+ * @throws IllegalArgumentException if bandwidth is less than zero.
+ */
+ public SocketFlow bandwidth(long bandwidth) {
+ if (bandwidth < 0)
+ throw new IllegalArgumentException("invalid bandwidth: " + bandwidth);
+ this.bandwidth = bandwidth;
+ return this;
+ }
+
+ /**
+ * Returns this SocketFlow's priority.
+ */
+ public int priority() {
+ return priority;
+ }
+
+ /**
+ * Returns this SocketFlow's bandwidth.
+ *
+ * @return this SocketFlow's bandwidth, or {@code -1} if status is not OK.
+ */
+ public long bandwidth() {
+ return bandwidth;
+ }
+
+ /**
+ * Returns the Status value of this SocketFlow. NO_STATUS is returned
+ * if the object was not used in a call to set or get the option.
+ */
+ public Status status() {
+ return status;
+ }
+
+ void status(int status) {
+ this.status = Status.from(status);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder(super.toString());
+ sb.append(" [ priority=").append(priority())
+ .append(", bandwidth=").append(bandwidth())
+ .append(", status=").append(status())
+ .append(" ]");
+ return sb.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/share/classes/jdk/net/Sockets.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.net;
+
+import java.net.*;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import jdk.net.ExtendedSocketOptions.PlatformSocketOptions;
+
+/**
+ * Defines static methods to set and get socket options defined by the
+ * {@link java.net.SocketOption} interface. All of the standard options defined
+ * by {@link java.net.Socket}, {@link java.net.ServerSocket}, and
+ * {@link java.net.DatagramSocket} can be set this way, as well as additional
+ * or platform specific options supported by each socket type.
+ * <p>
+ * The {@link #supportedOptions(Class)} method can be called to determine
+ * the complete set of options available (per socket type) on the
+ * current system.
+ * <p>
+ * When a security manager is installed, some non-standard socket options
+ * may require a security permission before being set or get.
+ * The details are specified in {@link ExtendedSocketOptions}. No permission
+ * is required for {@link java.net.StandardSocketOptions}.
+ *
+ * @see java.nio.channels.NetworkChannel
+ */
+public class Sockets {
+
+ private static final Map<Class<?>,Set<SocketOption<?>>>
+ options = optionSets();
+
+ private Sockets() {}
+
+ /**
+ * Sets the value of a socket option on a {@link java.net.Socket}
+ *
+ * @param s the socket
+ * @param name The socket option
+ * @param value The value of the socket option. May be null for some
+ * options.
+ *
+ * @throws UnsupportedOperationException if the socket does not support
+ * the option.
+ *
+ * @throws IllegalArgumentException if the value is not valid for
+ * the option.
+ *
+ * @throws IOException if an I/O error occurs, or socket is closed.
+ *
+ * @throws SecurityException if a security manager is set and the
+ * caller does not have any required permission.
+ *
+ * @throws NullPointerException if name is null
+ *
+ * @see java.net.StandardSocketOptions
+ */
+ public static <T> void setOption(Socket s, SocketOption<T> name, T value) throws IOException
+ {
+ s.setOption(name, value);
+ }
+
+ /**
+ * Returns the value of a socket option from a {@link java.net.Socket}
+ *
+ * @param s the socket
+ * @param name The socket option
+ *
+ * @return The value of the socket option.
+ *
+ * @throws UnsupportedOperationException if the socket does not support
+ * the option.
+ *
+ * @throws IOException if an I/O error occurs
+ *
+ * @throws SecurityException if a security manager is set and the
+ * caller does not have any required permission.
+ *
+ * @throws NullPointerException if name is null
+ *
+ * @see java.net.StandardSocketOptions
+ */
+ public static <T> T getOption(Socket s, SocketOption<T> name) throws IOException
+ {
+ return s.getOption(name);
+ }
+
+ /**
+ * Sets the value of a socket option on a {@link java.net.ServerSocket}
+ *
+ * @param s the socket
+ * @param name The socket option
+ * @param value The value of the socket option.
+ *
+ * @throws UnsupportedOperationException if the socket does not support
+ * the option.
+ *
+ * @throws IllegalArgumentException if the value is not valid for
+ * the option.
+ *
+ * @throws IOException if an I/O error occurs
+ *
+ * @throws NullPointerException if name is null
+ *
+ * @throws SecurityException if a security manager is set and the
+ * caller does not have any required permission.
+ *
+ * @see java.net.StandardSocketOptions
+ */
+ public static <T> void setOption(ServerSocket s, SocketOption<T> name, T value) throws IOException
+ {
+ s.setOption(name, value);
+ }
+
+ /**
+ * Returns the value of a socket option from a {@link java.net.ServerSocket}
+ *
+ * @param s the socket
+ * @param name The socket option
+ *
+ * @return The value of the socket option.
+ *
+ * @throws UnsupportedOperationException if the socket does not support
+ * the option.
+ *
+ * @throws IOException if an I/O error occurs
+ *
+ * @throws NullPointerException if name is null
+ *
+ * @throws SecurityException if a security manager is set and the
+ * caller does not have any required permission.
+ *
+ * @see java.net.StandardSocketOptions
+ */
+ public static <T> T getOption(ServerSocket s, SocketOption<T> name) throws IOException
+ {
+ return s.getOption(name);
+ }
+
+ /**
+ * Sets the value of a socket option on a {@link java.net.DatagramSocket}
+ * or {@link java.net.MulticastSocket}
+ *
+ * @param s the socket
+ * @param name The socket option
+ * @param value The value of the socket option.
+ *
+ * @throws UnsupportedOperationException if the socket does not support
+ * the option.
+ *
+ * @throws IllegalArgumentException if the value is not valid for
+ * the option.
+ *
+ * @throws IOException if an I/O error occurs
+ *
+ * @throws NullPointerException if name is null
+ *
+ * @throws SecurityException if a security manager is set and the
+ * caller does not have any required permission.
+ *
+ * @see java.net.StandardSocketOptions
+ */
+ public static <T> void setOption(DatagramSocket s, SocketOption<T> name, T value) throws IOException
+ {
+ s.setOption(name, value);
+ }
+
+ /**
+ * Returns the value of a socket option from a
+ * {@link java.net.DatagramSocket} or {@link java.net.MulticastSocket}
+ *
+ * @param s the socket
+ * @param name The socket option
+ *
+ * @return The value of the socket option.
+ *
+ * @throws UnsupportedOperationException if the socket does not support
+ * the option.
+ *
+ * @throws IOException if an I/O error occurs
+ *
+ * @throws NullPointerException if name is null
+ *
+ * @throws SecurityException if a security manager is set and the
+ * caller does not have any required permission.
+ *
+ * @see java.net.StandardSocketOptions
+ */
+ public static <T> T getOption(DatagramSocket s, SocketOption<T> name) throws IOException
+ {
+ return s.getOption(name);
+ }
+
+ /**
+ * Returns a set of {@link java.net.SocketOption}s supported by the
+ * given socket type. This set may include standard options and also
+ * non standard extended options.
+ *
+ * @param socketType the type of java.net socket
+ *
+ * @throws IllegalArgumentException if socketType is not a valid
+ * socket type from the java.net package.
+ */
+ public static Set<SocketOption<?>> supportedOptions(Class<?> socketType) {
+ Set<SocketOption<?>> set = options.get(socketType);
+ if (set == null) {
+ throw new IllegalArgumentException("unknown socket type");
+ }
+ return set;
+ }
+
+ private static void checkValueType(Object value, Class<?> type) {
+ if (!type.isAssignableFrom(value.getClass())) {
+ String s = "Found: " + value.getClass().toString() + " Expected: "
+ + type.toString();
+ throw new IllegalArgumentException(s);
+ }
+ }
+
+ private static volatile boolean checkedReusePort;
+ private static volatile boolean isReusePortAvailable;
+
+ /**
+ * Tells whether SO_REUSEPORT is supported.
+ */
+ static boolean isReusePortAvailable() {
+ if (!checkedReusePort) {
+ Set<SocketOption<?>> s = new Socket().supportedOptions();
+ isReusePortAvailable = s.contains(StandardSocketOptions.SO_REUSEPORT);
+ checkedReusePort = true;
+ }
+ return isReusePortAvailable;
+ }
+
+ private static Map<Class<?>,Set<SocketOption<?>>> optionSets() {
+ Map<Class<?>,Set<SocketOption<?>>> options = new HashMap<>();
+ boolean flowsupported = PlatformSocketOptions.get().flowSupported();
+ boolean reuseportsupported = isReusePortAvailable();
+ // Socket
+
+ Set<SocketOption<?>> set = new HashSet<>();
+ set.add(StandardSocketOptions.SO_KEEPALIVE);
+ set.add(StandardSocketOptions.SO_SNDBUF);
+ set.add(StandardSocketOptions.SO_RCVBUF);
+ set.add(StandardSocketOptions.SO_REUSEADDR);
+ if (reuseportsupported) {
+ set.add(StandardSocketOptions.SO_REUSEPORT);
+ }
+ set.add(StandardSocketOptions.SO_LINGER);
+ set.add(StandardSocketOptions.IP_TOS);
+ set.add(StandardSocketOptions.TCP_NODELAY);
+ if (flowsupported) {
+ set.add(ExtendedSocketOptions.SO_FLOW_SLA);
+ }
+ set = Collections.unmodifiableSet(set);
+ options.put(Socket.class, set);
+
+ // ServerSocket
+
+ set = new HashSet<>();
+ set.add(StandardSocketOptions.SO_RCVBUF);
+ set.add(StandardSocketOptions.SO_REUSEADDR);
+ if (reuseportsupported) {
+ set.add(StandardSocketOptions.SO_REUSEPORT);
+ }
+ set.add(StandardSocketOptions.IP_TOS);
+ set = Collections.unmodifiableSet(set);
+ options.put(ServerSocket.class, set);
+
+ // DatagramSocket
+
+ set = new HashSet<>();
+ set.add(StandardSocketOptions.SO_SNDBUF);
+ set.add(StandardSocketOptions.SO_RCVBUF);
+ set.add(StandardSocketOptions.SO_REUSEADDR);
+ if (reuseportsupported) {
+ set.add(StandardSocketOptions.SO_REUSEPORT);
+ }
+ set.add(StandardSocketOptions.IP_TOS);
+ if (flowsupported) {
+ set.add(ExtendedSocketOptions.SO_FLOW_SLA);
+ }
+ set = Collections.unmodifiableSet(set);
+ options.put(DatagramSocket.class, set);
+
+ // MulticastSocket
+
+ set = new HashSet<>();
+ set.add(StandardSocketOptions.SO_SNDBUF);
+ set.add(StandardSocketOptions.SO_RCVBUF);
+ set.add(StandardSocketOptions.SO_REUSEADDR);
+ if (reuseportsupported) {
+ set.add(StandardSocketOptions.SO_REUSEPORT);
+ }
+ set.add(StandardSocketOptions.IP_TOS);
+ set.add(StandardSocketOptions.IP_MULTICAST_IF);
+ set.add(StandardSocketOptions.IP_MULTICAST_TTL);
+ set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
+ if (flowsupported) {
+ set.add(ExtendedSocketOptions.SO_FLOW_SLA);
+ }
+ set = Collections.unmodifiableSet(set);
+ options.put(MulticastSocket.class, set);
+
+ return Collections.unmodifiableMap(options);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/share/classes/jdk/net/package-info.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.
+ */
+
+/**
+ * Platform specific socket options for the {@code java.net} and {@code java.nio.channels}
+ * socket classes.
+ *
+ * @since 1.8
+ */
+
+package jdk.net;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/share/classes/module-info.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+module jdk.net {
+ exports jdk.net;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/solaris/classes/jdk/net/SolarisSocketOptions.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.net;
+
+import java.net.SocketException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import jdk.net.ExtendedSocketOptions.PlatformSocketOptions;
+
+class SolarisSocketOptions extends PlatformSocketOptions {
+
+ public SolarisSocketOptions() { }
+
+ @Override native int setFlowOption(int fd, int priority, long bandwidth)
+ throws SocketException;
+
+ @Override native int getFlowOption(int fd, SocketFlow f)
+ throws SocketException;
+
+ @Override native boolean flowSupported();
+
+ private static native void init();
+
+ static {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ System.loadLibrary("extnet");
+ return null;
+ }
+ });
+ init();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/solaris/native/libextnet/SolarisSocketOptions.c Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.
+ */
+
+
+#include "SolarisSocketOptions.h"
+
+static jfieldID sf_priority;
+static jfieldID sf_bandwidth;
+
+static int initialized = 0;
+
+/*
+ * Class: jdk_net_SolarisSocketOptions
+ * Method: init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_jdk_net_SolarisSocketOptions_init
+ (JNIEnv *env, jclass unused)
+{
+ if (!initialized) {
+ jclass c = (*env)->FindClass(env, "jdk/net/SocketFlow");
+ CHECK_NULL(c);
+ sf_priority = (*env)->GetFieldID(env, c, "priority", "I");
+ CHECK_NULL(sf_priority);
+ sf_bandwidth = (*env)->GetFieldID(env, c, "bandwidth", "J");
+ CHECK_NULL(sf_bandwidth);
+ initialized = 1;
+ }
+}
+
+/** Return the Status value. */
+static jint toStatus(int errval)
+{
+ switch (errval) {
+ case 0: return jdk_net_SocketFlow_OK_VALUE;
+ case EPERM: return jdk_net_SocketFlow_NO_PERMISSION_VALUE;
+ case ENOTCONN: return jdk_net_SocketFlow_NOT_CONNECTED_VALUE;
+ case EOPNOTSUPP: return jdk_net_SocketFlow_NOT_SUPPORTED_VALUE;
+ case EALREADY: return jdk_net_SocketFlow_ALREADY_CREATED_VALUE;
+ case EINPROGRESS: return jdk_net_SocketFlow_IN_PROGRESS_VALUE;
+ default: return jdk_net_SocketFlow_OTHER_VALUE;
+ }
+}
+
+void throwByNameWithLastError
+ (JNIEnv *env, const char *name, const char *defaultDetail)
+{
+ char defaultMsg[255];
+ sprintf(defaultMsg, "errno: %d, %s", errno, defaultDetail);
+ JNU_ThrowByNameWithLastError(env, name, defaultMsg);
+}
+
+/*
+ * Class: jdk_net_SolarisSocketOptions
+ * Method: setFlowOption0
+ * Signature: (IIJ)I
+ */
+JNIEXPORT jint JNICALL Java_jdk_net_SolarisSocketOptions_setFlowOption
+ (JNIEnv *env, jobject unused, jint fd, jint priority, jlong bandwidth)
+{
+ int rv;
+ sock_flow_props_t props;
+ memset(&props, 0, sizeof(props));
+ props.sfp_version = SOCK_FLOW_PROP_VERSION1;
+
+ if (priority != jdk_net_SocketFlow_UNSET) {
+ props.sfp_mask |= SFP_PRIORITY;
+ props.sfp_priority = priority;
+ }
+ if (bandwidth > jdk_net_SocketFlow_UNSET) {
+ props.sfp_mask |= SFP_MAXBW;
+ props.sfp_maxbw = (uint64_t) bandwidth;
+ }
+
+ rv = setsockopt(fd, SOL_SOCKET, SO_FLOW_SLA, &props, sizeof(props));
+
+ if (rv < 0) {
+ if (errno == ENOPROTOOPT) {
+ JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+ "unsupported socket option");
+ } else if (errno == EACCES || errno == EPERM) {
+ JNU_ThrowByName(env, "java/net/SocketException", "Permission denied");
+ } else {
+ throwByNameWithLastError(env, "java/net/SocketException",
+ "set option SO_FLOW_SLA failed");
+ }
+ return 0;
+ }
+ return toStatus(props.sfp_status);
+}
+
+/*
+ * Class: jdk_net_SolarisSocketOptions
+ * Method: getFlowOption0
+ * Signature: (ILjdk/net/SocketFlow;)I
+ */
+JNIEXPORT jint JNICALL Java_jdk_net_SolarisSocketOptions_getFlowOption
+ (JNIEnv *env, jobject unused, jint fd, jobject flow)
+{
+ sock_flow_props_t props;
+ socklen_t sz = sizeof(props);
+
+ int rv = getsockopt(fd, SOL_SOCKET, SO_FLOW_SLA, &props, &sz);
+
+ if (rv < 0) {
+ if (errno == ENOPROTOOPT) {
+ JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+ "unsupported socket option");
+ } else if (errno == EACCES || errno == EPERM) {
+ JNU_ThrowByName(env, "java/net/SocketException", "Permission denied");
+ } else {
+ throwByNameWithLastError(env, "java/net/SocketException",
+ "get option SO_FLOW_SLA failed");
+ }
+ return -1;
+ }
+ /* first check status to see if flow exists */
+ if (props.sfp_status == 0) { /* OK */
+ /* can set the other fields now */
+ if (props.sfp_mask & SFP_PRIORITY) {
+ (*env)->SetIntField(env, flow, sf_priority, props.sfp_priority);
+ }
+ if (props.sfp_mask & SFP_MAXBW) {
+ (*env)->SetLongField(env, flow, sf_bandwidth,
+ (jlong)props.sfp_maxbw);
+ }
+ }
+ return toStatus(props.sfp_status);
+}
+
+JNIEXPORT jboolean JNICALL Java_jdk_net_SolarisSocketOptions_flowSupported
+ (JNIEnv *env, jobject unused)
+{
+ /* Do a simple dummy call, and try to figure out from that */
+ sock_flow_props_t props;
+ int rv, s;
+
+ s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (s < 0) {
+ return JNI_FALSE;
+ }
+ memset(&props, 0, sizeof(props));
+ props.sfp_version = SOCK_FLOW_PROP_VERSION1;
+ props.sfp_mask |= SFP_PRIORITY;
+ props.sfp_priority = SFP_PRIO_NORMAL;
+ rv = setsockopt(s, SOL_SOCKET, SO_FLOW_SLA, &props, sizeof(props));
+ if (rv != 0 && errno == ENOPROTOOPT) {
+ rv = JNI_FALSE;
+ } else {
+ rv = JNI_TRUE;
+ }
+ close(s);
+ return rv;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/solaris/native/libextnet/SolarisSocketOptions.h Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef SOLARIS_SOCKET_OPTIONS_H
+#define SOLARIS_SOCKET_OPTIONS_H
+
+#include <sys/socket.h>
+#include <jni.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "jni_util.h"
+#include "jdk_net_SocketFlow.h"
+#include "SolarisSocketOptions.h"
+#include "jdk_net_SolarisSocketOptions.h"
+
+#ifndef SO_FLOW_SLA
+#define SO_FLOW_SLA 0x1018
+
+#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
+#pragma pack(4)
+#endif
+
+/*
+ * Used with the setsockopt(SO_FLOW_SLA, ...) call to set
+ * per socket service level properties.
+ * When the application uses per-socket API, we will enforce the properties
+ * on both outbound and inbound packets.
+ *
+ * For now, only priority and maxbw are supported in SOCK_FLOW_PROP_VERSION1.
+ */
+typedef struct sock_flow_props_s {
+ int sfp_version;
+ uint32_t sfp_mask;
+ int sfp_priority; /* flow priority */
+ uint64_t sfp_maxbw; /* bandwidth limit in bps */
+ int sfp_status; /* flow create status for getsockopt */
+} sock_flow_props_t;
+
+#define SOCK_FLOW_PROP_VERSION1 1
+
+/* bit mask values for sfp_mask */
+#define SFP_MAXBW 0x00000001 /* Flow Bandwidth Limit */
+#define SFP_PRIORITY 0x00000008 /* Flow priority */
+
+/* possible values for sfp_priority */
+#define SFP_PRIO_NORMAL 1
+#define SFP_PRIO_HIGH 2
+
+#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
+#pragma pack()
+#endif /* _LONG_LONG_ALIGNMENT */
+
+#endif /* SO_FLOW_SLA */
+
+#endif /* SOLARIS_SOCKET_OPTIONS_H */
--- a/jdk/src/jdk.policytool/share/classes/module-info.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/src/jdk.policytool/share/classes/module-info.java Thu Apr 28 23:08:17 2016 -0700
@@ -28,6 +28,7 @@
requires java.logging;
requires java.management;
requires java.sql;
+ requires jdk.net;
requires java.security.jgss;
requires jdk.security.jgss;
}
--- a/jdk/src/jdk.unsupported/share/classes/sun/misc/ManagedLocalsThread.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-/**
- * A thread that has it's thread locals, and inheritable thread
- * locals erased on construction.
- */
-public class ManagedLocalsThread extends Thread {
- private static final jdk.internal.misc.Unsafe UNSAFE;
- private static final long THREAD_LOCALS;
- private static final long INHERITABLE_THREAD_LOCALS;
-
- public ManagedLocalsThread() {
- eraseThreadLocals();
- }
-
- public ManagedLocalsThread(Runnable target) {
- super(target);
- eraseThreadLocals();
- }
-
- public ManagedLocalsThread(String name) {
- super(name);
- eraseThreadLocals();
- }
-
- public ManagedLocalsThread(ThreadGroup group, Runnable target) {
- super(group, target);
- eraseThreadLocals();
- }
-
- public ManagedLocalsThread(Runnable target, String name) {
- super(target, name);
- eraseThreadLocals();
- }
-
- public ManagedLocalsThread(ThreadGroup group, String name) {
- super(group, name);
- eraseThreadLocals();
- }
-
- public ManagedLocalsThread(ThreadGroup group, Runnable target, String name) {
- super(group, target, name);
- eraseThreadLocals();
- }
-
- /**
- * Drops all thread locals (and inherited thread locals).
- */
- public final void eraseThreadLocals() {
- UNSAFE.putObject(this, THREAD_LOCALS, null);
- UNSAFE.putObject(this, INHERITABLE_THREAD_LOCALS, null);
- }
-
- static {
- UNSAFE = jdk.internal.misc.Unsafe.getUnsafe();
- Class<?> t = Thread.class;
- try {
- THREAD_LOCALS = UNSAFE.objectFieldOffset
- (t.getDeclaredField("threadLocals"));
- INHERITABLE_THREAD_LOCALS = UNSAFE.objectFieldOffset
- (t.getDeclaredField("inheritableThreadLocals"));
- } catch (Exception e) {
- throw new Error(e);
- }
- }
-}
-
--- a/jdk/test/java/lang/System/Logger/custom/CustomLoggerTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/System/Logger/custom/CustomLoggerTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -46,6 +46,8 @@
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.util.stream.Stream;
+import java.lang.reflect.Module;
+import java.security.AllPermission;
/**
* @test
@@ -70,6 +72,12 @@
return new AtomicBoolean(false);
}
};
+ static final ThreadLocal<AtomicBoolean> allowAll = new ThreadLocal<AtomicBoolean>() {
+ @Override
+ protected AtomicBoolean initialValue() {
+ return new AtomicBoolean(false);
+ }
+ };
public static class MyBundle extends ResourceBundle {
@@ -241,7 +249,7 @@
}
@Override
- public Logger getLogger(String name, Class<?> caller) {
+ public Logger getLogger(String name, Module caller) {
// We should check the permission to obey the API contract, but
// what happens if we don't?
// This is the main difference compared with what we test in
@@ -251,8 +259,13 @@
sm.checkPermission(SimplePolicy.LOGGERFINDER_PERMISSION);
}
- PrivilegedAction<ClassLoader> pa = () -> caller.getClassLoader();
- ClassLoader callerLoader = AccessController.doPrivileged(pa);
+ final boolean before = allowAll.get().getAndSet(true);
+ final ClassLoader callerLoader;
+ try {
+ callerLoader = caller.getClassLoader();
+ } finally {
+ allowAll.get().set(before);
+ }
if (callerLoader == null) {
return system.computeIfAbsent(name, (n) -> new LoggerImpl(n));
} else {
@@ -267,7 +280,7 @@
static void setSecurityManager() {
if (System.getSecurityManager() == null) {
- Policy.setPolicy(new SimplePolicy(allowControl));
+ Policy.setPolicy(new SimplePolicy(allowControl, allowAll));
System.setSecurityManager(new SecurityManager());
}
}
@@ -284,9 +297,9 @@
BaseLoggerFinder provider =
BaseLoggerFinder.class.cast(LoggerFinder.getLoggerFinder());
BaseLoggerFinder.LoggerImpl appSink =
- BaseLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", CustomLoggerTest.class));
+ BaseLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", CustomLoggerTest.class.getModule()));
BaseLoggerFinder.LoggerImpl sysSink =
- BaseLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class));
+ BaseLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class.getModule()));
Stream.of(args).map(TestCases::valueOf).forEach((testCase) -> {
@@ -695,34 +708,46 @@
static final RuntimePermission LOGGERFINDER_PERMISSION =
new RuntimePermission("loggerFinder");
final Permissions permissions;
+ final Permissions controlPermissions;
final Permissions allPermissions;
final ThreadLocal<AtomicBoolean> allowControl;
- public SimplePolicy(ThreadLocal<AtomicBoolean> allowControl) {
+ final ThreadLocal<AtomicBoolean> allowAll;
+ public SimplePolicy(ThreadLocal<AtomicBoolean> allowControl, ThreadLocal<AtomicBoolean> allowAll) {
this.allowControl = allowControl;
+ this.allowAll = allowAll;
permissions = new Permissions();
// these are used for configuring the test itself...
+ controlPermissions = new Permissions();
+ controlPermissions.add(LOGGERFINDER_PERMISSION);
+
+ // these are used for simulating a doPrivileged call from
+ // a class in the BCL
allPermissions = new Permissions();
- allPermissions.add(LOGGERFINDER_PERMISSION);
+ allPermissions.add(new AllPermission());
+
+ }
+
+ Permissions permissions() {
+ if (allowAll.get().get()) return allPermissions;
+ if (allowControl.get().get()) return controlPermissions;
+ return permissions;
}
@Override
public boolean implies(ProtectionDomain domain, Permission permission) {
- if (allowControl.get().get()) return allPermissions.implies(permission);
- return permissions.implies(permission);
+ return permissions().implies(permission);
}
@Override
public PermissionCollection getPermissions(CodeSource codesource) {
- return new PermissionsBuilder().addAll(allowControl.get().get()
- ? allPermissions : permissions).toPermissions();
+ return new PermissionsBuilder().addAll(permissions()).toPermissions();
}
@Override
public PermissionCollection getPermissions(ProtectionDomain domain) {
- return new PermissionsBuilder().addAll(allowControl.get().get()
- ? allPermissions : permissions).toPermissions();
+ return new PermissionsBuilder().addAll(permissions()).toPermissions();
}
}
}
--- a/jdk/test/java/lang/System/LoggerFinder/BaseLoggerFinderTest/BaseLoggerFinder.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/System/LoggerFinder/BaseLoggerFinderTest/BaseLoggerFinder.java Thu Apr 28 23:08:17 2016 -0700
@@ -25,13 +25,14 @@
import java.security.PrivilegedAction;
import java.lang.System.LoggerFinder;
import java.lang.System.Logger;
+import java.lang.reflect.Module;
public class BaseLoggerFinder extends LoggerFinder implements TestLoggerFinder {
static final RuntimePermission LOGGERFINDER_PERMISSION =
new RuntimePermission("loggerFinder");
@Override
- public Logger getLogger(String name, Class<?> caller) {
+ public Logger getLogger(String name, Module caller) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOGGERFINDER_PERMISSION);
--- a/jdk/test/java/lang/System/LoggerFinder/BaseLoggerFinderTest/BaseLoggerFinderTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/System/LoggerFinder/BaseLoggerFinderTest/BaseLoggerFinderTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -182,8 +182,8 @@
TestLoggerFinder.LoggerImpl appLogger1 = null;
try {
appLogger1 =
- TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", BaseLoggerFinderTest.class));
- loggerDescMap.put(appLogger1, "provider.getLogger(\"foo\", BaseLoggerFinderTest.class)");
+ TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", BaseLoggerFinderTest.class.getModule()));
+ loggerDescMap.put(appLogger1, "provider.getLogger(\"foo\", BaseLoggerFinderTest.class.getModule())");
if (!hasRequiredPermissions) {
throw new RuntimeException("Managed to obtain a logger without permission");
}
@@ -199,8 +199,8 @@
allowControl.get().set(true);
try {
appLogger1 =
- TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", BaseLoggerFinderTest.class));
- loggerDescMap.put(appLogger1, "provider.getLogger(\"foo\", BaseLoggerFinderTest.class)");
+ TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", BaseLoggerFinderTest.class.getModule()));
+ loggerDescMap.put(appLogger1, "provider.getLogger(\"foo\", BaseLoggerFinderTest.class.getModule())");
} finally {
allowControl.get().set(old);
}
@@ -208,8 +208,8 @@
TestLoggerFinder.LoggerImpl sysLogger1 = null;
try {
- sysLogger1 = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class));
- loggerDescMap.put(sysLogger1, "provider.getLogger(\"foo\", Thread.class)");
+ sysLogger1 = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class.getModule()));
+ loggerDescMap.put(sysLogger1, "provider.getLogger(\"foo\", Thread.class.getModule())");
if (!hasRequiredPermissions) {
throw new RuntimeException("Managed to obtain a system logger without permission");
}
@@ -224,8 +224,8 @@
final boolean old = allowControl.get().get();
allowControl.get().set(true);
try {
- sysLogger1 = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class));
- loggerDescMap.put(sysLogger1, "provider.getLogger(\"foo\", Thread.class)");
+ sysLogger1 = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class.getModule()));
+ loggerDescMap.put(sysLogger1, "provider.getLogger(\"foo\", Thread.class.getModule())");
} finally {
allowControl.get().set(old);
}
@@ -254,8 +254,8 @@
// callers and non system callers
Logger appLogger2 = null;
try {
- appLogger2 = provider.getLocalizedLogger("foo", loggerBundle, BaseLoggerFinderTest.class);
- loggerDescMap.put(appLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, BaseLoggerFinderTest.class)");
+ appLogger2 = provider.getLocalizedLogger("foo", loggerBundle, BaseLoggerFinderTest.class.getModule());
+ loggerDescMap.put(appLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, BaseLoggerFinderTest.class.getModule())");
if (!hasRequiredPermissions) {
throw new RuntimeException("Managed to obtain a logger without permission");
}
@@ -270,8 +270,8 @@
final boolean old = allowControl.get().get();
allowControl.get().set(true);
try {
- appLogger2 = provider.getLocalizedLogger("foo", loggerBundle, BaseLoggerFinderTest.class);
- loggerDescMap.put(appLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, BaseLoggerFinderTest.class)");
+ appLogger2 = provider.getLocalizedLogger("foo", loggerBundle, BaseLoggerFinderTest.class.getModule());
+ loggerDescMap.put(appLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, BaseLoggerFinderTest.class.getModule())");
} finally {
allowControl.get().set(old);
}
@@ -279,8 +279,8 @@
Logger sysLogger2 = null;
try {
- sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class);
- loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class)");
+ sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class.getModule());
+ loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class.getModule())");
if (!hasRequiredPermissions) {
throw new RuntimeException("Managed to obtain a system logger without permission");
}
@@ -295,8 +295,8 @@
final boolean old = allowControl.get().get();
allowControl.get().set(true);
try {
- sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class);
- loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class))");
+ sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class.getModule());
+ loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class.getModule()))");
} finally {
allowControl.get().set(old);
}
--- a/jdk/test/java/lang/System/LoggerFinder/BaseLoggerFinderTest/TestLoggerFinder.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/System/LoggerFinder/BaseLoggerFinderTest/TestLoggerFinder.java Thu Apr 28 23:08:17 2016 -0700
@@ -30,6 +30,7 @@
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Supplier;
import java.lang.System.Logger;
+import java.lang.reflect.Module;
/**
* What our test provider needs to implement.
@@ -176,6 +177,6 @@
}
}
- public Logger getLogger(String name, Class<?> caller);
- public Logger getLocalizedLogger(String name, ResourceBundle bundle, Class<?> caller);
+ public Logger getLogger(String name, Module caller);
+ public Logger getLocalizedLogger(String name, ResourceBundle bundle, Module caller);
}
--- a/jdk/test/java/lang/System/LoggerFinder/DefaultLoggerFinderTest/DefaultLoggerFinderTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/System/LoggerFinder/DefaultLoggerFinderTest/DefaultLoggerFinderTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -364,8 +364,8 @@
Logger appLogger1 = null;
try {
- appLogger1 = provider.getLogger("foo", DefaultLoggerFinderTest.class);
- loggerDescMap.put(appLogger1, "provider.getApplicationLogger(\"foo\")");
+ appLogger1 = provider.getLogger("foo", DefaultLoggerFinderTest.class.getModule());
+ loggerDescMap.put(appLogger1, "provider.getLogger(\"foo\", DefaultLoggerFinderTest.class.getModule())");
if (!hasRequiredPermissions) {
throw new RuntimeException("Managed to obtain a logger without permission");
}
@@ -380,8 +380,8 @@
boolean old = allowControl.get().get();
allowControl.get().set(true);
try {
- appLogger1 =provider.getLogger("foo", DefaultLoggerFinderTest.class);
- loggerDescMap.put(appLogger1, "provider.getApplicationLogger(\"foo\")");
+ appLogger1 =provider.getLogger("foo", DefaultLoggerFinderTest.class.getModule());
+ loggerDescMap.put(appLogger1, "provider.getLogger(\"foo\", DefaultLoggerFinderTest.class.getModule())");
} finally {
allowControl.get().set(old);
}
@@ -389,8 +389,8 @@
Logger sysLogger1 = null;
try {
- sysLogger1 = provider.getLogger("foo", Thread.class);
- loggerDescMap.put(sysLogger1, "provider.getSystemLogger(\"foo\")");
+ sysLogger1 = provider.getLogger("foo", Thread.class.getModule());
+ loggerDescMap.put(sysLogger1, "provider.getLogger(\"foo\", Thread.class.getModule())");
if (!hasRequiredPermissions) {
throw new RuntimeException("Managed to obtain a system logger without permission");
}
@@ -405,8 +405,8 @@
boolean old = allowControl.get().get();
allowControl.get().set(true);
try {
- sysLogger1 = provider.getLogger("foo", Thread.class);
- loggerDescMap.put(sysLogger1, "provider.getSystemLogger(\"foo\")");
+ sysLogger1 = provider.getLogger("foo", Thread.class.getModule());
+ loggerDescMap.put(sysLogger1, "provider.getLogger(\"foo\", Thread.class.getModule())");
} finally {
allowControl.get().set(old);
}
@@ -417,8 +417,8 @@
Logger appLogger2 = null;
try {
- appLogger2 = provider.getLocalizedLogger("foo", loggerBundle, DefaultLoggerFinderTest.class);
- loggerDescMap.put(appLogger2, "provider.getLocalizedApplicationLogger(\"foo\", loggerBundle)");
+ appLogger2 = provider.getLocalizedLogger("foo", loggerBundle, DefaultLoggerFinderTest.class.getModule());
+ loggerDescMap.put(appLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, DefaultLoggerFinderTest.class.getModule())");
if (!hasRequiredPermissions) {
throw new RuntimeException("Managed to obtain a logger without permission");
}
@@ -433,8 +433,8 @@
boolean old = allowControl.get().get();
allowControl.get().set(true);
try {
- appLogger2 = provider.getLocalizedLogger("foo", loggerBundle, DefaultLoggerFinderTest.class);
- loggerDescMap.put(appLogger2, "provider.getLocalizedApplicationLogger(\"foo\", loggerBundle)");
+ appLogger2 = provider.getLocalizedLogger("foo", loggerBundle, DefaultLoggerFinderTest.class.getModule());
+ loggerDescMap.put(appLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, DefaultLoggerFinderTest.class.getModule())");
} finally {
allowControl.get().set(old);
}
@@ -442,8 +442,8 @@
Logger sysLogger2 = null;
try {
- sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class);
- loggerDescMap.put(sysLogger2, "provider.getLocalizedSystemLogger(\"foo\", loggerBundle)");
+ sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class.getModule());
+ loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class.getModule())");
if (!hasRequiredPermissions) {
throw new RuntimeException("Managed to obtain a system logger without permission");
}
@@ -458,8 +458,8 @@
boolean old = allowControl.get().get();
allowControl.get().set(true);
try {
- sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class);
- loggerDescMap.put(sysLogger2, "provider.getLocalizedSystemLogger(\"foo\", loggerBundle)");
+ sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class.getModule());
+ loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class.getModule())");
} finally {
allowControl.get().set(old);
}
--- a/jdk/test/java/lang/System/LoggerFinder/internal/BaseDefaultLoggerFinderTest/BaseDefaultLoggerFinderTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/BaseDefaultLoggerFinderTest/BaseDefaultLoggerFinderTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -55,6 +55,7 @@
import jdk.internal.logger.DefaultLoggerFinder;
import jdk.internal.logger.SimpleConsoleLogger;
import sun.util.logging.PlatformLogger;
+import java.lang.reflect.Module;
/**
* @test
@@ -112,10 +113,10 @@
public final static AtomicLong sequencer = new AtomicLong();
- public Logger getLogger(String name, Class<?> caller);
- public Logger getLocalizedLogger(String name, ResourceBundle bundle, Class<?> caller);
- void setLevel(Logger logger, Level level, Class<?> caller);
- void setLevel(Logger logger, PlatformLogger.Level level, Class<?> caller);
+ public Logger getLogger(String name, Module caller);
+ public Logger getLocalizedLogger(String name, ResourceBundle bundle, Module caller);
+ void setLevel(Logger logger, Level level, Module caller);
+ void setLevel(Logger logger, PlatformLogger.Level level, Module caller);
PlatformLogger.Bridge asPlatformLoggerBridge(Logger logger);
}
@@ -130,7 +131,7 @@
}
@Override
- public void setLevel(Logger logger, Level level, Class<?> caller) {
+ public void setLevel(Logger logger, Level level, Module caller) {
PrivilegedAction<Void> pa = () -> {
setLevel(logger, PlatformLogger.toPlatformLevel(level), caller);
return null;
@@ -139,7 +140,7 @@
}
@Override
- public void setLevel(Logger logger, PlatformLogger.Level level, Class<?> caller) {
+ public void setLevel(Logger logger, PlatformLogger.Level level, Module caller) {
PrivilegedAction<Logger> pa = () -> demandLoggerFor(logger.getName(), caller);
Logger impl = AccessController.doPrivileged(pa);
SimpleConsoleLogger.class.cast(impl)
@@ -606,11 +607,12 @@
String name,
ResourceBundle loggerBundle,
Logger logger,
- Class<?> caller) {
+ Class<?> callerClass) {
System.out.println("Testing " + loggerDescMap.get(logger) + " [" + logger +"]");
AtomicLong sequencer = TestLoggerFinder.sequencer;
+ Module caller = callerClass.getModule();
Foo foo = new Foo();
String fooMsg = foo.toString();
for (Level loggerLevel : Level.values()) {
--- a/jdk/test/java/lang/System/LoggerFinder/internal/BaseLoggerBridgeTest/BaseLoggerBridgeTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/BaseLoggerBridgeTest/BaseLoggerBridgeTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -47,6 +47,7 @@
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.util.stream.Stream;
+import java.lang.reflect.Module;
/**
* @test
@@ -209,8 +210,6 @@
return Arrays.deepToString(toArray(false));
}
-
-
@Override
public boolean equals(Object obj) {
return obj instanceof LogEvent
@@ -342,15 +341,15 @@
}
- public Logger getLogger(String name, Class<?> caller);
- public Logger getLocalizedLogger(String name, ResourceBundle bundle, Class<?> caller);
+ public Logger getLogger(String name, Module caller);
+ public Logger getLocalizedLogger(String name, ResourceBundle bundle, Module caller);
}
public static class BaseLoggerFinder extends LoggerFinder implements TestLoggerFinder {
static final RuntimePermission LOGGERFINDER_PERMISSION =
new RuntimePermission("loggerFinder");
@Override
- public Logger getLogger(String name, Class<?> caller) {
+ public Logger getLogger(String name, Module caller) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOGGERFINDER_PERMISSION);
@@ -375,7 +374,7 @@
}
}
- static Logger getLogger(String name, Class<?> caller) {
+ static Logger getLogger(String name, Module caller) {
boolean old = allowAll.get().get();
allowAccess.get().set(true);
try {
@@ -465,7 +464,7 @@
TestLoggerFinder.LoggerImpl appSink = null;
try {
- appSink = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", BaseLoggerBridgeTest.class));
+ appSink = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", BaseLoggerBridgeTest.class.getModule()));
if (!hasRequiredPermissions) {
throw new RuntimeException("Managed to obtain a system logger without permission");
}
@@ -480,7 +479,7 @@
boolean old = allowControl.get().get();
allowControl.get().set(true);
try {
- appSink = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", BaseLoggerBridgeTest.class));
+ appSink = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", BaseLoggerBridgeTest.class.getModule()));
} finally {
allowControl.get().set(old);
}
@@ -489,7 +488,7 @@
TestLoggerFinder.LoggerImpl sysSink = null;
try {
- sysSink = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class));
+ sysSink = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class.getModule()));
if (!hasRequiredPermissions) {
throw new RuntimeException("Managed to obtain a system logger without permission");
}
@@ -527,13 +526,13 @@
Logger sysLogger1 = null;
try {
- sysLogger1 = getLogger("foo", Thread.class);
+ sysLogger1 = getLogger("foo", Thread.class.getModule());
loggerDescMap.put(sysLogger1,
- "jdk.internal.logger.LazyLoggers.getLogger(\"foo\", Thread.class)");
+ "jdk.internal.logger.LazyLoggers.getLogger(\"foo\", Thread.class.getModule())");
if (!hasRequiredPermissions) {
// check that the provider would have thrown an exception
- provider.getLogger("foo", Thread.class);
+ provider.getLogger("foo", Thread.class.getModule());
throw new RuntimeException("Managed to obtain a system logger without permission");
}
} catch (AccessControlException acx) {
@@ -572,8 +571,8 @@
Logger sysLogger2 = null;
try {
- sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class);
- loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class)");
+ sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class.getModule());
+ loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class.getModule())");
if (!hasRequiredPermissions) {
throw new RuntimeException("Managed to obtain a system logger without permission");
}
--- a/jdk/test/java/lang/System/LoggerFinder/internal/BasePlatformLoggerTest/BasePlatformLoggerTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/BasePlatformLoggerTest/BasePlatformLoggerTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -47,6 +47,7 @@
import java.security.AccessControlException;
import java.util.stream.Stream;
import sun.util.logging.PlatformLogger;
+import java.lang.reflect.Module;
/**
* @test
@@ -327,12 +328,12 @@
}
}
- public Logger getLogger(String name, Class<?> caller);
+ public Logger getLogger(String name, Module caller);
}
public static class BaseLoggerFinder extends LoggerFinder implements TestLoggerFinder {
@Override
- public Logger getLogger(String name, Class<?> caller) {
+ public Logger getLogger(String name, Module caller) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOGGERFINDER_PERMISSION);
@@ -433,7 +434,7 @@
try {
allowControl.get().set(true);
appSink = TestLoggerFinder.LoggerImpl.class.cast(
- provider.getLogger("foo", BasePlatformLoggerTest.class));
+ provider.getLogger("foo", BasePlatformLoggerTest.class.getModule()));
} finally {
allowControl.get().set(before);
}
@@ -442,7 +443,8 @@
before = allowControl.get().get();
try {
allowControl.get().set(true);
- sysSink = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class));
+ sysSink = TestLoggerFinder.LoggerImpl.class.cast(
+ provider.getLogger("foo", Thread.class.getModule()));
} finally {
allowControl.get().set(before);
}
--- a/jdk/test/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerAPIsTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerAPIsTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -30,7 +30,7 @@
import java.util.List;
import java.util.ResourceBundle;
import java.util.Set;
-
+import java.lang.reflect.Module;
import jdk.internal.logger.BootstrapLogger;
import jdk.internal.logger.LazyLoggers;
@@ -69,7 +69,7 @@
}
final Logger LOGGER =
- LazyLoggers.getLogger("foo.bar", Thread.class);
+ LazyLoggers.getLogger("foo.bar", Thread.class.getModule());
final sun.util.logging.PlatformLogger.Level PLATFORM_LEVEL =
sun.util.logging.PlatformLogger.Level.SEVERE;
final MyResources BUNDLE = new MyResources();
--- a/jdk/test/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -43,6 +43,7 @@
import java.util.stream.Stream;
import jdk.internal.logger.BootstrapLogger;
import jdk.internal.logger.LazyLoggers;
+import java.lang.reflect.Module;
/*
* @test
@@ -105,7 +106,7 @@
if (BootstrapLogger.isBooted()) {
throw new RuntimeException("VM should not be booted!");
}
- Logger logger = LazyLoggers.getLogger("foo.bar", Thread.class);
+ Logger logger = LazyLoggers.getLogger("foo.bar", Thread.class.getModule());
if (test != TestCase.NO_SECURITY) {
LogStream.err.println("Setting security manager");
@@ -261,7 +262,7 @@
SimplePolicy.allowAll.set(Boolean.TRUE);
try {
bazbaz = java.lang.System.LoggerFinder
- .getLoggerFinder().getLogger("foo.bar.baz.baz", BootstrapLoggerTest.class);
+ .getLoggerFinder().getLogger("foo.bar.baz.baz", BootstrapLoggerTest.class.getModule());
} finally {
SimplePolicy.allowAll.set(Boolean.FALSE);
}
--- a/jdk/test/java/lang/System/LoggerFinder/internal/LoggerBridgeTest/LoggerBridgeTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/LoggerBridgeTest/LoggerBridgeTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -51,6 +51,7 @@
import java.lang.System.Logger.Level;
import java.util.stream.Stream;
import sun.util.logging.PlatformLogger;
+import java.lang.reflect.Module;
/**
* @test
@@ -164,6 +165,7 @@
null, null, level, bundle, key,
thrown, params);
}
+
public static LogEvent of(long sequenceNumber,
boolean isLoggable, String name,
sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle,
@@ -231,7 +233,7 @@
try {
// Preload classes before the security manager is on.
providerClass = ClassLoader.getSystemClassLoader().loadClass("LoggerBridgeTest$LogProducerFinder");
- ((LoggerFinder)providerClass.newInstance()).getLogger("foo", providerClass);
+ ((LoggerFinder)providerClass.newInstance()).getLogger("foo", providerClass.getModule());
} catch (Exception ex) {
throw new ExceptionInInitializerError(ex);
}
@@ -415,7 +417,7 @@
}
@Override
- public Logger getLogger(String name, Class<?> caller) {
+ public Logger getLogger(String name, Module caller) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOGGERFINDER_PERMISSION);
@@ -430,6 +432,15 @@
}
}
+ static ClassLoader getClassLoader(Module m) {
+ final boolean before = allowAll.get().getAndSet(true);
+ try {
+ return m.getClassLoader();
+ } finally {
+ allowAll.get().set(before);
+ }
+ }
+
static final sun.util.logging.PlatformLogger.Level[] julLevels = {
sun.util.logging.PlatformLogger.Level.ALL,
sun.util.logging.PlatformLogger.Level.FINEST,
@@ -497,14 +508,14 @@
try {
Class<?> bridgeClass = Class.forName("jdk.internal.logger.LazyLoggers");
lazyGetLogger = bridgeClass.getDeclaredMethod("getLogger",
- String.class, Class.class);
+ String.class, Module.class);
lazyGetLogger.setAccessible(true);
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
- static Logger getLogger(LoggerFinder provider, String name, Class<?> caller) {
+ static Logger getLogger(LoggerFinder provider, String name, Module caller) {
Logger logger;
try {
logger = Logger.class.cast(lazyGetLogger.invoke(null, name, caller));
@@ -522,14 +533,14 @@
// The method above does not throw exception...
// call the provider here to verify that an exception would have
// been thrown by the provider.
- if (logger != null && caller == Thread.class) {
+ if (logger != null && caller == Thread.class.getModule()) {
Logger log = provider.getLogger(name, caller);
}
return logger;
}
- static Logger getLogger(LoggerFinder provider, String name, ResourceBundle bundle, Class<?> caller) {
- if (caller.getClassLoader() != null) {
+ static Logger getLogger(LoggerFinder provider, String name, ResourceBundle bundle, Module caller) {
+ if (getClassLoader(caller) != null) {
return System.getLogger(name,bundle);
} else {
return provider.getLocalizedLogger(name, bundle, caller);
@@ -614,12 +625,12 @@
Logger appLogger1 = System.getLogger("foo");
- loggerDescMap.put(appLogger1, "LogProducer.getApplicationLogger(\"foo\")");
+ loggerDescMap.put(appLogger1, "System.getLogger(\"foo\")");
Logger sysLogger1 = null;
try {
- sysLogger1 = getLogger(provider, "foo", Thread.class);
- loggerDescMap.put(sysLogger1, "LogProducer.getSystemLogger(\"foo\")");
+ sysLogger1 = getLogger(provider, "foo", Thread.class.getModule());
+ loggerDescMap.put(sysLogger1, "provider.getLogger(\"foo\", Thread.class.getModule())");
if (!hasRequiredPermissions) {
throw new RuntimeException("Managed to obtain a system logger without permission");
}
@@ -636,12 +647,12 @@
Logger appLogger2 =
System.getLogger("foo", loggerBundle);
- loggerDescMap.put(appLogger2, "LogProducer.getApplicationLogger(\"foo\", loggerBundle)");
+ loggerDescMap.put(appLogger2, "System.getLogger(\"foo\", loggerBundle)");
Logger sysLogger2 = null;
try {
- sysLogger2 = getLogger(provider, "foo", loggerBundle, Thread.class);
- loggerDescMap.put(sysLogger2, "provider.getSystemLogger(\"foo\", loggerBundle)");
+ sysLogger2 = getLogger(provider, "foo", loggerBundle, Thread.class.getModule());
+ loggerDescMap.put(sysLogger2, "provider.getLogger(\"foo\", loggerBundle, Thread.class.getModule())");
if (!hasRequiredPermissions) {
throw new RuntimeException("Managed to obtain a system logger without permission");
}
@@ -671,9 +682,9 @@
allowControl.get().set(true);
try {
appSink = LogProducerFinder.LoggerImpl.class.cast(
- provider.getLogger("foo", LoggerBridgeTest.class));
+ provider.getLogger("foo", LoggerBridgeTest.class.getModule()));
sysSink = LogProducerFinder.LoggerImpl.class.cast(
- provider.getLogger("foo", Thread.class));
+ provider.getLogger("foo", Thread.class.getModule()));
} finally {
allowControl.get().set(old);
}
--- a/jdk/test/java/lang/System/LoggerFinder/internal/LoggerFinderLoaderTest/LoggerFinderLoaderTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/LoggerFinderLoaderTest/LoggerFinderLoaderTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -53,6 +53,7 @@
import java.util.ServiceLoader;
import java.util.concurrent.atomic.AtomicReference;
import jdk.internal.logger.SimpleConsoleLogger;
+import java.lang.reflect.Module;
/**
* @test
@@ -166,8 +167,8 @@
}
- public Logger getLogger(String name, Class<?> caller);
- public Logger getLocalizedLogger(String name, ResourceBundle bundle, Class<?> caller);
+ public Logger getLogger(String name, Module caller);
+ public Logger getLocalizedLogger(String name, ResourceBundle bundle, Module caller);
}
public static class BaseLoggerFinder extends LoggerFinder implements TestLoggerFinder {
@@ -187,7 +188,7 @@
@Override
- public Logger getLogger(String name, Class<?> caller) {
+ public Logger getLogger(String name, Module caller) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOGGERFINDER_PERMISSION);
@@ -210,7 +211,7 @@
throw new ServiceConfigurationError("Should not come here");
}
@Override
- public Logger getLogger(String name, Class<?> caller) {
+ public Logger getLogger(String name, Module caller) {
throw new ServiceConfigurationError("Should not come here");
}
}
--- a/jdk/test/java/lang/System/LoggerFinder/internal/PlatformLoggerBridgeTest/PlatformLoggerBridgeTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/PlatformLoggerBridgeTest/PlatformLoggerBridgeTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -49,6 +49,7 @@
import java.lang.System.Logger.Level;
import java.util.stream.Stream;
import sun.util.logging.PlatformLogger;
+import java.lang.reflect.Module;
/**
* @test
@@ -94,7 +95,7 @@
try {
// Preload classes before the security manager is on.
providerClass = ClassLoader.getSystemClassLoader().loadClass("PlatformLoggerBridgeTest$LogProducerFinder");
- ((LoggerFinder)providerClass.newInstance()).getLogger("foo", providerClass);
+ ((LoggerFinder)providerClass.newInstance()).getLogger("foo", providerClass.getModule());
} catch (Exception ex) {
throw new ExceptionInInitializerError(ex);
}
@@ -415,7 +416,7 @@
}
@Override
- public Logger getLogger(String name, Class<?> caller) {
+ public Logger getLogger(String name, Module caller) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOGGERFINDER_PERMISSION);
@@ -598,7 +599,7 @@
allowControl.get().set(true);
try {
sysSink = LogProducerFinder.LoggerImpl.class.cast(
- provider.getLogger("foo", Thread.class));
+ provider.getLogger("foo", Thread.class.getModule()));
} finally {
allowControl.get().set(old);
}
--- a/jdk/test/java/lang/System/LoggerFinder/internal/api/LoggerFinderAPITest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/api/LoggerFinderAPITest.java Thu Apr 28 23:08:17 2016 -0700
@@ -469,12 +469,12 @@
errors.append(test.testGetLoggerOverriddenOnSpi());
java.lang.System.Logger julLogger =
java.lang.System.LoggerFinder.getLoggerFinder()
- .getLogger("foo", LoggerFinderAPITest.class);
+ .getLogger("foo", LoggerFinderAPITest.class.getModule());
errors.append(test.testDefaultJULLogger(julLogger));
if (errors.length() > 0) throw new RuntimeException(errors.toString());
java.lang.System.Logger julSystemLogger =
java.lang.System.LoggerFinder.getLoggerFinder()
- .getLogger("bar", Thread.class);
+ .getLogger("bar", Thread.class.getModule());
errors.append(test.testDefaultJULLogger(julSystemLogger));
if (errors.length() > 0) throw new RuntimeException(errors.toString());
java.lang.System.Logger julLocalizedLogger =
@@ -482,7 +482,7 @@
System.getLogger("baz", bundleLocalized);
java.lang.System.Logger julLocalizedSystemLogger =
java.lang.System.LoggerFinder.getLoggerFinder()
- .getLocalizedLogger("oof", bundleLocalized, Thread.class);
+ .getLocalizedLogger("oof", bundleLocalized, Thread.class.getModule());
final String error = errors.toString();
if (!error.isEmpty()) throw new RuntimeException(error);
for (java.lang.System.Logger logger : new java.lang.System.Logger[] {
--- a/jdk/test/java/lang/System/LoggerFinder/internal/backend/LoggerFinderBackendTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/backend/LoggerFinderBackendTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -77,6 +77,7 @@
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import sun.util.logging.internal.LoggingProviderImpl;
+import java.lang.reflect.Module;
/**
* @author danielfuchs
@@ -1506,7 +1507,7 @@
Logger getBackendLogger(String name) {
if (isSystem) {
return LoggingProviderImpl.getLogManagerAccess().demandLoggerFor(
- LogManager.getLogManager(), name, Thread.class);
+ LogManager.getLogManager(), name, Thread.class.getModule());
} else {
return Logger.getLogger(name);
}
@@ -1699,7 +1700,7 @@
Collections.synchronizedMap(new HashMap<>());
@Override
- public java.lang.System.Logger getLogger(String name, Class<?> caller) {
+ public java.lang.System.Logger getLogger(String name, Module caller) {
ClassLoader callerLoader = caller.getClassLoader();
if (callerLoader == null) {
systemLoggers.putIfAbsent(name, new CustomLogger(name));
@@ -1827,8 +1828,8 @@
public void setLevel(java.lang.System.Logger logger, Level level) {
final CustomLoggerFinder.CustomLogger l =
(CustomLoggerFinder.CustomLogger)
- (isSystem ? provider.getLogger(logger.getName(), Thread.class) :
- provider.getLogger(logger.getName(), LoggerFinderBackendTest.class));
+ (isSystem ? provider.getLogger(logger.getName(), Thread.class.getModule()) :
+ provider.getLogger(logger.getName(), LoggerFinderBackendTest.class.getModule()));
l.setLevel(provider.fromJul(level));
}
@Override
@@ -1840,8 +1841,8 @@
CustomLoggerFinder.CustomLevel getLevel(java.lang.System.Logger logger) {
final CustomLoggerFinder.CustomLogger l =
(CustomLoggerFinder.CustomLogger)
- (isSystem ? provider.getLogger(logger.getName(), Thread.class) :
- provider.getLogger(logger.getName(), LoggerFinderBackendTest.class));
+ (isSystem ? provider.getLogger(logger.getName(), Thread.class.getModule()) :
+ provider.getLogger(logger.getName(), LoggerFinderBackendTest.class.getModule()));
return l.level;
}
@@ -1962,7 +1963,7 @@
try {
Class<?> lazyLoggers = jdk.internal.logger.LazyLoggers.class;
getLazyLogger = lazyLoggers.getMethod("getLazyLogger",
- String.class, Class.class);
+ String.class, Module.class);
getLazyLogger.setAccessible(true);
Class<?> loggerFinderLoader =
Class.forName("java.lang.System$LoggerFinder");
@@ -1973,7 +1974,7 @@
}
}
- static java.lang.System.Logger getSystemLogger(String name, Class<?> caller) throws Exception {
+ static java.lang.System.Logger getSystemLogger(String name, Module caller) throws Exception {
try {
return java.lang.System.Logger.class.cast(getLazyLogger.invoke(null, name, caller));
} catch (InvocationTargetException x) {
@@ -1986,7 +1987,7 @@
}
}
static java.lang.System.Logger getSystemLogger(String name,
- ResourceBundle bundle, Class<?> caller) throws Exception {
+ ResourceBundle bundle, Module caller) throws Exception {
try {
LoggerFinder provider = LoggerFinder.class.cast(accessLoggerFinder.invoke(null));
return provider.getLocalizedLogger(name, bundle, caller);
@@ -2047,14 +2048,14 @@
final BackendTester tester = factory.createBackendTester(false);
final java.lang.System.Logger logger =
java.lang.System.LoggerFinder.getLoggerFinder()
- .getLogger("foo", LoggerFinderBackendTest.class);
+ .getLogger("foo", LoggerFinderBackendTest.class.getModule());
testLogger(tester, logger, nb);
// Test a simple system logger with JUL backend
final java.lang.System.Logger system =
java.lang.System.LoggerFinder.getLoggerFinder()
- .getLogger("bar", Thread.class);
+ .getLogger("bar", Thread.class.getModule());
final BackendTester systemTester = factory.createBackendTester(true);
testLogger(systemTester, system, nb);
@@ -2062,7 +2063,7 @@
// JUL backend
final java.lang.System.Logger noBundleLogger =
java.lang.System.LoggerFinder.getLoggerFinder()
- .getLocalizedLogger("baz", null, LoggerFinderBackendTest.class);
+ .getLocalizedLogger("baz", null, LoggerFinderBackendTest.class.getModule());
final BackendTester noBundleTester =
factory.createBackendTester(false, spiLoggerClass);
testLogger(noBundleTester, noBundleLogger, nb);
@@ -2071,7 +2072,7 @@
// backend
final java.lang.System.Logger noBundleSysLogger =
java.lang.System.LoggerFinder.getLoggerFinder()
- .getLocalizedLogger("oof", null, Thread.class);
+ .getLocalizedLogger("oof", null, Thread.class.getModule());
final BackendTester noBundleSysTester =
factory.createBackendTester(true, spiLoggerClass);
testLogger(noBundleSysTester, noBundleSysLogger, nb);
@@ -2085,14 +2086,14 @@
System.out.println("System.Loggers.getLogger(\"baz\", null): got expected " + x);
}
final java.lang.System.Logger noBundleExtensionLogger =
- getSystemLogger("baz", null, LoggerFinderBackendTest.class);
+ getSystemLogger("baz", null, LoggerFinderBackendTest.class.getModule());
final BackendTester noBundleExtensionTester =
factory.createBackendTester(false, jdkLoggerClass);
testLogger(noBundleExtensionTester, noBundleExtensionLogger, nb);
// Test a simple system logger with JUL backend
final java.lang.System.Logger sysExtensionLogger =
- getSystemLogger("oof", Thread.class);
+ getSystemLogger("oof", Thread.class.getModule());
final BackendTester sysExtensionTester =
factory.createBackendTester(true, jdkLoggerClass);
testLogger(sysExtensionTester, sysExtensionLogger, nb);
@@ -2100,7 +2101,7 @@
// Test a localized system logger with null resource bundle and JUL
// backend
final java.lang.System.Logger noBundleSysExtensionLogger =
- getSystemLogger("oof", null, Thread.class);
+ getSystemLogger("oof", null, Thread.class.getModule());
final BackendTester noBundleSysExtensionTester =
factory.createBackendTester(true, jdkLoggerClass);
testLogger(noBundleSysExtensionTester, noBundleSysExtensionLogger, nb);
@@ -2127,7 +2128,7 @@
ResourceBundle.getBundle(ResourceBundeLocalized.class.getName());
final java.lang.System.Logger bundleLogger =
java.lang.System.LoggerFinder.getLoggerFinder()
- .getLocalizedLogger("toto", bundle, LoggerFinderBackendTest.class);
+ .getLocalizedLogger("toto", bundle, LoggerFinderBackendTest.class.getModule());
final BackendTester bundleTester =
factory.createBackendTester(false, spiLoggerClass, bundle);
testLogger(bundleTester, bundleLogger, nb);
@@ -2135,7 +2136,7 @@
// Test a localized system logger with resource bundle and JUL backend
final java.lang.System.Logger bundleSysLogger =
java.lang.System.LoggerFinder.getLoggerFinder()
- .getLocalizedLogger("titi", bundle, Thread.class);
+ .getLocalizedLogger("titi", bundle, Thread.class.getModule());
final BackendTester bundleSysTester =
factory.createBackendTester(true, spiLoggerClass, bundle);
testLogger(bundleSysTester, bundleSysLogger, nb);
@@ -2151,7 +2152,7 @@
// Test a localized Jdk system logger with resource bundle and JUL
// backend
final java.lang.System.Logger bundleExtensionSysLogger =
- getSystemLogger("titu", bundle, Thread.class);
+ getSystemLogger("titu", bundle, Thread.class.getModule());
final BackendTester bundleExtensionSysTester =
factory.createBackendTester(true, jdkLoggerClass, bundle);
testLogger(bundleExtensionSysTester, bundleExtensionSysLogger, nb);
--- a/jdk/test/java/lang/System/LoggerFinder/jdk/DefaultLoggerBridgeTest/DefaultLoggerBridgeTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/System/LoggerFinder/jdk/DefaultLoggerBridgeTest/DefaultLoggerBridgeTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -48,6 +48,7 @@
import java.lang.System.Logger;
import java.util.stream.Stream;
import sun.util.logging.internal.LoggingProviderImpl;
+import java.lang.reflect.Module;
/**
* @test
@@ -246,7 +247,7 @@
}
}
- static Logger getLogger(String name, Class<?> caller) {
+ static Logger getLogger(String name, Module caller) {
boolean old = allowAccess.get().get();
allowAccess.get().set(true);
try {
@@ -311,8 +312,8 @@
ResourceBundle.getBundle(MyLoggerBundle.class.getName());
final Map<Object, String> loggerDescMap = new HashMap<>();
- Logger sysLogger1a = getLogger("foo", Thread.class);
- loggerDescMap.put(sysLogger1a, "jdk.internal.logger.LazyLoggers.getLogger(\"foo\", Thread.class)");
+ Logger sysLogger1a = getLogger("foo", Thread.class.getModule());
+ loggerDescMap.put(sysLogger1a, "jdk.internal.logger.LazyLoggers.getLogger(\"foo\", Thread.class.getModule())");
Logger appLogger1 = System.getLogger("foo");
loggerDescMap.put(appLogger1, "System.getLogger(\"foo\")");
@@ -341,9 +342,9 @@
Logger sysLogger1b = null;
try {
- sysLogger1b = provider.getLogger("foo", Thread.class);
+ sysLogger1b = provider.getLogger("foo", Thread.class.getModule());
if (sysLogger1b != sysLogger1a) {
- loggerDescMap.put(sysLogger1b, "provider.getLogger(\"foo\", Thread.class)");
+ loggerDescMap.put(sysLogger1b, "provider.getLogger(\"foo\", Thread.class.getModule())");
}
if (!hasRequiredPermissions) {
throw new RuntimeException("Managed to obtain a system logger without permission");
@@ -367,8 +368,8 @@
Logger sysLogger2 = null;
try {
- sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class);
- loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class)");
+ sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class.getModule());
+ loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class.getModule())");
if (!hasRequiredPermissions) {
throw new RuntimeException("Managed to obtain a system logger without permission");
}
@@ -396,9 +397,9 @@
allowAll.get().set(true);
try {
sysSink = LoggingProviderImpl.getLogManagerAccess().demandLoggerFor(
- LogManager.getLogManager(), "foo", Thread.class);
+ LogManager.getLogManager(), "foo", Thread.class.getModule());
appSink = LoggingProviderImpl.getLogManagerAccess().demandLoggerFor(
- LogManager.getLogManager(), "foo", DefaultLoggerBridgeTest.class);
+ LogManager.getLogManager(), "foo", DefaultLoggerBridgeTest.class.getModule());
if (appSink == sysSink) {
throw new RuntimeException("identical backend loggers");
}
--- a/jdk/test/java/lang/System/LoggerFinder/jdk/DefaultPlatformLoggerTest/DefaultPlatformLoggerTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/System/LoggerFinder/jdk/DefaultPlatformLoggerTest/DefaultPlatformLoggerTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -44,6 +44,7 @@
import java.lang.System.LoggerFinder;
import sun.util.logging.PlatformLogger;
import sun.util.logging.internal.LoggingProviderImpl;
+import java.lang.reflect.Module;
/**
* @test
@@ -244,9 +245,9 @@
LoggerFinder provider = LoggerFinder.getLoggerFinder();
java.util.logging.Logger appSink = LoggingProviderImpl.getLogManagerAccess()
.demandLoggerFor(LogManager.getLogManager(), "foo",
- DefaultPlatformLoggerTest.class);
+ DefaultPlatformLoggerTest.class.getModule());
java.util.logging.Logger sysSink = LoggingProviderImpl.getLogManagerAccess()
- .demandLoggerFor(LogManager.getLogManager(),"foo", Thread.class);
+ .demandLoggerFor(LogManager.getLogManager(),"foo", Thread.class.getModule());
appSink.addHandler(new MyHandler());
sysSink.addHandler(new MyHandler());
appSink.setUseParentHandlers(VERBOSE);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/ArrayConstructorTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8155106
+ * @run testng/othervm -ea -esa test.java.lang.invoke.ArrayConstructorTest
+ */
+package test.java.lang.invoke;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+
+import static java.lang.invoke.MethodType.methodType;
+
+import static org.testng.AssertJUnit.*;
+
+import org.testng.annotations.*;
+
+
+public class ArrayConstructorTest {
+
+ static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
+
+ @Test
+ public static void testFindConstructorArray() {
+ boolean caught = false;
+ try {
+ MethodHandle h = LOOKUP.findConstructor(Object[].class, methodType(void.class));
+ } catch (NoSuchMethodException nsme) {
+ assertEquals("no constructor for array class: [Ljava.lang.Object;", nsme.getMessage());
+ caught = true;
+ } catch (Exception e) {
+ throw new AssertionError("unexpected exception: " + e);
+ }
+ assertTrue(caught);
+ }
+
+ @DataProvider
+ static Object[][] arrayConstructorNegative() {
+ return new Object[][]{
+ {String.class, IllegalArgumentException.class, "not an array class: java.lang.String"},
+ {null, NullPointerException.class, null}
+ };
+ }
+
+ @Test(dataProvider = "arrayConstructorNegative")
+ public static void testArrayConstructorNegative(Class<?> clazz, Class<?> exceptionClass, String message) {
+ boolean caught = false;
+ try {
+ MethodHandle h = MethodHandles.arrayConstructor(clazz);
+ } catch (Exception e) {
+ assertEquals(exceptionClass, e.getClass());
+ if (message != null) {
+ assertEquals(message, e.getMessage());
+ }
+ caught = true;
+ }
+ assertTrue(caught);
+ }
+
+ @Test
+ public static void testArrayConstructor() throws Throwable {
+ MethodHandle h = MethodHandles.arrayConstructor(String[].class);
+ assertEquals(methodType(String[].class, int.class), h.type());
+ String[] a = (String[]) h.invoke(17);
+ assertEquals(17, a.length);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/JavaUtilConcurrentLookupTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @summary Tests that Lookup can be produced from classes under java.util.concurrent
+ * @bug 8154447
+ * @compile/module=java.base java/util/concurrent/LookupTester.java
+ * @run testng/othervm JavaUtilConcurrentLookupTest
+ */
+
+import org.testng.annotations.Test;
+
+import java.util.concurrent.LookupTester;
+
+public class JavaUtilConcurrentLookupTest {
+
+ @Test
+ public void testLookup() {
+ LookupTester.getLookup();
+ }
+
+ @Test
+ public void testLookupIn() {
+ LookupTester.getLookupIn();
+ }
+}
--- a/jdk/test/java/lang/invoke/LoopCombinatorTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/invoke/LoopCombinatorTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -28,7 +28,10 @@
* @bug 8150635
* @bug 8150956
* @bug 8150957
+ * @bug 8152667
* @bug 8153637
+ * @bug 8154751
+ * @bug 8154754
* @run testng/othervm -ea -esa test.java.lang.invoke.LoopCombinatorTest
*/
@@ -325,6 +328,74 @@
}
@Test
+ public static void testCountedLoopNullBody() throws Throwable {
+ MethodHandle h5 = MethodHandles.constant(int.class, 5);
+ MethodHandle h13 = MethodHandles.constant(int.class, 13);
+ MethodHandle loop = MethodHandles.countedLoop(h5, h13, null);
+ assertEquals(methodType(int.class), loop.type());
+ assertEquals(13, loop.invoke());
+ }
+
+ @Test
+ public static void testCountedLoopNullIterations() throws Throwable {
+ MethodHandle loop = MethodHandles.countedLoop(null, null, null);
+ assertEquals(methodType(void.class), loop.type());
+ loop.invoke();
+ }
+
+ @Test
+ public static void testCountedLoopNullInitAndBody() throws Throwable {
+ MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null, null);
+ assertEquals(methodType(void.class), loop.type());
+ loop.invoke();
+ }
+
+ @DataProvider
+ static Object[][] countedLoopBodyParameters() {
+ return new Object[][] {
+ {methodType(String.class), methodType(String.class, int.class)},
+ {methodType(String.class, List.class), methodType(String.class, int.class)},
+ {methodType(String.class, List.class), methodType(String.class, int.class, String.class)}
+ };
+ }
+
+ @Test(dataProvider = "countedLoopBodyParameters")
+ public static void testCountedLoopBodyParameters(MethodType initType, MethodType bodyType) throws Throwable {
+ MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5),
+ MethodHandles.empty(initType), MethodHandles.empty(bodyType));
+ assertEquals(initType, loop.type());
+ }
+
+ @DataProvider
+ static Object[][] countedLoopTypes() {
+ return new Object[][]{{void.class}, {int.class}, {Object.class}, {String.class}, {List.class}};
+ }
+
+ @Test(dataProvider = "countedLoopTypes")
+ public static void testCountedLoopBodyParametersNullInit(Class<?> t) throws Throwable {
+ MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null,
+ MethodHandles.empty(methodType(t, int.class)));
+ assertEquals(methodType(t), loop.type());
+ loop.invoke();
+ }
+
+ @Test
+ public static void testCountedLoopStateDefinedByBody() throws Throwable {
+ MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null, Counted.MH_stateBody);
+ assertEquals(Counted.MT_bodyDeterminesState, loop.type());
+ assertEquals("sssssnull01234", loop.invoke());
+ }
+
+ @Test
+ public static void testCountedLoopArgsDefinedByIterations() throws Throwable {
+ MethodHandle loop = MethodHandles.countedLoop(
+ MethodHandles.dropArguments(MethodHandles.constant(int.class, 3), 0, String.class),
+ null, Counted.MH_append);
+ assertEquals(Counted.MT_iterationsDefineArgs, loop.type());
+ assertEquals("hello012", loop.invoke("hello"));
+ }
+
+ @Test
public static void testCountedRangeLoop() throws Throwable {
// String s = "Lambdaman!"; for (int i = -5; i < 8; ++i) { s = "na " + s; } return s; => a well known theme
MethodHandle fitm5 = MethodHandles.dropArguments(Counted.MH_m5, 0, String.class);
@@ -347,6 +418,23 @@
}
@Test
+ public static void testCountedLoopEmpty() throws Throwable {
+ // for (int i = 0; i < 5; ++i) { /* empty */ }
+ MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null, null);
+ assertEquals(methodType(void.class), loop.type());
+ loop.invoke();
+ }
+
+ @Test
+ public static void testCountedRangeLoopEmpty() throws Throwable {
+ // for (int i = -5; i < 5; ++i) { /* empty */ }
+ MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, -5),
+ MethodHandles.constant(int.class, 5), null, null);
+ assertEquals(methodType(void.class), loop.type());
+ loop.invoke();
+ }
+
+ @Test
public static void testIterateSum() throws Throwable {
// Integer[] a = new Integer[]{1,2,3,4,5,6}; int sum = 0; for (int e : a) { sum += e; } return sum; => 21
MethodHandle loop = MethodHandles.iteratedLoop(Iterate.MH_sumIterator, Iterate.MH_sumInit, Iterate.MH_sumStep);
@@ -400,10 +488,15 @@
assertTrue(caught);
}
- @Test
- public static void testIterateVoidIterator() {
+ @DataProvider
+ static Object[][] wrongIteratorTypes() {
+ return new Object[][]{{void.class}, {Object.class}, {Iterable.class}};
+ }
+
+ @Test(dataProvider = "wrongIteratorTypes")
+ public static void testIterateVoidIterator(Class<?> it) {
boolean caught = false;
- MethodType v = methodType(void.class);
+ MethodType v = methodType(it);
try {
MethodHandles.iteratedLoop(MethodHandles.empty(v), null, MethodHandles.empty(v));
} catch(IllegalArgumentException iae) {
@@ -420,6 +513,77 @@
loop.invoke(Arrays.asList("hello", "world"));
}
+ @DataProvider
+ static Object[][] iterateParameters() {
+ MethodType i = methodType(int.class);
+ MethodType sil_i = methodType(int.class, String.class, int.class, List.class);
+ MethodType sl_v = methodType(void.class, String.class, List.class);
+ MethodType l_it = methodType(Iterator.class, List.class);
+ MethodType li_it = methodType(Iterator.class, List.class, int.class);
+ MethodType l_i = methodType(int.class, List.class);
+ MethodType _it = methodType(Iterator.class);
+ MethodType si_i = methodType(int.class, String.class, int.class);
+ MethodType s_i = methodType(int.class, String.class);
+ return new Object[][]{
+ {null, null, sl_v},
+ {null, i, sil_i},
+ {null, l_i, sil_i},
+ {l_it, null, sl_v},
+ {l_it, i, sil_i},
+ {li_it, l_i, sil_i},
+ {l_it, null, sil_i},
+ {li_it, null, sl_v},
+ {_it, l_i, si_i},
+ {_it, l_i, s_i}
+ };
+ }
+
+ @Test(dataProvider = "iterateParameters")
+ public static void testIterateParameters(MethodType it, MethodType in, MethodType bo) throws Throwable {
+ MethodHandle iterator = it == null ? null : MethodHandles.empty(it);
+ MethodHandle init = in == null ? null : MethodHandles.empty(in);
+ MethodHandle loop = MethodHandles.iteratedLoop(iterator, init, MethodHandles.empty(bo));
+ MethodType lt = loop.type();
+ if (it == null && in == null) {
+ assertEquals(bo.dropParameterTypes(0, 1), lt);
+ } else if (it == null) {
+ if (in.parameterCount() == 0) {
+ assertEquals(bo.dropParameterTypes(0, in.returnType() == void.class ? 1 : 2), lt);
+ } else {
+ assertEquals(methodType(bo.returnType(), in.parameterArray()), lt);
+ }
+ } else if (in == null) {
+ assertEquals(methodType(bo.returnType(), it.parameterArray()), lt);
+ } else if (it.parameterCount() > in.parameterCount()) {
+ assertEquals(methodType(bo.returnType(), it.parameterArray()), lt);
+ } else if (it.parameterCount() < in.parameterCount()) {
+ assertEquals(methodType(bo.returnType(), in.parameterArray()), lt);
+ } else {
+ // both it, in present; with equal parameter list lengths
+ assertEquals(it.parameterList(), lt.parameterList());
+ assertEquals(in.parameterList(), lt.parameterList());
+ assertEquals(bo.returnType(), lt.returnType());
+ }
+ }
+
+ @Test
+ public static void testIteratorSubclass() throws Throwable {
+ MethodHandle loop = MethodHandles.iteratedLoop(MethodHandles.empty(methodType(BogusIterator.class, List.class)),
+ null, MethodHandles.empty(methodType(void.class, String.class)));
+ assertEquals(methodType(void.class, List.class), loop.type());
+ }
+
+ static class BogusIterator implements Iterator {
+ @Override
+ public boolean hasNext() {
+ return false;
+ }
+ @Override
+ public Object next() {
+ return null;
+ }
+ }
+
static class Empty {
static void f() { }
@@ -744,6 +908,17 @@
return x + counter;
}
+ static String stateBody(int counter, String s) {
+ return "s" + s + counter;
+ }
+
+ static String append(int counter, String localState, String loopArg) {
+ if (null == localState) {
+ return loopArg + counter;
+ }
+ return localState + counter;
+ }
+
static final Class<Counted> COUNTED = Counted.class;
static final MethodType MT_start = methodType(String.class, String.class);
@@ -751,6 +926,8 @@
static final MethodType MT_stepUpdateArray = methodType(void.class, int.class, int[].class);
static final MethodType MT_printHello = methodType(void.class, int.class);
static final MethodType MT_addCounter = methodType(int.class, int.class, int.class);
+ static final MethodType MT_stateBody = methodType(String.class, int.class, String.class);
+ static final MethodType MT_append = methodType(String.class, int.class, String.class, String.class);
static final MethodHandle MH_13;
static final MethodHandle MH_m5;
@@ -760,11 +937,15 @@
static final MethodHandle MH_stepUpdateArray;
static final MethodHandle MH_printHello;
static final MethodHandle MH_addCounter;
+ static final MethodHandle MH_stateBody;
+ static final MethodHandle MH_append;
static final MethodType MT_counted = methodType(String.class, String.class);
static final MethodType MT_arrayCounted = methodType(void.class, int[].class);
static final MethodType MT_countedPrinting = methodType(void.class);
static final MethodType MT_counterInit = methodType(int.class);
+ static final MethodType MT_bodyDeterminesState = methodType(String.class);
+ static final MethodType MT_iterationsDefineArgs = methodType(String.class, String.class);
static {
try {
@@ -776,6 +957,8 @@
MH_stepUpdateArray = LOOKUP.findStatic(COUNTED, "stepUpdateArray", MT_stepUpdateArray);
MH_printHello = LOOKUP.findStatic(COUNTED, "printHello", MT_printHello);
MH_addCounter = LOOKUP.findStatic(COUNTED, "addCounter", MT_addCounter);
+ MH_stateBody = LOOKUP.findStatic(COUNTED, "stateBody", MT_stateBody);
+ MH_append = LOOKUP.findStatic(COUNTED, "append", MT_append);
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
--- a/jdk/test/java/lang/invoke/PermuteArgsTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/invoke/PermuteArgsTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/* @test
* @summary unit tests for method handles which permute their arguments
+ * @library /lib/testlibrary/jsr292 /lib/testlibrary
* @run testng/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies -ea -esa -DPermuteArgsTest.MAX_ARITY=8 test.java.lang.invoke.PermuteArgsTest
*/
/* Examples of manual runs:
@@ -36,6 +37,8 @@
import org.testng.*;
import org.testng.annotations.*;
+import com.oracle.testlibrary.jsr292.CodeCacheOverflowProcessor;
+
import java.util.*;
import java.lang.reflect.*;
@@ -122,9 +125,15 @@
}
new PermuteArgsTest().test();
}
+
static int testCases;
+
@Test
public void test() throws Throwable {
+ CodeCacheOverflowProcessor.runMHTest(this::test0);
+ }
+
+ public void test0() throws Throwable {
testCases = 0;
Lookup lookup = lookup();
for (Method m : lookup.lookupClass().getDeclaredMethods()) {
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java Thu Apr 28 23:08:17 2016 -0700
@@ -106,7 +106,6 @@
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
- assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java Thu Apr 28 23:08:17 2016 -0700
@@ -106,7 +106,6 @@
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
- assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java Thu Apr 28 23:08:17 2016 -0700
@@ -106,7 +106,6 @@
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
- assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java Thu Apr 28 23:08:17 2016 -0700
@@ -106,7 +106,6 @@
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
- assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java Thu Apr 28 23:08:17 2016 -0700
@@ -106,7 +106,6 @@
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
- assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java Thu Apr 28 23:08:17 2016 -0700
@@ -106,7 +106,6 @@
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
- assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java Thu Apr 28 23:08:17 2016 -0700
@@ -106,7 +106,6 @@
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
- assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java Thu Apr 28 23:08:17 2016 -0700
@@ -106,7 +106,6 @@
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
- assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessString.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessString.java Thu Apr 28 23:08:17 2016 -0700
@@ -106,7 +106,6 @@
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
- assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java Thu Apr 28 23:08:17 2016 -0700
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 8154556
* @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsChar
* @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsChar
* @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsChar
@@ -57,15 +58,16 @@
// Combinations of VarHandle byte[] or ByteBuffer
vhss = new ArrayList<>();
for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+
+ ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
+ ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
VarHandleSource aeh = new VarHandleSource(
- MethodHandles.byteArrayViewVarHandle(char[].class,
- endianess == MemoryMode.BIG_ENDIAN),
+ MethodHandles.byteArrayViewVarHandle(char[].class, bo),
endianess, MemoryMode.READ_WRITE);
vhss.add(aeh);
VarHandleSource bbh = new VarHandleSource(
- MethodHandles.byteBufferViewVarHandle(char[].class,
- endianess == MemoryMode.BIG_ENDIAN),
+ MethodHandles.byteBufferViewVarHandle(char[].class, bo),
endianess, MemoryMode.READ_WRITE);
vhss.add(bbh);
}
@@ -93,7 +95,6 @@
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
- assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java Thu Apr 28 23:08:17 2016 -0700
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 8154556
* @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsDouble
* @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsDouble
* @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsDouble
@@ -57,15 +58,16 @@
// Combinations of VarHandle byte[] or ByteBuffer
vhss = new ArrayList<>();
for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+
+ ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
+ ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
VarHandleSource aeh = new VarHandleSource(
- MethodHandles.byteArrayViewVarHandle(double[].class,
- endianess == MemoryMode.BIG_ENDIAN),
+ MethodHandles.byteArrayViewVarHandle(double[].class, bo),
endianess, MemoryMode.READ_WRITE);
vhss.add(aeh);
VarHandleSource bbh = new VarHandleSource(
- MethodHandles.byteBufferViewVarHandle(double[].class,
- endianess == MemoryMode.BIG_ENDIAN),
+ MethodHandles.byteBufferViewVarHandle(double[].class, bo),
endianess, MemoryMode.READ_WRITE);
vhss.add(bbh);
}
@@ -93,7 +95,6 @@
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
- assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java Thu Apr 28 23:08:17 2016 -0700
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 8154556
* @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsFloat
* @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsFloat
* @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsFloat
@@ -57,15 +58,16 @@
// Combinations of VarHandle byte[] or ByteBuffer
vhss = new ArrayList<>();
for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+
+ ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
+ ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
VarHandleSource aeh = new VarHandleSource(
- MethodHandles.byteArrayViewVarHandle(float[].class,
- endianess == MemoryMode.BIG_ENDIAN),
+ MethodHandles.byteArrayViewVarHandle(float[].class, bo),
endianess, MemoryMode.READ_WRITE);
vhss.add(aeh);
VarHandleSource bbh = new VarHandleSource(
- MethodHandles.byteBufferViewVarHandle(float[].class,
- endianess == MemoryMode.BIG_ENDIAN),
+ MethodHandles.byteBufferViewVarHandle(float[].class, bo),
endianess, MemoryMode.READ_WRITE);
vhss.add(bbh);
}
@@ -93,7 +95,6 @@
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
- assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java Thu Apr 28 23:08:17 2016 -0700
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 8154556
* @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsInt
* @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsInt
* @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsInt
@@ -37,10 +38,10 @@
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.EnumSet;
import java.util.List;
-import static org.testng.Assert.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest {
static final int SIZE = Integer.BYTES;
@@ -57,15 +58,16 @@
// Combinations of VarHandle byte[] or ByteBuffer
vhss = new ArrayList<>();
for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+
+ ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
+ ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
VarHandleSource aeh = new VarHandleSource(
- MethodHandles.byteArrayViewVarHandle(int[].class,
- endianess == MemoryMode.BIG_ENDIAN),
+ MethodHandles.byteArrayViewVarHandle(int[].class, bo),
endianess, MemoryMode.READ_WRITE);
vhss.add(aeh);
VarHandleSource bbh = new VarHandleSource(
- MethodHandles.byteBufferViewVarHandle(int[].class,
- endianess == MemoryMode.BIG_ENDIAN),
+ MethodHandles.byteBufferViewVarHandle(int[].class, bo),
endianess, MemoryMode.READ_WRITE);
vhss.add(bbh);
}
@@ -93,7 +95,6 @@
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
- assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java Thu Apr 28 23:08:17 2016 -0700
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 8154556
* @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsLong
* @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsLong
* @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsLong
@@ -57,15 +58,16 @@
// Combinations of VarHandle byte[] or ByteBuffer
vhss = new ArrayList<>();
for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+
+ ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
+ ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
VarHandleSource aeh = new VarHandleSource(
- MethodHandles.byteArrayViewVarHandle(long[].class,
- endianess == MemoryMode.BIG_ENDIAN),
+ MethodHandles.byteArrayViewVarHandle(long[].class, bo),
endianess, MemoryMode.READ_WRITE);
vhss.add(aeh);
VarHandleSource bbh = new VarHandleSource(
- MethodHandles.byteBufferViewVarHandle(long[].class,
- endianess == MemoryMode.BIG_ENDIAN),
+ MethodHandles.byteBufferViewVarHandle(long[].class, bo),
endianess, MemoryMode.READ_WRITE);
vhss.add(bbh);
}
@@ -93,7 +95,6 @@
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
- assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java Thu Apr 28 23:08:17 2016 -0700
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 8154556
* @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsShort
* @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsShort
* @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsShort
@@ -57,15 +58,16 @@
// Combinations of VarHandle byte[] or ByteBuffer
vhss = new ArrayList<>();
for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+
+ ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
+ ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
VarHandleSource aeh = new VarHandleSource(
- MethodHandles.byteArrayViewVarHandle(short[].class,
- endianess == MemoryMode.BIG_ENDIAN),
+ MethodHandles.byteArrayViewVarHandle(short[].class, bo),
endianess, MemoryMode.READ_WRITE);
vhss.add(aeh);
VarHandleSource bbh = new VarHandleSource(
- MethodHandles.byteBufferViewVarHandle(short[].class,
- endianess == MemoryMode.BIG_ENDIAN),
+ MethodHandles.byteBufferViewVarHandle(short[].class, bo),
endianess, MemoryMode.READ_WRITE);
vhss.add(bbh);
}
@@ -93,7 +95,6 @@
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
- assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
--- a/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template Thu Apr 28 23:08:17 2016 -0700
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 8154556
* @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAs$Type$
* @run testng/othervm -Diters=20000 VarHandleTestByteArrayAs$Type$
* @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAs$Type$
@@ -57,15 +58,16 @@
// Combinations of VarHandle byte[] or ByteBuffer
vhss = new ArrayList<>();
for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+
+ ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
+ ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
VarHandleSource aeh = new VarHandleSource(
- MethodHandles.byteArrayViewVarHandle($type$[].class,
- endianess == MemoryMode.BIG_ENDIAN),
+ MethodHandles.byteArrayViewVarHandle($type$[].class, bo),
endianess, MemoryMode.READ_WRITE);
vhss.add(aeh);
VarHandleSource bbh = new VarHandleSource(
- MethodHandles.byteBufferViewVarHandle($type$[].class,
- endianess == MemoryMode.BIG_ENDIAN),
+ MethodHandles.byteBufferViewVarHandle($type$[].class, bo),
endianess, MemoryMode.READ_WRITE);
vhss.add(bbh);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/java.base/java/util/concurrent/LookupTester.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.util.concurrent;
+
+import java.lang.invoke.MethodHandles;
+
+public class LookupTester {
+ public static MethodHandles.Lookup getLookup() {
+ return MethodHandles.lookup();
+ }
+
+
+ public static MethodHandles.Lookup getLookupIn() {
+ return MethodHandles.lookup().in(ConcurrentHashMap.class);
+ }
+}
--- a/jdk/test/java/net/SocketOption/OptionsTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/net/SocketOption/OptionsTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -23,11 +23,13 @@
/*
* @test
- * @bug 8036979 8072384
+ * @bug 8036979 8072384 8044773
* @run main/othervm -Xcheck:jni OptionsTest
* @run main/othervm -Xcheck:jni -Djava.net.preferIPv4Stack=true OptionsTest
+ * @run main/othervm -Djdk.launcher.limitmods=java.base OptionsTest
*/
+import java.lang.reflect.Method;
import java.net.*;
import java.util.*;
@@ -43,7 +45,7 @@
}
Object option;
Object testValue;
- };
+ }
// The tests set the option using the new API, read back the set value
// which could be diferent, and then use the legacy get API to check
@@ -223,8 +225,7 @@
} else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) {
return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT));
} else if (option.equals(StandardSocketOptions.IP_TOS)) {
- return Integer.valueOf(jdk.net.Sockets.getOption(
- socket, StandardSocketOptions.IP_TOS));
+ return getServerSocketTrafficClass(socket);
} else {
throw new RuntimeException("unexecpted socket option");
}
@@ -281,4 +282,20 @@
doDgSocketTests();
doMcSocketTests();
}
+
+ // Reflectively access jdk.net.Sockets.getOption so that the test can run
+ // without the jdk.net module.
+ static Object getServerSocketTrafficClass(ServerSocket ss) throws Exception {
+ try {
+ Class<?> c = Class.forName("jdk.net.Sockets");
+ Method m = c.getDeclaredMethod("getOption", ServerSocket.class, SocketOption.class);
+ return m.invoke(null, ss, StandardSocketOptions.IP_TOS);
+ } catch (ClassNotFoundException e) {
+ // Ok, jdk.net module not present, just fall back
+ System.out.println("jdk.net module not present, falling back.");
+ return Integer.valueOf(ss.getOption(StandardSocketOptions.IP_TOS));
+ } catch (ReflectiveOperationException e) {
+ throw new AssertionError(e);
+ }
+ }
}
--- a/jdk/test/java/net/SocketOption/UnsupportedOptionsTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/net/SocketOption/UnsupportedOptionsTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -21,34 +21,48 @@
* questions.
*/
-import jdk.net.ExtendedSocketOptions;
-
import java.io.IOException;
+import java.lang.reflect.Field;
import java.net.*;
+import java.util.ArrayList;
+import java.util.List;
/*
* @test
- * @bug 8143554
- * @run main UnsupportedOptionsTest
+ * @bug 8143554 8044773
* @summary Test checks that UnsupportedOperationException for unsupported
* SOCKET_OPTIONS is thrown by both getOption() and setOption() methods.
+ * @run main UnsupportedOptionsTest
+ * @run main/othervm -Djdk.launcher.limitmods=java.base UnsupportedOptionsTest
*/
+
public class UnsupportedOptionsTest {
- private static final SocketOption[] SOCKET_OPTIONS = {
- StandardSocketOptions.IP_MULTICAST_IF,
- StandardSocketOptions.IP_MULTICAST_LOOP,
- StandardSocketOptions.IP_MULTICAST_TTL,
- StandardSocketOptions.IP_TOS,
- StandardSocketOptions.SO_BROADCAST,
- StandardSocketOptions.SO_KEEPALIVE,
- StandardSocketOptions.SO_LINGER,
- StandardSocketOptions.SO_RCVBUF,
- StandardSocketOptions.SO_REUSEADDR,
- StandardSocketOptions.SO_SNDBUF,
- StandardSocketOptions.TCP_NODELAY,
- ExtendedSocketOptions.SO_FLOW_SLA
- };
+ private static final List<SocketOption<?>> socketOptions = new ArrayList<>();
+
+ static {
+ socketOptions.add(StandardSocketOptions.IP_MULTICAST_IF);
+ socketOptions.add(StandardSocketOptions.IP_MULTICAST_LOOP);
+ socketOptions.add(StandardSocketOptions.IP_MULTICAST_TTL);
+ socketOptions.add(StandardSocketOptions.IP_TOS);
+ socketOptions.add(StandardSocketOptions.SO_BROADCAST);
+ socketOptions.add(StandardSocketOptions.SO_KEEPALIVE);
+ socketOptions.add(StandardSocketOptions.SO_LINGER);
+ socketOptions.add(StandardSocketOptions.SO_RCVBUF);
+ socketOptions.add(StandardSocketOptions.SO_REUSEADDR);
+ socketOptions.add(StandardSocketOptions.SO_SNDBUF);
+ socketOptions.add(StandardSocketOptions.TCP_NODELAY);
+
+ try {
+ Class<?> c = Class.forName("jdk.net.ExtendedSocketOptions");
+ Field field = c.getField("SO_FLOW_SLA");
+ socketOptions.add((SocketOption<?>)field.get(null));
+ } catch (ClassNotFoundException e) {
+ // ignore, jdk.net module not present
+ } catch (ReflectiveOperationException e) {
+ throw new AssertionError(e);
+ }
+ }
public static void main(String[] args) throws IOException {
Socket s = new Socket();
@@ -56,7 +70,7 @@
DatagramSocket ds = new DatagramSocket();
MulticastSocket ms = new MulticastSocket();
- for (SocketOption option : SOCKET_OPTIONS) {
+ for (SocketOption option : socketOptions) {
if (!s.supportedOptions().contains(option)) {
testUnsupportedSocketOption(s, option);
}
--- a/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java Thu Apr 28 23:08:17 2016 -0700
@@ -22,8 +22,10 @@
*/
/* @test
- * @bug 4640544
+ * @bug 4640544 8044773
* @summary Unit test for setOption/getOption/options methods
+ * @run main SocketOptionTests
+ * @run main/othervm -Djdk.launcher.limitmods=java.base SocketOptionTests
*/
import java.nio.*;
--- a/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java Thu Apr 28 23:08:17 2016 -0700
@@ -22,9 +22,11 @@
*/
/* @test
- * @bug 4640544
+ * @bug 4640544 8044773
* @summary Unit test for ServerSocketChannel setOption/getOption/options
* methods.
+ * @run main SocketOptionTests
+ * @run main/othervm -Djdk.launcher.limitmods=java.base SocketOptionTests
*/
import java.nio.*;
--- a/jdk/test/java/nio/channels/SocketChannel/SocketOptionTests.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/nio/channels/SocketChannel/SocketOptionTests.java Thu Apr 28 23:08:17 2016 -0700
@@ -22,9 +22,11 @@
*/
/* @test
- * @bug 4640544
+ * @bug 4640544 8044773
* @summary Unit test to check SocketChannel setOption/getOption/options
* methods.
+ * @run main SocketOptionTests
+ * @run main/othervm -Djdk.launcher.limitmods=java.base SocketOptionTests
*/
import java.nio.*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/TEST.properties Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,1 @@
+modules = java.rmi
--- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Main.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Main.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
* @summary The Serialization benchmark test. This java class is used to run the
* test under JTREG.
* @library ../../
+ * @modules java.desktop
* @build bench.BenchInfo bench.HtmlReporter bench.Util bench.Benchmark
* @build bench.Reporter bench.XmlReporter bench.ConfigFormatException
* @build bench.Harness bench.TextReporter
--- a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -71,6 +71,7 @@
import java.text.ParsePosition;
import java.time.LocalDate;
+import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
@@ -661,6 +662,8 @@
{"W"},
{"W"},
+ {"g"},
+ {"ggggg"},
};
}
@@ -762,6 +765,37 @@
}
//-----------------------------------------------------------------------
+ @DataProvider(name="modJulianFieldPattern")
+ Object[][] data_modJuilanFieldPattern() {
+ return new Object[][] {
+ {"g", "1"},
+ {"g", "123456"},
+ {"gggggg", "123456"},
+ };
+ }
+
+ @Test(dataProvider="modJulianFieldPattern")
+ public void test_modJulianFieldPattern(String pattern, String input) throws Exception {
+ DateTimeFormatter.ofPattern(pattern).parse(input);
+ }
+
+ @DataProvider(name="modJulianFieldValues")
+ Object[][] data_modJuilanFieldValues() {
+ return new Object[][] {
+ {1970, 1, 1, "40587"},
+ {1858, 11, 17, "0"},
+ {1858, 11, 16, "-1"},
+ };
+ }
+
+ @Test(dataProvider="modJulianFieldValues")
+ public void test_modJulianFieldValues(int y, int m, int d, String expected) throws Exception {
+ DateTimeFormatter df = new DateTimeFormatterBuilder().appendPattern("g").toFormatter();
+ assertEquals(LocalDate.of(y, m, d).format(df), expected);
+ }
+
+
+ //-----------------------------------------------------------------------
@Test
public void test_adjacent_strict_firstFixedWidth() throws Exception {
// succeeds because both number elements are fixed width
@@ -897,7 +931,7 @@
@Test
public void test_adjacent_lenient_fractionFollows_0digit() throws Exception {
- // succeeds because hour/min are fixed width
+ // succeeds because hour, min and fraction of seconds are fixed width
DateTimeFormatter f = builder.parseLenient().appendValue(HOUR_OF_DAY, 2).appendValue(MINUTE_OF_HOUR, 2).appendFraction(NANO_OF_SECOND, 3, 3, false).toFormatter(Locale.UK);
ParsePosition pp = new ParsePosition(0);
TemporalAccessor parsed = f.parseUnresolved("1230", pp);
@@ -907,6 +941,21 @@
assertEquals(parsed.getLong(MINUTE_OF_HOUR), 30L);
}
+ @DataProvider(name="adjacentFractionParseData")
+ Object[][] data_adjacent_fraction_parse() {
+ return new Object[][] {
+ {"20130812214600025", "yyyyMMddHHmmssSSS", LocalDateTime.of(2013, 8, 12, 21, 46, 00, 25000000)},
+ {"201308122146000256", "yyyyMMddHHmmssSSSS", LocalDateTime.of(2013, 8, 12, 21, 46, 00, 25600000)},
+ };
+ }
+
+ @Test(dataProvider = "adjacentFractionParseData")
+ public void test_adjacent_fraction(String input, String pattern, LocalDateTime expected) {
+ DateTimeFormatter dtf = DateTimeFormatter.ofPattern(pattern);
+ LocalDateTime actual = LocalDateTime.parse(input, dtf);
+ assertEquals(actual, expected);
+ }
+
@DataProvider(name="lenientOffsetParseData")
Object[][] data_lenient_offset_parse() {
return new Object[][] {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/ServerName/BestEffortOnLazyConnected.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
+/**
+ * @test
+ * @bug 8144566
+ * @summary Custom HostnameVerifier disables SNI extension
+ * @run main/othervm BestEffortOnLazyConnected
+ */
+
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.util.*;
+import java.net.*;
+import javax.net.ssl.*;
+
+public class BestEffortOnLazyConnected {
+
+ /*
+ * =============================================================
+ * Set the various variables needed for the tests, then
+ * specify what tests to run on each side.
+ */
+
+ /*
+ * Should we run the client or server in a separate thread?
+ * Both sides can throw exceptions, but do you have a preference
+ * as to which side should be the main thread.
+ */
+ private static final boolean separateServerThread = true;
+
+ /*
+ * Where do we find the keystores?
+ */
+ private static final String pathToStores = "../etc";
+ private static final String keyStoreFile = "keystore";
+ private static final String trustStoreFile = "truststore";
+ private static final String passwd = "passphrase";
+
+ /*
+ * Is the server ready to serve?
+ */
+ private static volatile boolean serverReady = false;
+
+ /*
+ * Turn on SSL debugging?
+ */
+ private static final boolean debug = false;
+
+ /*
+ * the fully qualified domain name of localhost
+ */
+ private static String hostname = null;
+
+ /*
+ * If the client or server is doing some kind of object creation
+ * that the other side depends on, and that thread prematurely
+ * exits, you may experience a hang. The test harness will
+ * terminate all hung threads after its timeout has expired,
+ * currently 3 minutes by default, but you might try to be
+ * smart about it....
+ */
+
+ /*
+ * Define the server side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ private void doServerSide() throws Exception {
+ SSLServerSocketFactory sslssf =
+ (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
+ try (SSLServerSocket sslServerSocket =
+ (SSLServerSocket) sslssf.createServerSocket(serverPort)) {
+
+ serverPort = sslServerSocket.getLocalPort();
+
+ /*
+ * Signal Client, we're ready for his connect.
+ */
+ serverReady = true;
+
+ try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) {
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslIS.read();
+ sslOS.write(85);
+ sslOS.flush();
+
+ ExtendedSSLSession session =
+ (ExtendedSSLSession)sslSocket.getSession();
+ if (session.getRequestedServerNames().isEmpty()) {
+ throw new Exception("No expected Server Name Indication");
+ }
+ }
+ }
+ }
+
+ /*
+ * Define the client side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ private void doClientSide() throws Exception {
+
+ /*
+ * Wait for server to get started.
+ */
+ while (!serverReady) {
+ Thread.sleep(50);
+ }
+
+ SSLSocketFactory sslsf =
+ (SSLSocketFactory) SSLSocketFactory.getDefault();
+
+ try (SSLSocket sslSocket = (SSLSocket)sslsf.createSocket()) {
+
+ sslSocket.connect(new InetSocketAddress(hostname, serverPort), 0);
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslOS.write(280);
+ sslOS.flush();
+ sslIS.read();
+ }
+ }
+
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+
+ // use any free port by default
+ private volatile int serverPort = 0;
+
+ private volatile Exception serverException = null;
+ private volatile Exception clientException = null;
+
+ public static void main(String[] args) throws Exception {
+ String keyFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + keyStoreFile;
+ String trustFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + trustStoreFile;
+
+ System.setProperty("javax.net.ssl.keyStore", keyFilename);
+ System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+ System.setProperty("javax.net.ssl.trustStore", trustFilename);
+ System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+ if (debug) {
+ System.setProperty("javax.net.debug", "all");
+ }
+
+ try {
+ hostname = InetAddress.getLocalHost().getCanonicalHostName();
+ } catch (UnknownHostException uhe) {
+ System.out.println(
+ "Ignore the test as the local hostname cannot be determined");
+
+ return;
+ }
+
+ System.out.println(
+ "The fully qualified domain name of the local host is " +
+ hostname);
+ // Ignore the test if the hostname does not sound like a domain name.
+ if ((hostname == null) || hostname.isEmpty() ||
+ hostname.startsWith("localhost") ||
+ Character.isDigit(hostname.charAt(hostname.length() - 1))) {
+
+ System.out.println("Ignore the test as the local hostname " +
+ "cannot be determined as fully qualified domain name");
+
+ return;
+ }
+
+ /*
+ * Start the tests.
+ */
+ new BestEffortOnLazyConnected();
+ }
+
+ private Thread clientThread = null;
+ private Thread serverThread = null;
+
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ BestEffortOnLazyConnected() throws Exception {
+ try {
+ if (separateServerThread) {
+ startServer(true);
+ startClient(false);
+ } else {
+ startClient(true);
+ startServer(false);
+ }
+ } catch (Exception e) {
+ // swallow for now. Show later
+ }
+
+ /*
+ * Wait for other side to close down.
+ */
+ if (separateServerThread) {
+ serverThread.join();
+ } else {
+ clientThread.join();
+ }
+
+ /*
+ * When we get here, the test is pretty much over.
+ * Which side threw the error?
+ */
+ Exception local;
+ Exception remote;
+ String whichRemote;
+
+ if (separateServerThread) {
+ remote = serverException;
+ local = clientException;
+ whichRemote = "server";
+ } else {
+ remote = clientException;
+ local = serverException;
+ whichRemote = "client";
+ }
+
+ /*
+ * If both failed, return the curthread's exception, but also
+ * print the remote side Exception
+ */
+ if ((local != null) && (remote != null)) {
+ System.out.println(whichRemote + " also threw:");
+ remote.printStackTrace();
+ System.out.println();
+ throw local;
+ }
+
+ if (remote != null) {
+ throw remote;
+ }
+
+ if (local != null) {
+ throw local;
+ }
+ }
+
+ private void startServer(boolean newThread) throws Exception {
+ if (newThread) {
+ serverThread = new Thread() {
+ public void run() {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ /*
+ * Our server thread just died.
+ *
+ * Release the client, if not active already...
+ */
+ System.err.println("Server died...");
+ serverReady = true;
+ serverException = e;
+ }
+ }
+ };
+ serverThread.start();
+ } else {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ serverException = e;
+ } finally {
+ serverReady = true;
+ }
+ }
+ }
+
+ private void startClient(boolean newThread) throws Exception {
+ if (newThread) {
+ clientThread = new Thread() {
+ public void run() {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ /*
+ * Our client thread just died.
+ */
+ System.err.println("Client died...");
+ clientException = e;
+ }
+ }
+ };
+ clientThread.start();
+ } else {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ clientException = e;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/net/SocketFlow/SocketFlowBasic.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8765432
+ * @summary Basic test for SocketFlow API
+ * @run testng SocketFlowBasic
+ */
+
+import jdk.net.SocketFlow;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import static jdk.net.SocketFlow.*;
+import static org.testng.Assert.*;
+
+public class SocketFlowBasic {
+
+ @DataProvider
+ public Object[][] validPriorities() {
+ return new Object[][] { {HIGH_PRIORITY}, {NORMAL_PRIORITY} };
+ }
+
+ @Test(dataProvider = "validPriorities")
+ public void priority(long validPriority) {
+ SocketFlow flow = SocketFlow.create();
+ flow.bandwidth(validPriority);
+ long bandwidth = flow.bandwidth();
+ assertTrue(bandwidth == validPriority, "Expected " + validPriority + ", got" + bandwidth);
+ }
+
+ @DataProvider
+ public Object[][] invalidPriorities() {
+ return new Object[][] { {HIGH_PRIORITY+10}, {NORMAL_PRIORITY-10000} };
+ }
+
+ @Test(dataProvider = "invalidPriorities", expectedExceptions = IllegalArgumentException.class)
+ public void priority(int invalidPriority) {
+ SocketFlow flow = SocketFlow.create();
+ flow.priority(invalidPriority);
+ }
+
+ @DataProvider
+ public Object[][] positiveBandwidth() {
+ return new Object[][] { {0}, {100}, {Integer.MAX_VALUE}, {Long.MAX_VALUE} };
+ }
+
+ @Test(dataProvider = "positiveBandwidth")
+ public void bandwidth(long posBandwidth) {
+ SocketFlow flow = SocketFlow.create();
+ flow.bandwidth(posBandwidth);
+ long bandwidth = flow.bandwidth();
+ assertTrue(bandwidth == posBandwidth, "Expected " + posBandwidth + ", got" + bandwidth);
+ }
+
+
+ @DataProvider
+ public Object[][] negativeBandwidth() {
+ return new Object[][] { {-1}, {-100}, {Integer.MIN_VALUE}, {Long.MIN_VALUE} };
+ }
+
+ @Test(dataProvider = "negativeBandwidth", expectedExceptions = IllegalArgumentException.class)
+ public void invalidBandwidth(long negBandwidth) {
+ SocketFlow flow = SocketFlow.create();
+ flow.bandwidth(negBandwidth);
+ }
+
+ @Test
+ public void status() {
+ SocketFlow flow = SocketFlow.create();
+ assertTrue(flow.status() == Status.NO_STATUS);
+ }
+}
--- a/jdk/test/jdk/net/Sockets/Test.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/jdk/net/Sockets/Test.java Thu Apr 28 23:08:17 2016 -0700
@@ -23,8 +23,9 @@
/*
* @test
- * @bug 8032808
- * @run main/othervm -Xcheck:jni Test
+ * @bug 8032808 8044773
+ * @modules jdk.net
+ * @run main/othervm -Xcheck:jni Test success
* @run main/othervm/policy=policy.fail -Xcheck:jni Test fail
* @run main/othervm/policy=policy.success -Xcheck:jni Test success
*/
@@ -35,15 +36,13 @@
import java.util.concurrent.*;
import java.util.Set;
import jdk.net.*;
+import static java.lang.System.out;
public class Test {
- static boolean security;
- static boolean success;
+ interface Runner { void run() throws Exception; }
- interface Runner {
- public void run() throws Exception;
- }
+ static boolean expectSuccess;
public static void main(String[] args) throws Exception {
@@ -52,95 +51,107 @@
Sockets.supportedOptions(Socket.class);
- security = System.getSecurityManager() != null;
- success = security && args[0].equals("success");
+ expectSuccess = args[0].equals("success");
// Main thing is to check for JNI problems
// Doesn't matter if current system does not support the option
// and currently setting the option with the loopback interface
// doesn't work either
- System.out.println ("Security Manager enabled: " + security);
- if (security) {
- System.out.println ("Success expected: " + success);
- }
+ boolean sm = System.getSecurityManager() != null;
+ out.println("Security Manager enabled: " + sm);
+ out.println("Success expected: " + expectSuccess);
- final SocketFlow flowIn = SocketFlow.create()
- .bandwidth(1000)
- .priority(SocketFlow.HIGH_PRIORITY);
+ SocketFlow flowIn = SocketFlow.create()
+ .bandwidth(1000)
+ .priority(SocketFlow.HIGH_PRIORITY);
- ServerSocket ss = new ServerSocket(0);
- int tcp_port = ss.getLocalPort();
- final InetAddress loop = InetAddress.getByName("127.0.0.1");
- final InetSocketAddress loopad = new InetSocketAddress(loop, tcp_port);
+ try (ServerSocket ss = new ServerSocket(0);
+ DatagramSocket dg = new DatagramSocket(0)) {
- DatagramSocket dg = new DatagramSocket(0);
- final int udp_port = dg.getLocalPort();
+ int tcp_port = ss.getLocalPort();
+ final InetAddress loop = InetAddress.getByName("127.0.0.1");
+ final InetSocketAddress loopad = new InetSocketAddress(loop, tcp_port);
+
+ final int udp_port = dg.getLocalPort();
- // If option not available, end test
- Set<SocketOption<?>> options = dg.supportedOptions();
- if (!options.contains(ExtendedSocketOptions.SO_FLOW_SLA)) {
- System.out.println("SO_FLOW_SLA not supported");
- return;
- }
+ // If option not available, end test
+ Set<SocketOption<?>> options = dg.supportedOptions();
+ if (!options.contains(ExtendedSocketOptions.SO_FLOW_SLA)) {
+ System.out.println("SO_FLOW_SLA not supported");
+ return;
+ }
- final Socket s = new Socket("127.0.0.1", tcp_port);
- final SocketChannel sc = SocketChannel.open();
- sc.connect (new InetSocketAddress("127.0.0.1", tcp_port));
+ final Socket s = new Socket("127.0.0.1", tcp_port);
+ final SocketChannel sc = SocketChannel.open();
+ sc.connect(new InetSocketAddress("127.0.0.1", tcp_port));
- doTest(()->{
- Sockets.setOption(s, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
- });
- doTest(()->{
- Sockets.getOption(s, ExtendedSocketOptions.SO_FLOW_SLA);
- });
- doTest(()->{
- sc.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
- });
- doTest(()->{
- sc.getOption(ExtendedSocketOptions.SO_FLOW_SLA);
- });
- doTest(()->{
- DatagramSocket dg1 = new DatagramSocket(0);
- dg1.connect(loop, udp_port);
- Sockets.setOption(dg1, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
- });
- doTest(()->{
- DatagramChannel dg2 = DatagramChannel.open();
- dg2.bind(new InetSocketAddress(loop, 0));
- dg2.connect(new InetSocketAddress(loop, udp_port));
- dg2.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
- });
- doTest(()->{
- MulticastSocket mc1 = new MulticastSocket(0);
- mc1.connect(loop, udp_port);
- Sockets.setOption(mc1, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
- });
- doTest(()->{
- AsynchronousSocketChannel asc = AsynchronousSocketChannel.open();
- Future<Void> f = asc.connect(loopad);
- f.get();
- asc.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
- });
+ doTest("Sockets.setOption Socket", () -> {
+ out.println(flowIn);
+ Sockets.setOption(s, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+ out.println(flowIn);
+ });
+ doTest("Sockets.getOption Socket",() -> {
+ Sockets.getOption(s, ExtendedSocketOptions.SO_FLOW_SLA);
+ out.println(flowIn);
+ });
+ doTest("Sockets.setOption SocketChannel",() ->
+ sc.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn)
+ );
+ doTest("Sockets.getOption SocketChannel",() ->
+ sc.getOption(ExtendedSocketOptions.SO_FLOW_SLA)
+ );
+ doTest("Sockets.setOption DatagramSocket",() -> {
+ try (DatagramSocket dg1 = new DatagramSocket(0)) {
+ dg1.connect(loop, udp_port);
+ Sockets.setOption(dg1, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+ }
+ });
+ doTest("Sockets.setOption DatagramSocket 2", () -> {
+ try (DatagramChannel dg2 = DatagramChannel.open()) {
+ dg2.bind(new InetSocketAddress(loop, 0));
+ dg2.connect(new InetSocketAddress(loop, udp_port));
+ dg2.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+ }
+ });
+ doTest("Sockets.setOption MulticastSocket", () -> {
+ try (MulticastSocket mc1 = new MulticastSocket(0)) {
+ mc1.connect(loop, udp_port);
+ Sockets.setOption(mc1, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+ }
+ });
+ doTest("Sockets.setOption AsynchronousSocketChannel", () -> {
+ try (AsynchronousSocketChannel asc = AsynchronousSocketChannel.open()) {
+ Future<Void> f = asc.connect(loopad);
+ f.get();
+ asc.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+ }
+ });
+ }
}
- static void doTest(Runner func) throws Exception {
+ static void doTest(String message, Runner func) throws Exception {
+ out.println(message);
try {
func.run();
- if (security && !success) {
- throw new RuntimeException("Test failed");
+ if (expectSuccess) {
+ out.println("Completed as expected");
+ } else {
+ throw new RuntimeException("Operation succeeded, but expected SecurityException");
}
} catch (SecurityException e) {
- if (success) {
- throw new RuntimeException("Test failed");
+ if (expectSuccess) {
+ throw new RuntimeException("Unexpected SecurityException", e);
+ } else {
+ out.println("Caught expected: " + e);
}
} catch (UnsupportedOperationException e) {
- System.out.println (e);
+ System.out.println(e);
} catch (IOException e) {
// Probably a permission error, but we're not
// going to check unless a specific permission exception
// is defined.
- System.out.println (e);
+ System.out.println(e);
}
}
}
--- a/jdk/test/sanity/client/SwingSet/src/ButtonDemoScreenshotTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sanity/client/SwingSet/src/ButtonDemoScreenshotTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -21,6 +21,8 @@
* questions.
*/
+import com.sun.swingset3.demos.button.ButtonDemo;
+import org.jtregext.GuiTestListener;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.InputEvent;
@@ -32,6 +34,7 @@
import static org.jemmy2ext.JemmyExt.*;
import org.testng.annotations.Test;
import static com.sun.swingset3.demos.button.ButtonDemo.*;
+import org.testng.annotations.Listeners;
/*
* @test
@@ -41,31 +44,30 @@
* image is different from initial button image.
*
* @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.button.ButtonDemo
* @run testng ButtonDemoScreenshotTest
*/
+@Listeners(GuiTestListener.class)
public class ButtonDemoScreenshotTest {
private static final int BUTTON_COUNT = 6; // TODO: Decide about "open browser" buttons (value was 8 originally)
@Test
public void test() throws Exception {
- captureDebugInfoOnFail(() -> {
- Robot rob = new Robot();
+ Robot rob = new Robot();
- new ClassReference(com.sun.swingset3.demos.button.ButtonDemo.class.getCanonicalName()).startApplication();
+ new ClassReference(ButtonDemo.class.getCanonicalName()).startApplication();
- JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
- waitImageIsStill(rob, mainFrame);
+ JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
+ waitImageIsStill(rob, mainFrame);
- // Check all the buttons
- for (int i = 0; i < BUTTON_COUNT; i++) {
- checkButton(mainFrame, i, rob);
- }
- });
+ // Check all the buttons
+ for (int i = 0; i < BUTTON_COUNT; i++) {
+ checkButton(mainFrame, i, rob);
+ }
}
public void checkButton(JFrameOperator jfo, int i, Robot rob) {
--- a/jdk/test/sanity/client/SwingSet/src/ButtonDemoTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sanity/client/SwingSet/src/ButtonDemoTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -21,6 +21,7 @@
* questions.
*/
+import org.jtregext.GuiTestListener;
import com.sun.swingset3.demos.JHyperlink;
import com.sun.swingset3.demos.button.ButtonDemo;
import java.util.concurrent.ArrayBlockingQueue;
@@ -38,7 +39,7 @@
import static com.sun.swingset3.demos.button.ButtonDemo.*;
import org.jemmy2ext.JemmyExt;
import org.jemmy2ext.JemmyExt.MultiThreadedTryCatch;
-import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+import org.testng.annotations.Listeners;
/*
* @test
@@ -48,12 +49,13 @@
* on buttons before and after click.
*
* @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.button.ButtonDemo
* @run testng ButtonDemoTest
*/
+@Listeners(GuiTestListener.class)
public class ButtonDemoTest {
private static final String[] BUTTON_TEXT_AFTER = {
@@ -92,34 +94,30 @@
@Test
public void test() throws Exception {
- captureDebugInfoOnFail(() -> {
-
- new ClassReference(ButtonDemo.class.getCanonicalName()).startApplication();
+ new ClassReference(ButtonDemo.class.getCanonicalName()).startApplication();
- JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
- mainFrame.setComparator(EXACT_STRING_COMPARATOR);
-
- // Check all the buttons
- for (int i = 0; i < BUTTON_TOOLTIP.length; i++) {
- String tooltip = BUTTON_TOOLTIP[i];
-
- JButtonOperator button = new JButtonOperator(mainFrame, new ByToolTipChooser(tooltip));
+ JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
+ mainFrame.setComparator(EXACT_STRING_COMPARATOR);
- assertEquals(BUTTON_TEXT_BEFORE[i], button.getText());
+ // Check all the buttons
+ for (int i = 0; i < BUTTON_TOOLTIP.length; i++) {
+ String tooltip = BUTTON_TOOLTIP[i];
+
+ JButtonOperator button = new JButtonOperator(mainFrame, new ByToolTipChooser(tooltip));
- // Two buttons are hyperlinks, we don't want to click them
- if (!button.getSource().getClass().equals(JHyperlink.class)) {
- checkButton(button);
- }
+ assertEquals(BUTTON_TEXT_BEFORE[i], button.getText());
- if (BUTTON_TEXT_AFTER.length > i) {
- assertEquals(BUTTON_TEXT_AFTER[i], button.getText());
- } else {
- assertEquals(BUTTON_TEXT_BEFORE[i], button.getText());
- }
+ // Two buttons are hyperlinks, we don't want to click them
+ if (!button.getSource().getClass().equals(JHyperlink.class)) {
+ checkButton(button);
}
- });
+ if (BUTTON_TEXT_AFTER.length > i) {
+ assertEquals(BUTTON_TEXT_AFTER[i], button.getText());
+ } else {
+ assertEquals(BUTTON_TEXT_BEFORE[i], button.getText());
+ }
+ }
}
private void checkButton(JButtonOperator button) throws Exception {
--- a/jdk/test/sanity/client/SwingSet/src/ComboBoxDemoTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sanity/client/SwingSet/src/ComboBoxDemoTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -21,6 +21,7 @@
* questions.
*/
+import org.jtregext.GuiTestListener;
import com.sun.swingset3.demos.combobox.ComboBoxDemo;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.Test;
@@ -28,7 +29,7 @@
import org.netbeans.jemmy.operators.JComboBoxOperator;
import org.netbeans.jemmy.operators.JFrameOperator;
import static com.sun.swingset3.demos.combobox.ComboBoxDemo.*;
-import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+import org.testng.annotations.Listeners;
/*
* @test
@@ -37,12 +38,13 @@
* each value of each ComboBox.
*
* @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.combobox.ComboBoxDemo
* @run testng ComboBoxDemoTest
*/
+@Listeners(GuiTestListener.class)
public class ComboBoxDemoTest {
private static enum ComboBoxInfo {
@@ -61,14 +63,13 @@
@Test
public void test() throws Exception {
- captureDebugInfoOnFail(() -> {
- new ClassReference(ComboBoxDemo.class.getCanonicalName()).startApplication();
+
+ new ClassReference(ComboBoxDemo.class.getCanonicalName()).startApplication();
- JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
- for (ComboBoxInfo comboBoxInfo : ComboBoxInfo.values()) {
- comboBoxChecker(frame, comboBoxInfo);
- }
- });
+ JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+ for (ComboBoxInfo comboBoxInfo : ComboBoxInfo.values()) {
+ comboBoxChecker(frame, comboBoxInfo);
+ }
}
private void comboBoxChecker(JFrameOperator jfo, ComboBoxInfo comboBoxInfo) {
--- a/jdk/test/sanity/client/SwingSet/src/ListDemoTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sanity/client/SwingSet/src/ListDemoTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -21,6 +21,7 @@
* questions.
*/
+import org.jtregext.GuiTestListener;
import com.sun.swingset3.demos.list.ListDemo;
import static com.sun.swingset3.demos.list.ListDemo.DEMO_TITLE;
import static org.testng.AssertJUnit.*;
@@ -30,7 +31,7 @@
import org.netbeans.jemmy.operators.JCheckBoxOperator;
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JListOperator;
-import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+import org.testng.annotations.Listeners;
/*
* @test
@@ -40,64 +41,64 @@
* list.
*
* @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.list.ListDemo
* @run testng ListDemoTest
*/
+@Listeners(GuiTestListener.class)
public class ListDemoTest {
private static final int CHECKBOX_COUNT = 50;
@Test
public void test() throws Exception {
- captureDebugInfoOnFail(() -> {
- new ClassReference(ListDemo.class.getCanonicalName()).startApplication();
+
+ new ClassReference(ListDemo.class.getCanonicalName()).startApplication();
+
+ JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+ JListOperator listOp = new JListOperator(frame);
+
+ // Check *NO* Prefix and Suffixes Marked
+ for (int i = 0; i < CHECKBOX_COUNT; i++) {
+ JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
+ checkBox.changeSelection(false);
+ }
+ System.out.println("######## Number of Items = " + listOp.getModel().getSize());
+ assertEquals("Select None number of items is correct", 0, listOp.getModel().getSize());
- JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
- JListOperator listOp = new JListOperator(frame);
+ // Check *ALL* Prefix and Suffixes Marked
+ for (int i = 0; i < CHECKBOX_COUNT; i++) {
+ JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
+ checkBox.changeSelection(true);
+ }
+ System.out.println("######## Number of Items = " + listOp.getModel().getSize());
+ assertEquals("Select All number of items is correct", CHECKBOX_COUNT / 2 * CHECKBOX_COUNT / 2, listOp.getModel().getSize());
- // Check *NO* Prefix and Suffixes Marked
- for (int i = 0; i < CHECKBOX_COUNT; i++) {
- JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
+ // Check *ALL* Prefix and *NO* Suffixes Marked
+ for (int i = 0; i < CHECKBOX_COUNT; i++) {
+ JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
+ if (i < CHECKBOX_COUNT / 2) {
+ checkBox.changeSelection(true);
+ } else {
checkBox.changeSelection(false);
}
- System.out.println("######## Number of Items = " + listOp.getModel().getSize());
- assertEquals("Select None number of items is correct", 0, listOp.getModel().getSize());
+ }
+ System.out.println("######## Number of Items = " + listOp.getModel().getSize());
+ assertEquals("Select All Prefixes and NO Suffixes number of items is correct", 0, listOp.getModel().getSize());
- // Check *ALL* Prefix and Suffixes Marked
- for (int i = 0; i < CHECKBOX_COUNT; i++) {
- JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
+ // Check *NO* Prefix and *ALL* Suffixes Marked
+ for (int i = 0; i < CHECKBOX_COUNT; i++) {
+ JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
+ if (i < CHECKBOX_COUNT / 2) {
+ checkBox.changeSelection(false);
+ } else {
checkBox.changeSelection(true);
}
- System.out.println("######## Number of Items = " + listOp.getModel().getSize());
- assertEquals("Select All number of items is correct", CHECKBOX_COUNT / 2 * CHECKBOX_COUNT / 2, listOp.getModel().getSize());
-
- // Check *ALL* Prefix and *NO* Suffixes Marked
- for (int i = 0; i < CHECKBOX_COUNT; i++) {
- JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
- if (i < CHECKBOX_COUNT / 2) {
- checkBox.changeSelection(true);
- } else {
- checkBox.changeSelection(false);
- }
- }
- System.out.println("######## Number of Items = " + listOp.getModel().getSize());
- assertEquals("Select All Prefixes and NO Suffixes number of items is correct", 0, listOp.getModel().getSize());
-
- // Check *NO* Prefix and *ALL* Suffixes Marked
- for (int i = 0; i < CHECKBOX_COUNT; i++) {
- JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
- if (i < CHECKBOX_COUNT / 2) {
- checkBox.changeSelection(false);
- } else {
- checkBox.changeSelection(true);
- }
- }
- System.out.println("######## Number of Items = " + listOp.getModel().getSize());
- assertEquals("Select NO Prefixes and All Suffixes number of items is correct", 0, listOp.getModel().getSize());
- });
+ }
+ System.out.println("######## Number of Items = " + listOp.getModel().getSize());
+ assertEquals("Select NO Prefixes and All Suffixes number of items is correct", 0, listOp.getModel().getSize());
}
private JCheckBoxOperator getJCheckBoxOperator(JFrameOperator frame, int index) {
--- a/jdk/test/sanity/client/SwingSet/src/OptionPaneDemoTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sanity/client/SwingSet/src/OptionPaneDemoTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -21,10 +21,10 @@
* questions.
*/
+import org.jtregext.GuiTestListener;
import com.sun.swingset3.demos.optionpane.OptionPaneDemo;
import static com.sun.swingset3.demos.optionpane.OptionPaneDemo.*;
import javax.swing.UIManager;
-import static org.jemmy2ext.JemmyExt.*;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.Test;
import org.netbeans.jemmy.ClassReference;
@@ -34,6 +34,7 @@
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JLabelOperator;
import org.netbeans.jemmy.operators.JTextFieldOperator;
+import org.testng.annotations.Listeners;
/*
@@ -43,12 +44,13 @@
* and choosing different options in them.
*
* @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.optionpane.OptionPaneDemo
* @run testng OptionPaneDemoTest
*/
+@Listeners(GuiTestListener.class)
public class OptionPaneDemoTest {
public static final String SOME_TEXT_TO_TYPE = "I am some text";
@@ -59,21 +61,20 @@
public static final String TEXT_TO_TYPE = "Hooray! I'm a textField";
public static final String NO = "No";
public static final String YES = "Yes";
- public static final String SELECT_AN__OPTION = UIManager.getString("OptionPane.titleText");
+ public static final String SELECT_AN_OPTION = UIManager.getString("OptionPane.titleText");
@Test
public void test() throws Exception {
- captureDebugInfoOnFail(() -> {
- new ClassReference(OptionPaneDemo.class.getCanonicalName()).startApplication();
- JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+ new ClassReference(OptionPaneDemo.class.getCanonicalName()).startApplication();
+
+ JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
- showInputDialog(frame);
- showWarningDialog(frame);
- showMessageDialog(frame);
- showComponentDialog(frame);
- showConfirmationDialog(frame);
- });
+ showInputDialog(frame);
+ showWarningDialog(frame);
+ showMessageDialog(frame);
+ showComponentDialog(frame);
+ showConfirmationDialog(frame);
}
public void showInputDialog(JFrameOperator jfo) throws Exception {
@@ -286,7 +287,7 @@
{
new JButtonOperator(jfo, CONFIRM_BUTTON).pushNoBlock();
- JDialogOperator jdo = new JDialogOperator(SELECT_AN__OPTION);
+ JDialogOperator jdo = new JDialogOperator(SELECT_AN_OPTION);
new JButtonOperator(jdo, YES).pushNoBlock();
JDialogOperator jdo1 = new JDialogOperator(MESSAGE);
@@ -306,7 +307,7 @@
{
new JButtonOperator(jfo, CONFIRM_BUTTON).pushNoBlock();
- JDialogOperator jdo = new JDialogOperator(SELECT_AN__OPTION);
+ JDialogOperator jdo = new JDialogOperator(SELECT_AN_OPTION);
new JButtonOperator(jdo, NO).pushNoBlock();
JDialogOperator jdo1 = new JDialogOperator(MESSAGE);
@@ -326,7 +327,7 @@
{
new JButtonOperator(jfo, CONFIRM_BUTTON).pushNoBlock();
- JDialogOperator jdo = new JDialogOperator(SELECT_AN__OPTION);
+ JDialogOperator jdo = new JDialogOperator(SELECT_AN_OPTION);
assertTrue("Show Confirmation Dialog Cancel Option", jdo.isShowing());
--- a/jdk/test/sanity/client/SwingSet/src/ProgressBarDemoTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sanity/client/SwingSet/src/ProgressBarDemoTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -21,6 +21,7 @@
* questions.
*/
+import org.jtregext.GuiTestListener;
import com.sun.swingset3.demos.progressbar.ProgressBarDemo;
import static com.sun.swingset3.demos.progressbar.ProgressBarDemo.*;
import java.awt.Component;
@@ -31,7 +32,7 @@
import org.netbeans.jemmy.operators.JButtonOperator;
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JProgressBarOperator;
-import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+import org.testng.annotations.Listeners;
/*
* @test
@@ -40,31 +41,31 @@
* buttons and checking the progress bar and the buttons state.
*
* @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.progressbar.ProgressBarDemo
* @run testng ProgressBarDemoTest
*/
+@Listeners(GuiTestListener.class)
public class ProgressBarDemoTest {
@Test
public void test() throws Exception {
- captureDebugInfoOnFail(() -> {
- new ClassReference(ProgressBarDemo.class.getCanonicalName()).startApplication();
- JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+ new ClassReference(ProgressBarDemo.class.getCanonicalName()).startApplication();
+
+ JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
- JButtonOperator startButton = new JButtonOperator(frame, START_BUTTON);
- JButtonOperator stopButton = new JButtonOperator(frame, STOP_BUTTON);
- JProgressBarOperator jpbo = new JProgressBarOperator(frame);
+ JButtonOperator startButton = new JButtonOperator(frame, START_BUTTON);
+ JButtonOperator stopButton = new JButtonOperator(frame, STOP_BUTTON);
+ JProgressBarOperator jpbo = new JProgressBarOperator(frame);
- // Check that progress completes and corect enable/disable of start/stop buttons
- checkCompleteProgress(frame, startButton, stopButton, jpbo);
+ // Check that progress completes and corect enable/disable of start/stop buttons
+ checkCompleteProgress(frame, startButton, stopButton, jpbo);
- // Check progess bar progression and start/stop button disabled/enabled states
- checkStartStop(frame, startButton, stopButton, jpbo);
- });
+ // Check progess bar progression and start/stop button disabled/enabled states
+ checkStartStop(frame, startButton, stopButton, jpbo);
}
// Check that progress completes and corect enable/disable of start/stop buttons
--- a/jdk/test/sanity/client/SwingSet/src/ScrollPaneDemoTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sanity/client/SwingSet/src/ScrollPaneDemoTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -21,6 +21,7 @@
* questions.
*/
+import org.jtregext.GuiTestListener;
import com.sun.swingset3.demos.scrollpane.ScrollPaneDemo;
import static com.sun.swingset3.demos.scrollpane.ScrollPaneDemo.DEMO_TITLE;
import static org.testng.AssertJUnit.*;
@@ -28,7 +29,7 @@
import org.netbeans.jemmy.ClassReference;
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JScrollPaneOperator;
-import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+import org.testng.annotations.Listeners;
/*
* @test
@@ -37,73 +38,73 @@
* to left and to right and checking scroll bar values.
*
* @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.scrollpane.ScrollPaneDemo
* @run testng ScrollPaneDemoTest
*/
+@Listeners(GuiTestListener.class)
public class ScrollPaneDemoTest {
@Test
public void test() throws Exception {
- captureDebugInfoOnFail(() -> {
- new ClassReference(ScrollPaneDemo.class.getName()).startApplication();
+
+ new ClassReference(ScrollPaneDemo.class.getName()).startApplication();
- JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
- JScrollPaneOperator jspo = new JScrollPaneOperator(frame);
+ JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+ JScrollPaneOperator jspo = new JScrollPaneOperator(frame);
- // Set initial scrollbar positions
- int initialVerticalValue = jspo.getVerticalScrollBar().getValue();
- int initialHorizontalValue = jspo.getHorizontalScrollBar().getValue();
+ // Set initial scrollbar positions
+ int initialVerticalValue = jspo.getVerticalScrollBar().getValue();
+ int initialHorizontalValue = jspo.getHorizontalScrollBar().getValue();
- System.out.println("Initial Vertical Value = " + jspo.getVerticalScrollBar().getValue());
- System.out.println("Initial HoriZontal Value = " + jspo.getHorizontalScrollBar().getValue());
+ System.out.println("Initial Vertical Value = " + jspo.getVerticalScrollBar().getValue());
+ System.out.println("Initial HoriZontal Value = " + jspo.getHorizontalScrollBar().getValue());
- // Check scroll to Bottom
- {
- jspo.scrollToBottom();
- int currentValue = jspo.getVerticalScrollBar().getValue();
- System.out.println("Final Value = " + currentValue);
- assertTrue("Scroll to Bottom of Pane "
- + "(initialVerticalValue, actual value: " + initialVerticalValue + " "
- + "< currentValue, actual value = " + currentValue + ")",
- initialVerticalValue < currentValue);
- }
+ // Check scroll to Bottom
+ {
+ jspo.scrollToBottom();
+ int currentValue = jspo.getVerticalScrollBar().getValue();
+ System.out.println("Final Value = " + currentValue);
+ assertTrue("Scroll to Bottom of Pane "
+ + "(initialVerticalValue, actual value: " + initialVerticalValue + " "
+ + "< currentValue, actual value = " + currentValue + ")",
+ initialVerticalValue < currentValue);
+ }
- // Check scroll to Top
- {
- jspo.scrollToTop();
- int currentValue = jspo.getVerticalScrollBar().getValue();
- System.out.println("Top Scroll Final Value = " + currentValue);
- assertTrue("Scroll to Top of Pane "
- + "(initialVerticalValue, actual value: " + initialVerticalValue + " "
- + "> currentValue, actual value = " + currentValue + ")",
- initialVerticalValue > currentValue);
- }
+ // Check scroll to Top
+ {
+ jspo.scrollToTop();
+ int currentValue = jspo.getVerticalScrollBar().getValue();
+ System.out.println("Top Scroll Final Value = " + currentValue);
+ assertTrue("Scroll to Top of Pane "
+ + "(initialVerticalValue, actual value: " + initialVerticalValue + " "
+ + "> currentValue, actual value = " + currentValue + ")",
+ initialVerticalValue > currentValue);
+ }
- // Check scroll to Left
- {
- jspo.scrollToLeft();
- int currentValue = jspo.getHorizontalScrollBar().getValue();
- System.out.println("Scroll to Left Final Value = " + currentValue);
- assertTrue("Scroll to Left of Pane "
- + "(initialHorizontalValue, actual value: " + initialHorizontalValue + " "
- + "> currentValue, actual value = " + currentValue + ")",
- initialHorizontalValue > currentValue);
- }
+ // Check scroll to Left
+ {
+ jspo.scrollToLeft();
+ int currentValue = jspo.getHorizontalScrollBar().getValue();
+ System.out.println("Scroll to Left Final Value = " + currentValue);
+ assertTrue("Scroll to Left of Pane "
+ + "(initialHorizontalValue, actual value: " + initialHorizontalValue + " "
+ + "> currentValue, actual value = " + currentValue + ")",
+ initialHorizontalValue > currentValue);
+ }
- // Check scroll to Right
- {
- jspo.scrollToRight();
- int currentValue = jspo.getHorizontalScrollBar().getValue();
- System.out.println("Scroll to Right Final Value = " + currentValue);
- assertTrue("Scroll to Right of Pane "
- + "(initialHorizontalValue, actual value: " + initialHorizontalValue + " "
- + "< currentValue, actual value = " + currentValue + ")",
- initialHorizontalValue < currentValue);
- }
- });
+ // Check scroll to Right
+ {
+ jspo.scrollToRight();
+ int currentValue = jspo.getHorizontalScrollBar().getValue();
+ System.out.println("Scroll to Right Final Value = " + currentValue);
+ assertTrue("Scroll to Right of Pane "
+ + "(initialHorizontalValue, actual value: " + initialHorizontalValue + " "
+ + "< currentValue, actual value = " + currentValue + ")",
+ initialHorizontalValue < currentValue);
+ }
}
}
--- a/jdk/test/sanity/client/SwingSet/src/SpinnerDemoTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sanity/client/SwingSet/src/SpinnerDemoTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -21,6 +21,7 @@
* questions.
*/
+import org.jtregext.GuiTestListener;
import com.sun.swingset3.demos.spinner.SpinnerDemo;
import static com.sun.swingset3.demos.spinner.SpinnerDemo.DEMO_TITLE;
import java.text.DecimalFormat;
@@ -30,7 +31,7 @@
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JSpinnerOperator;
import org.netbeans.jemmy.operators.JTextFieldOperator;
-import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+import org.testng.annotations.Listeners;
/*
* @test
@@ -39,12 +40,13 @@
* the spinner button and checking text field value.
*
* @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.spinner.SpinnerDemo
* @run testng SpinnerDemoTest
*/
+@Listeners(GuiTestListener.class)
public class SpinnerDemoTest {
private static final int SPINNERS_COUNT = 9;
@@ -52,16 +54,14 @@
@Test
public void test() throws Exception {
- captureDebugInfoOnFail(() -> {
- new ClassReference(SpinnerDemo.class.getCanonicalName()).startApplication();
+ new ClassReference(SpinnerDemo.class.getCanonicalName()).startApplication();
- JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+ JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
- // Check changing different spinners
- for (int i = 0; i < SPINNERS_COUNT; i++) {
- changeValues(frame, i);
- }
- });
+ // Check changing different spinners
+ for (int i = 0; i < SPINNERS_COUNT; i++) {
+ changeValues(frame, i);
+ }
}
private void changeValues(JFrameOperator jfo, int spinnerIndex) throws Exception {
--- a/jdk/test/sanity/client/SwingSet/src/SplitPaneDemoTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sanity/client/SwingSet/src/SplitPaneDemoTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -21,6 +21,7 @@
* questions.
*/
+import org.jtregext.GuiTestListener;
import com.sun.swingset3.demos.splitpane.SplitPaneDemo;
import static com.sun.swingset3.demos.splitpane.SplitPaneDemo.*;
import java.awt.event.KeyEvent;
@@ -35,6 +36,7 @@
import org.netbeans.jemmy.operators.JSplitPaneOperator;
import org.netbeans.jemmy.operators.JTextFieldOperator;
import static org.jemmy2ext.JemmyExt.*;
+import org.testng.annotations.Listeners;
/*
* @test
@@ -44,39 +46,39 @@
* and changing the divider orientation.
*
* @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.splitpane.SplitPaneDemo
* @run testng SplitPaneDemoTest
*/
+@Listeners(GuiTestListener.class)
public class SplitPaneDemoTest {
@Test
public void test() throws Exception {
- captureDebugInfoOnFail(() -> {
- new ClassReference(SplitPaneDemo.class.getCanonicalName()).startApplication();
- JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+ new ClassReference(SplitPaneDemo.class.getCanonicalName()).startApplication();
+
+ JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
- JSplitPaneOperator splitPane = new JSplitPaneOperator(frame);
+ JSplitPaneOperator splitPane = new JSplitPaneOperator(frame);
- // Toggle OneTouch Expandable
- checkOneTouch(frame, splitPane, true);
- checkOneTouch(frame, splitPane, false);
+ // Toggle OneTouch Expandable
+ checkOneTouch(frame, splitPane, true);
+ checkOneTouch(frame, splitPane, false);
- // Check changing divider size to minimum and maximum values
- changeDividerSize(frame, splitPane, 50);
- changeDividerSize(frame, splitPane, 6);
+ // Check changing divider size to minimum and maximum values
+ changeDividerSize(frame, splitPane, 50);
+ changeDividerSize(frame, splitPane, 6);
- // Check moving the divider
- checkDividerMoves(frame, splitPane, false);
- checkDividerMoves(frame, splitPane, true);
+ // Check moving the divider
+ checkDividerMoves(frame, splitPane, false);
+ checkDividerMoves(frame, splitPane, true);
- // Check different minumum Day/Night sizes
- changeMinimumSizes(frame, splitPane, 100);
- changeMinimumSizes(frame, splitPane, 0);
- });
+ // Check different minumum Day/Night sizes
+ changeMinimumSizes(frame, splitPane, 100);
+ changeMinimumSizes(frame, splitPane, 0);
}
// Check for different day and night minimum size
--- a/jdk/test/sanity/client/SwingSet/src/TabbedPaneDemoTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sanity/client/SwingSet/src/TabbedPaneDemoTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -21,6 +21,7 @@
* questions.
*/
+import org.jtregext.GuiTestListener;
import com.sun.swingset3.demos.tabbedpane.TabbedPaneDemo;
import static com.sun.swingset3.demos.tabbedpane.TabbedPaneDemo.*;
import static org.jemmy2ext.JemmyExt.getLabeledContainerOperator;
@@ -31,7 +32,7 @@
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JRadioButtonOperator;
import org.netbeans.jemmy.operators.JTabbedPaneOperator;
-import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+import org.testng.annotations.Listeners;
/*
* @test
@@ -40,25 +41,24 @@
* positions, opening each tab and verifying the the tab gets selected.
*
* @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.tabbedpane.TabbedPaneDemo
* @run testng TabbedPaneDemoTest
*/
+@Listeners(GuiTestListener.class)
public class TabbedPaneDemoTest {
@Test
public void test() throws Exception {
- captureDebugInfoOnFail(() -> {
- new ClassReference(TabbedPaneDemo.class.getCanonicalName()).startApplication();
+ new ClassReference(TabbedPaneDemo.class.getCanonicalName()).startApplication();
- JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
+ JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
- for (String tp : new String[]{TOP, LEFT, BOTTOM, RIGHT}) {
- testTabs(mainFrame, tp);
- }
- });
+ for (String tp : new String[]{TOP, LEFT, BOTTOM, RIGHT}) {
+ testTabs(mainFrame, tp);
+ }
}
public void testTabs(JFrameOperator mainFrame, String tabPlacement) throws Exception {
--- a/jdk/test/sanity/client/SwingSet/src/TextFieldDemoTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sanity/client/SwingSet/src/TextFieldDemoTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -21,6 +21,7 @@
* questions.
*/
+import org.jtregext.GuiTestListener;
import com.sun.swingset3.demos.textfield.JHistoryTextField;
import com.sun.swingset3.demos.textfield.TextFieldDemo;
import static com.sun.swingset3.demos.textfield.TextFieldDemo.*;
@@ -41,6 +42,7 @@
import org.netbeans.jemmy.operators.JLabelOperator;
import org.netbeans.jemmy.operators.JPasswordFieldOperator;
import org.netbeans.jemmy.operators.JTextFieldOperator;
+import org.testng.annotations.Listeners;
/*
* @test
@@ -49,25 +51,25 @@
* checking that app reacts accordingly.
*
* @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.textfield.TextFieldDemo
* @run testng TextFieldDemoTest
*/
+@Listeners(GuiTestListener.class)
public class TextFieldDemoTest {
@Test
public void test() throws Exception {
- captureDebugInfoOnFail(() -> {
- new ClassReference(TextFieldDemo.class.getCanonicalName()).startApplication();
- JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+ new ClassReference(TextFieldDemo.class.getCanonicalName()).startApplication();
- historyTextField(frame);
- dateTextField(frame);
- passwordField(frame);
- });
+ JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+
+ historyTextField(frame);
+ dateTextField(frame);
+ passwordField(frame);
}
private void historyTextField(JFrameOperator jfo) throws Exception {
--- a/jdk/test/sanity/client/SwingSet/src/ToggleButtonDemoTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sanity/client/SwingSet/src/ToggleButtonDemoTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -21,6 +21,7 @@
* questions.
*/
+import org.jtregext.GuiTestListener;
import com.sun.swingset3.DemoProperties;
import com.sun.swingset3.demos.togglebutton.DirectionPanel;
import com.sun.swingset3.demos.togglebutton.LayoutControlPanel;
@@ -40,7 +41,7 @@
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JRadioButtonOperator;
import org.netbeans.jemmy.operators.JTabbedPaneOperator;
-import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+import org.testng.annotations.Listeners;
/*
* @test
@@ -53,50 +54,49 @@
* selected.
*
* @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.togglebutton.ToggleButtonDemo
* @run testng ToggleButtonDemoTest
*/
+@Listeners(GuiTestListener.class)
public class ToggleButtonDemoTest {
@Test
public void test() throws Exception {
- captureDebugInfoOnFail(() -> {
- new ClassReference(ToggleButtonDemo.class.getCanonicalName()).startApplication();
+ new ClassReference(ToggleButtonDemo.class.getCanonicalName()).startApplication();
- JFrameOperator mainFrame = new JFrameOperator(ToggleButtonDemo.class.getAnnotation(DemoProperties.class).value());
- JTabbedPaneOperator tabPane = new JTabbedPaneOperator(mainFrame);
+ JFrameOperator mainFrame = new JFrameOperator(ToggleButtonDemo.class.getAnnotation(DemoProperties.class).value());
+ JTabbedPaneOperator tabPane = new JTabbedPaneOperator(mainFrame);
- // Radio Button Toggles
- testRadioButtons(getBorderTitledJPanelOperator(mainFrame, TEXT_RADIO_BUTTONS), 3, null);
- testRadioButtons(getBorderTitledJPanelOperator(mainFrame, IMAGE_RADIO_BUTTONS), 3, null);
- testRadioButtons(getLabeledContainerOperator(mainFrame, PAD_AMOUNT), 3, (t, i) -> DEFAULT.equals(t));
+ // Radio Button Toggles
+ testRadioButtons(getBorderTitledJPanelOperator(mainFrame, TEXT_RADIO_BUTTONS), 3, null);
+ testRadioButtons(getBorderTitledJPanelOperator(mainFrame, IMAGE_RADIO_BUTTONS), 3, null);
+ testRadioButtons(getLabeledContainerOperator(mainFrame, PAD_AMOUNT), 3, (t, i) -> DEFAULT.equals(t));
- // switch to the Check Boxes Tab
- tabPane.selectPage(CHECK_BOXES);
+ // switch to the Check Boxes Tab
+ tabPane.selectPage(CHECK_BOXES);
- // Check Box Toggles
- ContainerOperator<?> textCheckBoxesJPanel = getBorderTitledJPanelOperator(mainFrame, TEXT_CHECKBOXES);
- testCheckBox(textCheckBoxesJPanel, CHECK1, false);
- testCheckBox(textCheckBoxesJPanel, CHECK2, false);
- testCheckBox(textCheckBoxesJPanel, CHECK3, false);
+ // Check Box Toggles
+ ContainerOperator<?> textCheckBoxesJPanel = getBorderTitledJPanelOperator(mainFrame, TEXT_CHECKBOXES);
+ testCheckBox(textCheckBoxesJPanel, CHECK1, false);
+ testCheckBox(textCheckBoxesJPanel, CHECK2, false);
+ testCheckBox(textCheckBoxesJPanel, CHECK3, false);
- ContainerOperator<?> imageCheckBoxesJPanel = getBorderTitledJPanelOperator(mainFrame, IMAGE_CHECKBOXES);
- testCheckBox(imageCheckBoxesJPanel, CHECK1, false);
- testCheckBox(imageCheckBoxesJPanel, CHECK2, false);
- testCheckBox(imageCheckBoxesJPanel, CHECK3, false);
+ ContainerOperator<?> imageCheckBoxesJPanel = getBorderTitledJPanelOperator(mainFrame, IMAGE_CHECKBOXES);
+ testCheckBox(imageCheckBoxesJPanel, CHECK1, false);
+ testCheckBox(imageCheckBoxesJPanel, CHECK2, false);
+ testCheckBox(imageCheckBoxesJPanel, CHECK3, false);
- ContainerOperator<?> displayOptionsContainer = getLabeledContainerOperator(mainFrame, DISPLAY_OPTIONS);
- testCheckBox(displayOptionsContainer, PAINT_BORDER, false);
- testCheckBox(displayOptionsContainer, PAINT_FOCUS, true);
- testCheckBox(displayOptionsContainer, ENABLED, true);
- testCheckBox(displayOptionsContainer, CONTENT_FILLED, true);
+ ContainerOperator<?> displayOptionsContainer = getLabeledContainerOperator(mainFrame, DISPLAY_OPTIONS);
+ testCheckBox(displayOptionsContainer, PAINT_BORDER, false);
+ testCheckBox(displayOptionsContainer, PAINT_FOCUS, true);
+ testCheckBox(displayOptionsContainer, ENABLED, true);
+ testCheckBox(displayOptionsContainer, CONTENT_FILLED, true);
- // Direction Button Toggles
- testToggleButtons(mainFrame);
- });
+ // Direction Button Toggles
+ testToggleButtons(mainFrame);
}
/**
--- a/jdk/test/sanity/client/SwingSet/src/TreeDemoTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sanity/client/SwingSet/src/TreeDemoTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -21,6 +21,7 @@
* questions.
*/
+import org.jtregext.GuiTestListener;
import com.sun.swingset3.demos.tree.TreeDemo;
import static com.sun.swingset3.demos.tree.TreeDemo.DEMO_TITLE;
import javax.swing.tree.TreePath;
@@ -29,7 +30,7 @@
import org.netbeans.jemmy.ClassReference;
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JTreeOperator;
-import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+import org.testng.annotations.Listeners;
/*
* @test
@@ -42,67 +43,67 @@
* vertically (as ScrollPane allows it).
*
* @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.tree.TreeDemo
* @run testng TreeDemoTest
*/
+@Listeners(GuiTestListener.class)
public class TreeDemoTest {
@Test
public void test() throws Exception {
- captureDebugInfoOnFail(() -> {
- new ClassReference(TreeDemo.class.getCanonicalName()).startApplication();
- JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+ new ClassReference(TreeDemo.class.getCanonicalName()).startApplication();
+
+ JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
- JTreeOperator tree = new JTreeOperator(frame);
+ JTreeOperator tree = new JTreeOperator(frame);
- assertEquals("Initial number of rows in the tree", 4, tree.getRowCount());
+ assertEquals("Initial number of rows in the tree", 4, tree.getRowCount());
- int initialTreeHeight = tree.getHeight();
+ int initialTreeHeight = tree.getHeight();
- // expand all nodes
- int expandsCount = 0;
- for (int i = 0; i < tree.getRowCount(); i++) {
- TreePath tp = tree.getPathForRow(i);
- if (tree.getChildCount(tp) > 0 && !tree.isExpanded(tp)) {
- tree.expandRow(i);
- expandsCount++;
- }
+ // expand all nodes
+ int expandsCount = 0;
+ for (int i = 0; i < tree.getRowCount(); i++) {
+ TreePath tp = tree.getPathForRow(i);
+ if (tree.getChildCount(tp) > 0 && !tree.isExpanded(tp)) {
+ tree.expandRow(i);
+ expandsCount++;
}
+ }
- assertEquals("Number of rows expanded", 75, expandsCount);
- assertEquals("Number of rows in the tree after expanding all of them",
- 616, tree.getRowCount());
+ assertEquals("Number of rows expanded", 75, expandsCount);
+ assertEquals("Number of rows in the tree after expanding all of them",
+ 616, tree.getRowCount());
- int expandedTreeHeight = tree.getHeight();
- assertTrue("Expanded tree height has increased, current "
- + expandedTreeHeight + " > initial " + initialTreeHeight,
- expandedTreeHeight > initialTreeHeight);
+ int expandedTreeHeight = tree.getHeight();
+ assertTrue("Expanded tree height has increased, current "
+ + expandedTreeHeight + " > initial " + initialTreeHeight,
+ expandedTreeHeight > initialTreeHeight);
- // collapse all nodes
- int collapsesCount = 0;
- for (int i = tree.getRowCount() - 1; i >= 0; i--) {
- TreePath tp = tree.getPathForRow(i);
- if (tree.getChildCount(tp) > 0 && tree.isExpanded(tp)) {
- tree.collapseRow(i);
- collapsesCount++;
- }
+ // collapse all nodes
+ int collapsesCount = 0;
+ for (int i = tree.getRowCount() - 1; i >= 0; i--) {
+ TreePath tp = tree.getPathForRow(i);
+ if (tree.getChildCount(tp) > 0 && tree.isExpanded(tp)) {
+ tree.collapseRow(i);
+ collapsesCount++;
}
+ }
- assertEquals("Number of rows collapsed", 76, collapsesCount);
- assertEquals("Number of rows in the tree after collapsing all of them",
- 1, tree.getRowCount());
+ assertEquals("Number of rows collapsed", 76, collapsesCount);
+ assertEquals("Number of rows in the tree after collapsing all of them",
+ 1, tree.getRowCount());
- int collapsedTreeHeight = tree.getHeight();
- assertTrue("Collpased tree height is not longer than initial, "
- + "current " + collapsedTreeHeight + " <= initial "
- + initialTreeHeight,
- collapsedTreeHeight <= initialTreeHeight);
+ int collapsedTreeHeight = tree.getHeight();
+ assertTrue("Collpased tree height is not longer than initial, "
+ + "current " + collapsedTreeHeight + " <= initial "
+ + initialTreeHeight,
+ collapsedTreeHeight <= initialTreeHeight);
- });
}
}
--- a/jdk/test/sanity/client/SwingSet/src/WindowDemoTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sanity/client/SwingSet/src/WindowDemoTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -21,6 +21,7 @@
* questions.
*/
+import org.jtregext.GuiTestListener;
import com.sun.swingset3.demos.window.WindowDemo;
import static com.sun.swingset3.demos.window.WindowDemo.*;
import static org.jemmy2ext.JemmyExt.*;
@@ -31,6 +32,7 @@
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JLabelOperator;
import org.netbeans.jemmy.operators.WindowOperator;
+import org.testng.annotations.Listeners;
/*
* @test
@@ -40,37 +42,37 @@
* when the "Show JWindow..." button is clicked.
*
* @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.window.WindowDemo
* @run testng WindowDemoTest
*/
+@Listeners(GuiTestListener.class)
public class WindowDemoTest {
@Test
public void test() throws Exception {
- captureDebugInfoOnFail(() -> {
- new ClassReference(WindowDemo.class.getCanonicalName()).startApplication();
+
+ new ClassReference(WindowDemo.class.getCanonicalName()).startApplication();
- JFrameOperator frame = new JFrameOperator();
+ JFrameOperator frame = new JFrameOperator();
- assertEquals("Only one JWindow is shown", 1, getJWindowCount());
+ assertEquals("Only one JWindow is shown", 1, getJWindowCount());
- WindowOperator window = new WindowOperator(getJWindow());
+ WindowOperator window = new WindowOperator(getJWindow());
- assertTrue("JFrame is showing", frame.isShowing());
- assertFalse("JFrame is not iconified", isIconified(frame));
- assertTrue("JWindow is showing", window.isShowing());
+ assertTrue("JFrame is showing", frame.isShowing());
+ assertFalse("JFrame is not iconified", isIconified(frame));
+ assertTrue("JWindow is showing", window.isShowing());
- final String labelText = I_HAVE_NO_SYSTEM_BORDER;
- JLabelOperator jLabelOperator = new JLabelOperator(window, labelText);
- assertEquals("JWindow contains the label with corresponding text", labelText, jLabelOperator.getText());
+ final String labelText = I_HAVE_NO_SYSTEM_BORDER;
+ JLabelOperator jLabelOperator = new JLabelOperator(window, labelText);
+ assertEquals("JWindow contains the label with corresponding text", labelText, jLabelOperator.getText());
- new JButtonOperator(frame, SHOW_J_WINDOW).push();
+ new JButtonOperator(frame, SHOW_J_WINDOW).push();
- assertEquals("Only one JWindow is shown", 1, getJWindowCount());
- });
+ assertEquals("Only one JWindow is shown", 1, getJWindowCount());
}
}
--- a/jdk/test/sanity/client/TEST.ROOT.template Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sanity/client/TEST.ROOT.template Thu Apr 28 23:08:17 2016 -0700
@@ -12,7 +12,7 @@
# A "headful" test requires a graphical environment to meaningfully
# run. Tests that are not headful are "headless."
-keys=screenshots
+keys=2d dnd i18n intermittent randomness headful
# Tests that must run in othervm mode
othervm.dirs=sanity/client/SwingSet
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sanity/client/lib/Extensions/src/org/jemmy2ext/JemmyExt.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,613 @@
+/*
+ * 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.jemmy2ext;
+
+import java.awt.Component;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.Window;
+import java.awt.image.BufferedImage;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Function;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.IntStream;
+import javax.imageio.ImageIO;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JWindow;
+import javax.swing.border.Border;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.TitledBorder;
+import org.netbeans.jemmy.ComponentChooser;
+import org.netbeans.jemmy.DefaultCharBindingMap;
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.TimeoutExpiredException;
+import org.netbeans.jemmy.Waitable;
+import org.netbeans.jemmy.Waiter;
+import org.netbeans.jemmy.drivers.scrolling.JSpinnerDriver;
+import org.netbeans.jemmy.image.StrictImageComparator;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.ContainerOperator;
+import org.netbeans.jemmy.operators.FrameOperator;
+import org.netbeans.jemmy.operators.JButtonOperator;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import org.netbeans.jemmy.operators.JLabelOperator;
+import org.netbeans.jemmy.operators.Operator;
+import org.netbeans.jemmy.util.Dumper;
+import org.netbeans.jemmy.util.PNGEncoder;
+import static org.testng.AssertJUnit.*;
+
+/**
+ * This class solves two tasks: 1. It adds functionality that is missing in
+ * Jemmy 2. It references all the Jemmy API that is needed by tests so that they
+ * can just @build JemmyExt class and do not worry about Jemmy
+ *
+ * @author akouznet
+ */
+public class JemmyExt {
+
+ /**
+ * Statically referencing all the classes that are needed by tests so that
+ * they're compiled by jtreg
+ */
+ static final Class<?>[] DEPENDENCIES = {
+ JSpinnerDriver.class,
+ DefaultCharBindingMap.class
+ };
+
+ public static void assertNotBlack(BufferedImage image) {
+ int w = image.getWidth();
+ int h = image.getHeight();
+ try {
+ assertFalse("All pixels are not black", IntStream.range(0, w).parallel().allMatch(x
+ -> IntStream.range(0, h).allMatch(y -> (image.getRGB(x, y) & 0xffffff) == 0)
+ ));
+ } catch (Throwable t) {
+ save(image, "allPixelsAreBlack.png");
+ throw t;
+ }
+ }
+
+ public static void waitArmed(JButtonOperator button) {
+ button.waitState(new ComponentChooser() {
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ return isArmed(button);
+ }
+
+ @Override
+ public String getDescription() {
+ return "Button is armed";
+ }
+ });
+ }
+
+ public static boolean isArmed(JButtonOperator button) {
+ return button.getQueueTool().invokeSmoothly(new QueueTool.QueueAction<Boolean>("getModel().isArmed()") {
+
+ @Override
+ public Boolean launch() throws Exception {
+ return ((JButton) button.getSource()).getModel().isArmed();
+ }
+ });
+ }
+
+ public static void waitPressed(JButtonOperator button) {
+ button.waitState(new ComponentChooser() {
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ return isPressed(button);
+ }
+
+ @Override
+ public String getDescription() {
+ return "Button is pressed";
+ }
+ });
+ }
+
+ public static boolean isPressed(JButtonOperator button) {
+ return button.getQueueTool().invokeSmoothly(new QueueTool.QueueAction<Boolean>("getModel().isPressed()") {
+
+ @Override
+ public Boolean launch() throws Exception {
+ return ((JButton) button.getSource()).getModel().isPressed();
+ }
+ });
+ }
+
+ public static void assertEquals(String string, StrictImageComparator comparator, BufferedImage expected, BufferedImage actual) {
+ try {
+ assertTrue(string, comparator.compare(expected, actual));
+ } catch (Error err) {
+ save(expected, "expected.png");
+ save(actual, "actual.png");
+ throw err;
+ }
+ }
+
+ public static void assertNotEquals(String string, StrictImageComparator comparator, BufferedImage notExpected, BufferedImage actual) {
+ try {
+ assertFalse(string, comparator.compare(notExpected, actual));
+ } catch (Error err) {
+ save(notExpected, "notExpected.png");
+ save(actual, "actual.png");
+ throw err;
+ }
+ }
+
+ public static void save(BufferedImage image, String filename) {
+ String filepath = filename;
+ try {
+ filepath = new File(filename).getCanonicalPath();
+ System.out.println("Saving screenshot to " + filepath);
+ BufferedOutputStream file = new BufferedOutputStream(new FileOutputStream(filepath));
+ new PNGEncoder(file, PNGEncoder.COLOR_MODE).encode(image);
+ } catch (IOException ioe) {
+ throw new RuntimeException("Failed to save image to " + filepath, ioe);
+ }
+ }
+
+ public static void waitImageIsStill(Robot rob, ComponentOperator operator) {
+ operator.waitState(new ComponentChooser() {
+
+ private BufferedImage previousImage = null;
+ private int index = 0;
+ private final StrictImageComparator sComparator = new StrictImageComparator();
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ BufferedImage currentImage = capture(rob, operator);
+ save(currentImage, "waitImageIsStill" + index + ".png");
+ index++;
+ boolean compareResult = previousImage == null ? false : sComparator.compare(currentImage, previousImage);
+ previousImage = currentImage;
+ return compareResult;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Image of " + operator + " is still";
+ }
+ });
+ }
+
+ private static class ThrowableHolder {
+
+ volatile Throwable t;
+ }
+
+ public static void waitFor(String description, RunnableWithException r) throws Exception {
+ Waiter<Boolean, ThrowableHolder> waiter = new Waiter<>(new Waitable<Boolean, ThrowableHolder>() {
+
+ @Override
+ public Boolean actionProduced(ThrowableHolder obj) {
+ try {
+ r.run();
+ return true;
+ } catch (Throwable t) {
+ obj.t = t;
+ return null;
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+ });
+ ThrowableHolder th = new ThrowableHolder();
+ try {
+ waiter.waitAction(th);
+ } catch (TimeoutExpiredException tee) {
+ Throwable t = th.t;
+ if (t != null) {
+ t.addSuppressed(tee);
+ if (t instanceof Exception) {
+ throw (Exception) t;
+ } else if (t instanceof Error) {
+ throw (Error) t;
+ } else if (t instanceof RuntimeException) {
+ throw (RuntimeException) t;
+ } else {
+ throw new IllegalStateException("Unexpected exception type", t);
+ }
+ }
+ }
+ }
+
+ public static BufferedImage capture(Robot rob, ComponentOperator operator) {
+ Rectangle boundary = new Rectangle(operator.getLocationOnScreen(),
+ operator.getSize());
+ return rob.createScreenCapture(boundary);
+ }
+
+ /**
+ * Dispose all AWT/Swing windows causing event thread to stop
+ */
+ public static void disposeAllWindows() {
+ System.out.println("disposeAllWindows");
+ try {
+ EventQueue.invokeAndWait(() -> {
+ Window[] windows = Window.getWindows();
+ for (Window w : windows) {
+ w.dispose();
+ }
+ });
+ } catch (InterruptedException | InvocationTargetException ex) {
+ Logger.getLogger(JemmyExt.class.getName()).log(Level.SEVERE, "Failed to dispose all windows", ex);
+ }
+ }
+
+ /**
+ * This is a helper class which allows to catch throwables thrown in other
+ * threads and throw them in the main test thread
+ */
+ public static class MultiThreadedTryCatch {
+
+ private final List<Throwable> throwables
+ = Collections.synchronizedList(new ArrayList<>());
+
+ /**
+ * Throws registered throwables. If the list of the registered
+ * throwables is not empty, it re-throws the first throwable in the list
+ * adding all others into its suppressed list. Can be used in any
+ * thread.
+ *
+ * @throws Exception
+ */
+ public void throwRegistered() throws Exception {
+ Throwable root = null;
+ synchronized (throwables) {
+ if (!throwables.isEmpty()) {
+ root = throwables.remove(0);
+ while (!throwables.isEmpty()) {
+ root.addSuppressed(throwables.remove(0));
+ }
+ }
+ }
+ if (root != null) {
+ if (root instanceof Error) {
+ throw (Error) root;
+ } else if (root instanceof Exception) {
+ throw (Exception) root;
+ } else {
+ throw new AssertionError("Unexpected exception type: " + root.getClass() + " (" + root + ")");
+ }
+ }
+ }
+
+ /**
+ * Registers a throwable and adds it to the list of throwables. Can be
+ * used in any thread.
+ *
+ * @param t
+ */
+ public void register(Throwable t) {
+ t.printStackTrace();
+ throwables.add(t);
+ }
+
+ /**
+ * Registers a throwable and adds it as the first item of the list of
+ * catched throwables.
+ *
+ * @param t
+ */
+ public void registerRoot(Throwable t) {
+ t.printStackTrace();
+ throwables.add(0, t);
+ }
+ }
+
+ /**
+ * Trying to capture as much information as possible. Currently it includes
+ * full dump and a screenshot of the whole screen.
+ */
+ public static void captureAll() {
+ PNGEncoder.captureScreen("failure.png", PNGEncoder.COLOR_MODE);
+ try {
+ Dumper.dumpAll("dumpAll.xml");
+ } catch (FileNotFoundException ex) {
+ Logger.getLogger(JemmyExt.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ captureWindows();
+ }
+
+ /**
+ * Captures each showing window image using Window.paint() method.
+ */
+ private static void captureWindows() {
+ try {
+ EventQueue.invokeAndWait(() -> {
+ Window[] windows = Window.getWindows();
+ int index = 0;
+ for (Window w : windows) {
+ if (!w.isShowing()) {
+ continue;
+ }
+ BufferedImage img = new BufferedImage(w.getWidth(), w.getHeight(), BufferedImage.TYPE_INT_ARGB);
+ Graphics g = img.getGraphics();
+ w.paint(g);
+ g.dispose();
+
+ try {
+ ImageIO.write(img, "png", new File("window" + index++ + ".png"));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ } catch (InterruptedException | InvocationTargetException ex) {
+ Logger.getLogger(JemmyExt.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ public static interface RunnableWithException {
+
+ public void run() throws Exception;
+ }
+
+ public static void waitIsFocused(JFrameOperator jfo) {
+ jfo.waitState(new ComponentChooser() {
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ return jfo.isFocused();
+ }
+
+ @Override
+ public String getDescription() {
+ return "JFrame is focused";
+ }
+ });
+ }
+
+ public static int getJWindowCount() {
+ return new QueueTool().invokeAndWait(new QueueTool.QueueAction<Integer>(null) {
+
+ @Override
+ public Integer launch() throws Exception {
+ Window[] windows = Window.getWindows();
+ int windowCount = 0;
+ for (Window w : windows) {
+ if (w.getClass().equals(JWindow.class)) {
+ windowCount++;
+ }
+ }
+ return windowCount;
+ }
+ });
+ }
+
+ public static JWindow getJWindow() {
+ return getJWindow(0);
+ }
+
+ public static JWindow getJWindow(int index) {
+ return new QueueTool().invokeAndWait(new QueueTool.QueueAction<JWindow>(null) {
+
+ @Override
+ public JWindow launch() throws Exception {
+ Window[] windows = Window.getWindows();
+ int windowIndex = 0;
+ for (Window w : windows) {
+ if (w.getClass().equals(JWindow.class)) {
+ if (windowIndex == index) {
+ return (JWindow) w;
+ }
+ windowIndex++;
+ }
+ }
+ return null;
+ }
+ });
+ }
+
+ public static boolean isIconified(FrameOperator frameOperator) {
+ return frameOperator.getQueueTool().invokeAndWait(new QueueTool.QueueAction<Boolean>("Frame is iconified") {
+
+ @Override
+ public Boolean launch() throws Exception {
+ return (((Frame) frameOperator.getSource()).getState() & Frame.ICONIFIED) != 0;
+ }
+ });
+ }
+
+ public static final Operator.DefaultStringComparator EXACT_STRING_COMPARATOR
+ = new Operator.DefaultStringComparator(true, true);
+
+ /**
+ * Finds a label with the exact labelText and returns the operator for its
+ * parent container.
+ *
+ * @param container
+ * @param labelText
+ * @return
+ */
+ public static ContainerOperator<?> getLabeledContainerOperator(ContainerOperator<?> container, String labelText) {
+
+ container.setComparator(EXACT_STRING_COMPARATOR);
+
+ JLabelOperator jLabelOperator = new JLabelOperator(container, labelText);
+
+ assert labelText.equals(jLabelOperator.getText());
+
+ return new ContainerOperator<>(jLabelOperator.getParent());
+ }
+
+ /**
+ * Finds a JPanel with exact title text.
+ *
+ * @param container
+ * @param titleText
+ * @return
+ */
+ public static ContainerOperator<?> getBorderTitledJPanelOperator(ContainerOperator<?> container, String titleText) {
+ return new ContainerOperator<>(container, new JPanelByBorderTitleFinder(titleText, EXACT_STRING_COMPARATOR));
+ }
+
+ public static final QueueTool QUEUE_TOOL = new QueueTool();
+
+ /**
+ * Allows to find JPanel by the title text in its border.
+ */
+ public static class JPanelByBorderTitleFinder implements ComponentChooser {
+
+ String titleText;
+ Operator.StringComparator comparator;
+
+ /**
+ * @param titleText title text pattern
+ * @param comparator specifies string comparison algorithm.
+ */
+ public JPanelByBorderTitleFinder(String titleText, Operator.StringComparator comparator) {
+ this.titleText = titleText;
+ this.comparator = comparator;
+ }
+
+ /**
+ * @param titleText title text pattern
+ */
+ public JPanelByBorderTitleFinder(String titleText) {
+ this(titleText, Operator.getDefaultStringComparator());
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ assert EventQueue.isDispatchThread();
+ if (comp instanceof JPanel) {
+ return checkBorder(((JPanel) comp).getBorder());
+ }
+ return false;
+ }
+
+ public boolean checkBorder(Border border) {
+ if (border instanceof TitledBorder) {
+ String title = ((TitledBorder) border).getTitle();
+ return comparator.equals(title, titleText);
+ } else if (border instanceof CompoundBorder) {
+ CompoundBorder compoundBorder = (CompoundBorder) border;
+ return checkBorder(compoundBorder.getInsideBorder()) || checkBorder(compoundBorder.getOutsideBorder());
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return ("JPanel with border title text \"" + titleText + "\" with comparator " + comparator);
+ }
+ }
+
+ public static class ByClassSimpleNameChooser implements ComponentChooser {
+
+ private final String className;
+
+ public ByClassSimpleNameChooser(String className) {
+ this.className = className;
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ return comp.getClass().getSimpleName().equals(className);
+ }
+
+ @Override
+ public String getDescription() {
+ return "Component with the simple class name of " + className;
+ }
+
+ }
+
+ public static class ByClassChooser implements ComponentChooser {
+
+ private final Class<?> clazz;
+
+ public ByClassChooser(Class<?> clazz) {
+ this.clazz = clazz;
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ return comp.getClass().equals(clazz);
+ }
+
+ @Override
+ public String getDescription() {
+ return "Component with the class of " + clazz;
+ }
+
+ }
+
+ public static class ByToolTipChooser implements ComponentChooser {
+
+ private final String tooltip;
+
+ public ByToolTipChooser(String tooltip) {
+ if (tooltip == null) {
+ throw new NullPointerException("Tooltip cannot be null");
+ }
+ this.tooltip = tooltip;
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ return (comp instanceof JComponent)
+ ? tooltip.equals(((JComponent) comp).getToolTipText())
+ : false;
+ }
+
+ @Override
+ public String getDescription() {
+ return "JComponent with the tooltip '" + tooltip + "'";
+ }
+
+ }
+
+ @SuppressWarnings(value = "unchecked")
+ public static <R, O extends Operator, S extends Component> R getUIValue(O operator, Function<S, R> getter) {
+ return operator.getQueueTool().invokeSmoothly(new QueueTool.QueueAction<R>("getting UI value through the queue using " + getter) {
+
+ @Override
+ public R launch() throws Exception {
+ return getter.apply((S) operator.getSource());
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sanity/client/lib/Extensions/src/org/jtregext/GuiTestListener.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,72 @@
+package org.jtregext;
+
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+import org.jemmy2ext.JemmyExt;
+import static org.jemmy2ext.JemmyExt.captureAll;
+import org.testng.ITestContext;
+import org.testng.ITestListener;
+import org.testng.ITestResult;
+
+// TODO: Remove this once https://bugs.openjdk.java.net/browse/JDK-8151671 is fixed
+public class GuiTestListener implements ITestListener {
+
+ private void afterTest() {
+ JemmyExt.disposeAllWindows();
+ }
+
+ @Override
+ public void onTestStart(ITestResult result) {
+ }
+
+ @Override
+ public void onTestSuccess(ITestResult result) {
+ System.out.println("TEST PASSED");
+ afterTest();
+ }
+
+ @Override
+ public void onTestFailure(ITestResult result) {
+ captureAll();
+ afterTest();
+ }
+
+ @Override
+ public void onTestSkipped(ITestResult result) {
+ }
+
+ @Override
+ public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
+ }
+
+ @Override
+ public void onStart(ITestContext context) {
+ }
+
+ @Override
+ public void onFinish(ITestContext context) {
+ }
+
+}
--- a/jdk/test/sanity/client/lib/Jemmy2Ext/src/org/jemmy2ext/JemmyExt.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,614 +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.jemmy2ext;
-
-import java.awt.Component;
-import java.awt.EventQueue;
-import java.awt.Frame;
-import java.awt.Graphics;
-import java.awt.Rectangle;
-import java.awt.Robot;
-import java.awt.Window;
-import java.awt.image.BufferedImage;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.function.Function;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.stream.IntStream;
-import javax.imageio.ImageIO;
-import javax.swing.JButton;
-import javax.swing.JComponent;
-import javax.swing.JPanel;
-import javax.swing.JWindow;
-import javax.swing.border.Border;
-import javax.swing.border.CompoundBorder;
-import javax.swing.border.TitledBorder;
-import org.netbeans.jemmy.ComponentChooser;
-import org.netbeans.jemmy.DefaultCharBindingMap;
-import org.netbeans.jemmy.QueueTool;
-import org.netbeans.jemmy.TimeoutExpiredException;
-import org.netbeans.jemmy.Waitable;
-import org.netbeans.jemmy.Waiter;
-import org.netbeans.jemmy.drivers.scrolling.JSpinnerDriver;
-import org.netbeans.jemmy.image.StrictImageComparator;
-import org.netbeans.jemmy.operators.ComponentOperator;
-import org.netbeans.jemmy.operators.ContainerOperator;
-import org.netbeans.jemmy.operators.FrameOperator;
-import org.netbeans.jemmy.operators.JButtonOperator;
-import org.netbeans.jemmy.operators.JFrameOperator;
-import org.netbeans.jemmy.operators.JLabelOperator;
-import org.netbeans.jemmy.operators.Operator;
-import org.netbeans.jemmy.util.Dumper;
-import org.netbeans.jemmy.util.PNGEncoder;
-import static org.testng.AssertJUnit.*;
-
-/**
- * This class solves two tasks: 1. It adds functionality that is missing in
- * Jemmy 2. It references all the Jemmy API that is needed by tests so that they
- * can just @build JemmyExt class and do not worry about Jemmy
- *
- * @author akouznet
- */
-public class JemmyExt {
-
- /**
- * Statically referencing all the classes that are needed by tests so that
- * they're compiled by jtreg
- */
- static final Class<?>[] DEPENDENCIES = {
- JSpinnerDriver.class,
- DefaultCharBindingMap.class
- };
-
- public static void assertNotBlack(BufferedImage image) {
- int w = image.getWidth();
- int h = image.getHeight();
- try {
- assertFalse("All pixels are not black", IntStream.range(0, w).parallel().allMatch(x
- -> IntStream.range(0, h).allMatch(y -> (image.getRGB(x, y) & 0xffffff) == 0)
- ));
- } catch (Throwable t) {
- save(image, "allPixelsAreBlack.png");
- throw t;
- }
- }
-
- public static void waitArmed(JButtonOperator button) {
- button.waitState(new ComponentChooser() {
-
- @Override
- public boolean checkComponent(Component comp) {
- return isArmed(button);
- }
-
- @Override
- public String getDescription() {
- return "Button is armed";
- }
- });
- }
-
- public static boolean isArmed(JButtonOperator button) {
- return button.getQueueTool().invokeSmoothly(new QueueTool.QueueAction<Boolean>("getModel().isArmed()") {
-
- @Override
- public Boolean launch() throws Exception {
- return ((JButton) button.getSource()).getModel().isArmed();
- }
- });
- }
-
- public static void waitPressed(JButtonOperator button) {
- button.waitState(new ComponentChooser() {
-
- @Override
- public boolean checkComponent(Component comp) {
- return isPressed(button);
- }
-
- @Override
- public String getDescription() {
- return "Button is pressed";
- }
- });
- }
-
- public static boolean isPressed(JButtonOperator button) {
- return button.getQueueTool().invokeSmoothly(new QueueTool.QueueAction<Boolean>("getModel().isPressed()") {
-
- @Override
- public Boolean launch() throws Exception {
- return ((JButton) button.getSource()).getModel().isPressed();
- }
- });
- }
-
- public static void assertEquals(String string, StrictImageComparator comparator, BufferedImage expected, BufferedImage actual) {
- try {
- assertTrue(string, comparator.compare(expected, actual));
- } catch (Error err) {
- save(expected, "expected.png");
- save(actual, "actual.png");
- throw err;
- }
- }
-
- public static void assertNotEquals(String string, StrictImageComparator comparator, BufferedImage notExpected, BufferedImage actual) {
- try {
- assertFalse(string, comparator.compare(notExpected, actual));
- } catch (Error err) {
- save(notExpected, "notExpected.png");
- save(actual, "actual.png");
- throw err;
- }
- }
-
- public static void save(BufferedImage image, String filename) {
- String filepath = filename;
- try {
- filepath = new File(filename).getCanonicalPath();
- System.out.println("Saving screenshot to " + filepath);
- BufferedOutputStream file = new BufferedOutputStream(new FileOutputStream(filepath));
- new PNGEncoder(file, PNGEncoder.COLOR_MODE).encode(image);
- } catch (IOException ioe) {
- throw new RuntimeException("Failed to save image to " + filepath, ioe);
- }
- }
-
- public static void waitImageIsStill(Robot rob, ComponentOperator operator) {
- operator.waitState(new ComponentChooser() {
-
- private BufferedImage previousImage = null;
- private int index = 0;
- private final StrictImageComparator sComparator = new StrictImageComparator();
-
- @Override
- public boolean checkComponent(Component comp) {
- BufferedImage currentImage = capture(rob, operator);
- save(currentImage, "waitImageIsStill" + index + ".png");
- index++;
- boolean compareResult = previousImage == null ? false : sComparator.compare(currentImage, previousImage);
- previousImage = currentImage;
- return compareResult;
- }
-
- @Override
- public String getDescription() {
- return "Image of " + operator + " is still";
- }
- });
- }
-
- private static class ThrowableHolder {
-
- volatile Throwable t;
- }
-
- public static void waitFor(String description, RunnableWithException r) throws Exception {
- Waiter<Boolean, ThrowableHolder> waiter = new Waiter<>(new Waitable<Boolean, ThrowableHolder>() {
-
- @Override
- public Boolean actionProduced(ThrowableHolder obj) {
- try {
- r.run();
- return true;
- } catch (Throwable t) {
- obj.t = t;
- return null;
- }
- }
-
- @Override
- public String getDescription() {
- return description;
- }
- });
- ThrowableHolder th = new ThrowableHolder();
- try {
- waiter.waitAction(th);
- } catch (TimeoutExpiredException tee) {
- Throwable t = th.t;
- if (t != null) {
- t.addSuppressed(tee);
- if (t instanceof Exception) {
- throw (Exception) t;
- } else if (t instanceof Error) {
- throw (Error) t;
- } else if (t instanceof RuntimeException) {
- throw (RuntimeException) t;
- } else {
- throw new IllegalStateException("Unexpected exception type", t);
- }
- }
- }
- }
-
- public static BufferedImage capture(Robot rob, ComponentOperator operator) {
- Rectangle boundary = new Rectangle(operator.getLocationOnScreen(),
- operator.getSize());
- return rob.createScreenCapture(boundary);
- }
-
- /**
- * Wraps the test code so that in case of any failure as much information as
- * possible is captured
- *
- * @param r test code Runnable
- * @throws Exception whatever exception the test may throw
- */
- public static void captureDebugInfoOnFail(RunnableWithException r) throws Exception {
- // TODO: Remove this once https://bugs.openjdk.java.net/browse/JDK-8151671 is fixed
- try {
- r.run();
- System.out.println("TEST PASSED");
- } catch (Throwable t) {
- captureAll();
- throw t;
- }
- }
-
- /**
- * This is a helper class which allows to catch throwables thrown in other
- * threads and throw them in the main test thread
- */
- public static class MultiThreadedTryCatch {
-
- private final List<Throwable> throwables
- = Collections.synchronizedList(new ArrayList<>());
-
- /**
- * Throws registered throwables. If the list of the registered
- * throwables is not empty, it re-throws the first throwable in the list
- * adding all others into its suppressed list. Can be used in any
- * thread.
- *
- * @throws Exception
- */
- public void throwRegistered() throws Exception {
- Throwable root = null;
- synchronized (throwables) {
- if (!throwables.isEmpty()) {
- root = throwables.remove(0);
- while (!throwables.isEmpty()) {
- root.addSuppressed(throwables.remove(0));
- }
- }
- }
- if (root != null) {
- if (root instanceof Error) {
- throw (Error) root;
- } else if (root instanceof Exception) {
- throw (Exception) root;
- } else {
- throw new AssertionError("Unexpected exception type: " + root.getClass() + " (" + root + ")");
- }
- }
- }
-
- /**
- * Registers a throwable and adds it to the list of throwables. Can be
- * used in any thread.
- *
- * @param t
- */
- public void register(Throwable t) {
- t.printStackTrace();
- throwables.add(t);
- }
-
- /**
- * Registers a throwable and adds it as the first item of the list of
- * catched throwables.
- *
- * @param t
- */
- public void registerRoot(Throwable t) {
- t.printStackTrace();
- throwables.add(0, t);
- }
- }
-
- /**
- * Trying to capture as much information as possible. Currently it includes
- * full dump and a screenshot of the whole screen.
- */
- public static void captureAll() {
- PNGEncoder.captureScreen("failure.png", PNGEncoder.COLOR_MODE);
- try {
- Dumper.dumpAll("dumpAll.xml");
- } catch (FileNotFoundException ex) {
- Logger.getLogger(JemmyExt.class.getName()).log(Level.SEVERE, null, ex);
- }
- captureWindows();
- }
-
- /**
- * Captures each showing window image using Window.paint() method.
- */
- private static void captureWindows() {
- try {
- EventQueue.invokeAndWait(() -> {
- Window[] windows = Window.getWindows();
- int index = 0;
- for (Window w : windows) {
- if (!w.isShowing()) {
- continue;
- }
- BufferedImage img = new BufferedImage(w.getWidth(), w.getHeight(), BufferedImage.TYPE_INT_ARGB);
- Graphics g = img.getGraphics();
- w.paint(g);
- g.dispose();
-
- try {
- ImageIO.write(img, "png", new File("window" + index++ + ".png"));
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- });
- } catch (InterruptedException | InvocationTargetException ex) {
- Logger.getLogger(JemmyExt.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
-
- public static interface RunnableWithException {
-
- public void run() throws Exception;
- }
-
- public static void waitIsFocused(JFrameOperator jfo) {
- jfo.waitState(new ComponentChooser() {
-
- @Override
- public boolean checkComponent(Component comp) {
- return jfo.isFocused();
- }
-
- @Override
- public String getDescription() {
- return "JFrame is focused";
- }
- });
- }
-
- public static int getJWindowCount() {
- return new QueueTool().invokeAndWait(new QueueTool.QueueAction<Integer>(null) {
-
- @Override
- public Integer launch() throws Exception {
- Window[] windows = Window.getWindows();
- int windowCount = 0;
- for (Window w : windows) {
- if (w.getClass().equals(JWindow.class)) {
- windowCount++;
- }
- }
- return windowCount;
- }
- });
- }
-
- public static JWindow getJWindow() {
- return getJWindow(0);
- }
-
- public static JWindow getJWindow(int index) {
- return new QueueTool().invokeAndWait(new QueueTool.QueueAction<JWindow>(null) {
-
- @Override
- public JWindow launch() throws Exception {
- Window[] windows = Window.getWindows();
- int windowIndex = 0;
- for (Window w : windows) {
- if (w.getClass().equals(JWindow.class)) {
- if (windowIndex == index) {
- return (JWindow) w;
- }
- windowIndex++;
- }
- }
- return null;
- }
- });
- }
-
- public static boolean isIconified(FrameOperator frameOperator) {
- return frameOperator.getQueueTool().invokeAndWait(new QueueTool.QueueAction<Boolean>("Frame is iconified") {
-
- @Override
- public Boolean launch() throws Exception {
- return (((Frame) frameOperator.getSource()).getState() & Frame.ICONIFIED) != 0;
- }
- });
- }
-
- public static final Operator.DefaultStringComparator EXACT_STRING_COMPARATOR
- = new Operator.DefaultStringComparator(true, true);
-
- /**
- * Finds a label with the exact labelText and returns the operator for its
- * parent container.
- *
- * @param container
- * @param labelText
- * @return
- */
- public static ContainerOperator<?> getLabeledContainerOperator(ContainerOperator<?> container, String labelText) {
-
- container.setComparator(EXACT_STRING_COMPARATOR);
-
- JLabelOperator jLabelOperator = new JLabelOperator(container, labelText);
-
- assert labelText.equals(jLabelOperator.getText());
-
- return new ContainerOperator<>(jLabelOperator.getParent());
- }
-
- /**
- * Finds a JPanel with exact title text.
- *
- * @param container
- * @param titleText
- * @return
- */
- public static ContainerOperator<?> getBorderTitledJPanelOperator(ContainerOperator<?> container, String titleText) {
- return new ContainerOperator<>(container, new JPanelByBorderTitleFinder(titleText, EXACT_STRING_COMPARATOR));
- }
-
- public static final QueueTool QUEUE_TOOL = new QueueTool();
-
- /**
- * Allows to find JPanel by the title text in its border.
- */
- public static class JPanelByBorderTitleFinder implements ComponentChooser {
-
- String titleText;
- Operator.StringComparator comparator;
-
- /**
- * @param titleText title text pattern
- * @param comparator specifies string comparison algorithm.
- */
- public JPanelByBorderTitleFinder(String titleText, Operator.StringComparator comparator) {
- this.titleText = titleText;
- this.comparator = comparator;
- }
-
- /**
- * @param titleText title text pattern
- */
- public JPanelByBorderTitleFinder(String titleText) {
- this(titleText, Operator.getDefaultStringComparator());
- }
-
- @Override
- public boolean checkComponent(Component comp) {
- assert EventQueue.isDispatchThread();
- if (comp instanceof JPanel) {
- return checkBorder(((JPanel) comp).getBorder());
- }
- return false;
- }
-
- public boolean checkBorder(Border border) {
- if (border instanceof TitledBorder) {
- String title = ((TitledBorder) border).getTitle();
- return comparator.equals(title, titleText);
- } else if (border instanceof CompoundBorder) {
- CompoundBorder compoundBorder = (CompoundBorder) border;
- return checkBorder(compoundBorder.getInsideBorder()) || checkBorder(compoundBorder.getOutsideBorder());
- } else {
- return false;
- }
- }
-
- @Override
- public String getDescription() {
- return ("JPanel with border title text \"" + titleText + "\" with comparator " + comparator);
- }
- }
-
- public static class ByClassSimpleNameChooser implements ComponentChooser {
-
- private final String className;
-
- public ByClassSimpleNameChooser(String className) {
- this.className = className;
- }
-
- @Override
- public boolean checkComponent(Component comp) {
- return comp.getClass().getSimpleName().equals(className);
- }
-
- @Override
- public String getDescription() {
- return "Component with the simple class name of " + className;
- }
-
- }
-
- public static class ByClassChooser implements ComponentChooser {
-
- private final Class<?> clazz;
-
- public ByClassChooser(Class<?> clazz) {
- this.clazz = clazz;
- }
-
- @Override
- public boolean checkComponent(Component comp) {
- return comp.getClass().equals(clazz);
- }
-
- @Override
- public String getDescription() {
- return "Component with the class of " + clazz;
- }
-
- }
-
- public static class ByToolTipChooser implements ComponentChooser {
-
- private final String tooltip;
-
- public ByToolTipChooser(String tooltip) {
- if (tooltip == null) {
- throw new NullPointerException("Tooltip cannot be null");
- }
- this.tooltip = tooltip;
- }
-
- @Override
- public boolean checkComponent(Component comp) {
- return (comp instanceof JComponent)
- ? tooltip.equals(((JComponent) comp).getToolTipText())
- : false;
- }
-
- @Override
- public String getDescription() {
- return "JComponent with the tooltip '" + tooltip + "'";
- }
-
- }
-
- @SuppressWarnings(value = "unchecked")
- public static <R, O extends Operator, S extends Component> R getUIValue(O operator, Function<S, R> getter) {
- return operator.getQueueTool().invokeSmoothly(new QueueTool.QueueAction<R>("getting UI value through the queue using " + getter) {
-
- @Override
- public R launch() throws Exception {
- return getter.apply((S) operator.getSource());
- }
- });
- }
-}
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/ButtonDemo.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/ButtonDemo.java Thu Apr 28 23:08:17 2016 -0700
@@ -36,6 +36,7 @@
import com.sun.swingset3.DemoProperties;
import com.sun.swingset3.demos.JHyperlink;
+import java.lang.reflect.InvocationTargetException;
/**
*
@@ -210,10 +211,10 @@
return panel;
}
- public static void main(String args[]) {
+ public static void main(String args[]) throws InterruptedException, InvocationTargetException {
final ButtonDemo buttonDemo = new ButtonDemo();
- javax.swing.SwingUtilities.invokeLater(() -> {
+ javax.swing.SwingUtilities.invokeAndWait(() -> {
JFrame frame = new JFrame(DEMO_TITLE);
frame.add(buttonDemo);
frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/TabbedPaneDemo.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/TabbedPaneDemo.java Thu Apr 28 23:08:17 2016 -0700
@@ -91,7 +91,6 @@
public static void main(String[] args) {
JFrame frame = new JFrame(DEMO_TITLE);
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new TabbedPaneDemo());
frame.setPreferredSize(new Dimension(800, 600));
frame.pack();
@@ -205,7 +204,9 @@
}
public void go() {
- animator = new javax.swing.Timer(22 + 22 + 22, this);
+ if (animator == null) {
+ animator = new javax.swing.Timer(22 + 22 + 22, this);
+ }
animator.start();
}
@@ -247,7 +248,7 @@
@Override
public void actionPerformed(ActionEvent e) {
- if (isVisible()) {
+ if (isShowing()) {
repaint();
} else {
animator.stop();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/window/WindowDemo.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/window/WindowDemo.java Thu Apr 28 23:08:17 2016 -0700
@@ -31,6 +31,7 @@
import com.sun.swingset3.DemoProperties;
import com.sun.swingset3.demos.DemoUtilities;
+import java.lang.reflect.InvocationTargetException;
/**
* @author aim
@@ -145,8 +146,8 @@
}
}
- public static void main(String args[]) {
- EventQueue.invokeLater(() -> {
+ public static void main(String args[]) throws InterruptedException, InvocationTargetException {
+ EventQueue.invokeAndWait(() -> {
JFrame frame = new JFrame();
WindowDemo demo = new WindowDemo();
frame.add(demo);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/ImpactOnSNI.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
+/*
+ * @test
+ * @bug 8144566
+ * @summary Custom HostnameVerifier disables SNI extension
+ * @run main/othervm ImpactOnSNI
+ */
+
+import java.io.*;
+import java.net.*;
+import javax.net.ssl.*;
+
+public class ImpactOnSNI {
+
+ /*
+ * =============================================================
+ * Set the various variables needed for the tests, then
+ * specify what tests to run on each side.
+ */
+
+ /*
+ * Should we run the client or server in a separate thread?
+ * Both sides can throw exceptions, but do you have a preference
+ * as to which side should be the main thread.
+ */
+ private static final boolean separateServerThread = true;
+
+ /*
+ * Where do we find the keystores?
+ */
+ private static final String pathToStores =
+ "../../../../../../javax/net/ssl/etc";
+ private static final String keyStoreFile = "keystore";
+ private static final String trustStoreFile = "truststore";
+ private static final String passwd = "passphrase";
+
+ /*
+ * Is the server ready to serve?
+ */
+ private static volatile boolean serverReady = false;
+
+ /*
+ * Is the connection ready to close?
+ */
+ private static volatile boolean closeReady = false;
+
+ /*
+ * Turn on SSL debugging?
+ */
+ private static final boolean debug = false;
+
+ /*
+ * Message posted
+ */
+ private static final String postMsg = "HTTP post on a https server";
+
+ /*
+ * the fully qualified domain name of localhost
+ */
+ private static String hostname = null;
+
+ /*
+ * If the client or server is doing some kind of object creation
+ * that the other side depends on, and that thread prematurely
+ * exits, you may experience a hang. The test harness will
+ * terminate all hung threads after its timeout has expired,
+ * currently 3 minutes by default, but you might try to be
+ * smart about it....
+ */
+
+ /*
+ * Define the server side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ private void doServerSide() throws Exception {
+ SSLServerSocketFactory sslssf =
+ (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
+ try (SSLServerSocket sslServerSocket =
+ (SSLServerSocket)sslssf.createServerSocket(serverPort)) {
+
+ serverPort = sslServerSocket.getLocalPort();
+
+ /*
+ * Signal Client, we're ready for his connect.
+ */
+ serverReady = true;
+
+ /*
+ * Accept connections
+ */
+ try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) {
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+ BufferedReader br =
+ new BufferedReader(new InputStreamReader(sslIS));
+ PrintStream ps = new PrintStream(sslOS);
+
+ // process HTTP POST request from client
+ System.out.println("status line: " + br.readLine());
+ String msg = null;
+ while ((msg = br.readLine()) != null && msg.length() > 0);
+
+ msg = br.readLine();
+ if (msg.equals(postMsg)) {
+ ps.println("HTTP/1.1 200 OK\n\n");
+ } else {
+ ps.println("HTTP/1.1 500 Not OK\n\n");
+ }
+ ps.flush();
+
+ ExtendedSSLSession session =
+ (ExtendedSSLSession)sslSocket.getSession();
+ if (session.getRequestedServerNames().isEmpty()) {
+ throw new Exception("No expected Server Name Indication");
+ }
+
+ // close the socket
+ while (!closeReady) {
+ Thread.sleep(50);
+ }
+ }
+ }
+ }
+
+ /*
+ * Define the client side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ private void doClientSide() throws Exception {
+ /*
+ * Wait for server to get started.
+ */
+ while (!serverReady) {
+ Thread.sleep(50);
+ }
+
+ // Send HTTP POST request to server
+ URL url = new URL("https://" + hostname + ":" + serverPort);
+
+ HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
+ HttpsURLConnection http = (HttpsURLConnection)url.openConnection();
+ http.setDoOutput(true);
+
+ http.setRequestMethod("POST");
+ PrintStream ps = new PrintStream(http.getOutputStream());
+ try {
+ ps.println(postMsg);
+ ps.flush();
+ if (http.getResponseCode() != 200) {
+ throw new RuntimeException("test Failed");
+ }
+ } finally {
+ ps.close();
+ http.disconnect();
+ closeReady = true;
+ }
+ }
+
+ private static class NameVerifier implements HostnameVerifier {
+ public boolean verify(String hostname, SSLSession session) {
+ return true;
+ }
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+
+ // use any free port by default
+ private volatile int serverPort = 0;
+
+ private volatile Exception serverException = null;
+ private volatile Exception clientException = null;
+
+ public static void main(String[] args) throws Exception {
+ String keyFilename =
+ System.getProperty("test.src", "./") + "/" + pathToStores +
+ "/" + keyStoreFile;
+ String trustFilename =
+ System.getProperty("test.src", "./") + "/" + pathToStores +
+ "/" + trustStoreFile;
+
+ System.setProperty("javax.net.ssl.keyStore", keyFilename);
+ System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+ System.setProperty("javax.net.ssl.trustStore", trustFilename);
+ System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+ if (debug) {
+ System.setProperty("javax.net.debug", "all");
+ }
+
+ try {
+ hostname = InetAddress.getLocalHost().getCanonicalHostName();
+ } catch (UnknownHostException uhe) {
+ System.out.println(
+ "Ignore the test as the local hostname cannot be determined");
+
+ return;
+ }
+
+ System.out.println(
+ "The fully qualified domain name of the local host is " +
+ hostname);
+ // Ignore the test if the hostname does not sound like a domain name.
+ if ((hostname == null) || hostname.isEmpty() ||
+ hostname.startsWith("localhost") ||
+ Character.isDigit(hostname.charAt(hostname.length() - 1))) {
+
+ System.out.println("Ignore the test as the local hostname " +
+ "cannot be determined as fully qualified domain name");
+
+ return;
+ }
+
+ /*
+ * Start the tests.
+ */
+ new ImpactOnSNI();
+ }
+
+ private Thread clientThread = null;
+ private Thread serverThread = null;
+
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ ImpactOnSNI() throws Exception {
+ Exception startException = null;
+ try {
+ if (separateServerThread) {
+ startServer(true);
+ startClient(false);
+ } else {
+ startClient(true);
+ startServer(false);
+ }
+ } catch (Exception e) {
+ startException = e;
+ }
+
+ /*
+ * Wait for other side to close down.
+ */
+ if (separateServerThread) {
+ if (serverThread != null) {
+ serverThread.join();
+ }
+ } else {
+ if (clientThread != null) {
+ clientThread.join();
+ }
+ }
+
+ /*
+ * When we get here, the test is pretty much over.
+ * Which side threw the error?
+ */
+ Exception local;
+ Exception remote;
+
+ if (separateServerThread) {
+ remote = serverException;
+ local = clientException;
+ } else {
+ remote = clientException;
+ local = serverException;
+ }
+
+ Exception exception = null;
+
+ /*
+ * Check various exception conditions.
+ */
+ if ((local != null) && (remote != null)) {
+ // If both failed, return the curthread's exception.
+ local.initCause(remote);
+ exception = local;
+ } else if (local != null) {
+ exception = local;
+ } else if (remote != null) {
+ exception = remote;
+ } else if (startException != null) {
+ exception = startException;
+ }
+
+ /*
+ * If there was an exception *AND* a startException,
+ * output it.
+ */
+ if (exception != null) {
+ if (exception != startException && startException != null) {
+ exception.addSuppressed(startException);
+ }
+ throw exception;
+ }
+
+ // Fall-through: no exception to throw!
+ }
+
+ private void startServer(boolean newThread) throws Exception {
+ if (newThread) {
+ serverThread = new Thread() {
+ @Override
+ public void run() {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ /*
+ * Our server thread just died.
+ *
+ * Release the client, if not active already...
+ */
+ System.err.println("Server died...");
+ serverReady = true;
+ serverException = e;
+ }
+ }
+ };
+ serverThread.start();
+ } else {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ serverException = e;
+ } finally {
+ serverReady = true;
+ }
+ }
+ }
+
+ private void startClient(boolean newThread) throws Exception {
+ if (newThread) {
+ clientThread = new Thread() {
+ @Override
+ public void run() {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ /*
+ * Our client thread just died.
+ */
+ System.err.println("Client died...");
+ clientException = e;
+ }
+ }
+ };
+ clientThread.start();
+ } else {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ clientException = e;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/rmi/TEST.properties Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,1 @@
+modules = java.rmi
--- a/jdk/test/sun/util/logging/PlatformLoggerTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/sun/util/logging/PlatformLoggerTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -197,7 +197,7 @@
// create a brand new java logger
Logger javaLogger = sun.util.logging.internal.LoggingProviderImpl.getLogManagerAccess()
.demandLoggerFor(LogManager.getLogManager(),
- logger.getName()+"."+level.getName(), Thread.class);
+ logger.getName()+"."+level.getName(), Thread.class.getModule());
// Set a non standard java.util.logging.Level on the java logger
// (except for OFF & ALL - which will remain unchanged)
--- a/jdk/test/tools/jimage/JImageTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/tools/jimage/JImageTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -110,54 +110,5 @@
.dir(helper.createNewExtractedDir("modules"))
.image(image.resolve("lib").resolve("modules"))
.extract().assertSuccess();
-
- Path recreatedImage = JImageGenerator.getJImageTask()
- .dir(extractedDir)
- .image(helper.createNewRecreatedDir(extractedDir.getFileName().toString()))
- .recreate().assertSuccess();
- JImageValidator.validate(recreatedImage, bootClasses, Collections.emptyList());
-
- // Check replacing the boot image by recreated one
- Path destFile = image.resolve("lib").resolve("modules");
- Files.copy(recreatedImage, destFile, REPLACE_EXISTING);
- JImageValidator validator = new JImageValidator(module, Collections.emptyList(),
- image.toFile(), Collections.emptyList(), Collections.emptyList());
- validator.validate();
-
- Path recreatedImage2 = JImageGenerator.getJImageTask()
- .dir(extractedDir)
- .option("--compress").option("2")
- .image(helper.createNewRecreatedDir(extractedDir.getFileName().toString()))
- .recreate().assertSuccess();
- JImageValidator.validate(recreatedImage2, bootClasses, Collections.emptyList());
-
- Path recreatedImage3 = JImageGenerator.getJImageTask()
- .dir(extractedDir)
- .option("--strip-debug")
- .image(helper.createNewRecreatedDir(extractedDir.getFileName().toString()))
- .recreate().assertSuccess();
- JImageValidator.validate(recreatedImage3, bootClasses, Collections.emptyList());
-
- Path recreatedImage4 = JImageGenerator.getJImageTask()
- .dir(extractedDir)
- .option("--exclude-resources")
- .option("*.jcov, */META-INF/*")
- .image(helper.createNewRecreatedDir(extractedDir.getFileName().toString()))
- .recreate().assertSuccess();
- List<String> unexpectedPaths = new ArrayList<>();
- unexpectedPaths.add(".jcov");
- unexpectedPaths.add("/META-INF/");
- JImageValidator.validate(recreatedImage4, bootClasses, unexpectedPaths);
-
- Path recreatedImage5 = JImageGenerator.getJImageTask()
- .dir(extractedDir)
- .option("--compress")
- .option("2")
- .option("--strip-debug")
- .option("--exclude-resources")
- .option("*.jcov, */META-INF/*")
- .image(helper.createNewRecreatedDir(extractedDir.getFileName().toString()))
- .recreate().assertSuccess();
- JImageValidator.validate(recreatedImage5, bootClasses, unexpectedPaths);
}
}
--- a/jdk/test/tools/jimage/JImageToolTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/tools/jimage/JImageToolTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -63,11 +63,7 @@
String jimage = jimagePath.toAbsolutePath().toString();
String bootimage = modulesimagePath.toAbsolutePath().toString();
String extractDir = Paths.get(".", "extract").toAbsolutePath().toString();
- String recreateImage = Paths.get(".", "recreate").toAbsolutePath().toString();
- String relativeRecreateImage = Paths.get(".", "recreate2").toString();
jimage("extract", "--dir", extractDir, bootimage);
- jimage("recreate", "--dir", extractDir, recreateImage);
- jimage("recreate", "--dir", extractDir, relativeRecreateImage);
System.out.println("Test successful");
} else {
System.out.println("Test skipped, not an images build");
--- a/jdk/test/tools/launcher/modules/limitmods/LimitModsTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/tools/launcher/modules/limitmods/LimitModsTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -103,10 +103,9 @@
public void testWithAddMods() throws Exception {
int exitValue;
- // java -limitmods java.base -addmods java.logging,jdk.unsupported -listmods
+ // java -limitmods java.base -addmods java.logging -listmods
exitValue = executeTestJava("-limitmods", "java.base",
- "-addmods",
- "java.logging,jdk.unsupported", // TODO: add bug No.
+ "-addmods", "java.logging",
"-listmods")
.outputTo(System.out)
.errorTo(System.out)
--- a/jdk/test/tools/lib/tests/JImageGenerator.java Thu Apr 28 00:38:21 2016 -0700
+++ b/jdk/test/tools/lib/tests/JImageGenerator.java Thu Apr 28 23:08:17 2016 -0700
@@ -553,10 +553,6 @@
public Result extract() {
return cmd("extract", dir);
}
-
- public Result recreate() {
- return cmd("recreate", image);
- }
}
public static class JLinkTask {
--- a/langtools/.hgtags Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/.hgtags Thu Apr 28 23:08:17 2016 -0700
@@ -357,3 +357,4 @@
3d4117c36559b344a73f786d39cc7626b4d8e2c0 jdk-9+112
4e87682893e662421af10a62d29ae822ce0fea04 jdk-9+113
cba09a2e6ae969b029783eb59bb01017b78f8eef jdk-9+114
+31c8b18fdc5b94a2ddd5ea0694f350a2c907e9f7 jdk-9+115
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Thu Apr 28 23:08:17 2016 -0700
@@ -4491,10 +4491,11 @@
chk.checkNonCyclicElements(tree);
// Check for proper use of serialVersionUID
- if (env.info.lint.isEnabled(LintCategory.SERIAL) &&
- isSerializable(c.type) &&
- (c.flags() & Flags.ENUM) == 0 &&
- checkForSerial(c)) {
+ if (env.info.lint.isEnabled(LintCategory.SERIAL)
+ && isSerializable(c.type)
+ && (c.flags() & Flags.ENUM) == 0
+ && !c.isAnonymous()
+ && checkForSerial(c)) {
checkSerialVersionUID(tree, c);
}
if (allowTypeAnnos) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ConstFold.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ConstFold.java Thu Apr 28 23:08:17 2016 -0700
@@ -125,15 +125,15 @@
return syms.booleanType.constType(b2i(intValue(od) >= 0));
case lneg: // unary -
- return syms.longType.constType(new Long(-longValue(od)));
+ return syms.longType.constType(Long.valueOf(-longValue(od)));
case lxor: // ~
- return syms.longType.constType(new Long(~longValue(od)));
+ return syms.longType.constType(Long.valueOf(~longValue(od)));
case fneg: // unary -
- return syms.floatType.constType(new Float(-floatValue(od)));
+ return syms.floatType.constType(Float.valueOf(-floatValue(od)));
case dneg: // ~
- return syms.doubleType.constType(new Double(-doubleValue(od)));
+ return syms.doubleType.constType(Double.valueOf(-doubleValue(od)));
default:
return null;
@@ -216,37 +216,37 @@
case ladd:
return syms.longType.constType(
- new Long(longValue(l) + longValue(r)));
+ Long.valueOf(longValue(l) + longValue(r)));
case lsub:
return syms.longType.constType(
- new Long(longValue(l) - longValue(r)));
+ Long.valueOf(longValue(l) - longValue(r)));
case lmul:
return syms.longType.constType(
- new Long(longValue(l) * longValue(r)));
+ Long.valueOf(longValue(l) * longValue(r)));
case ldiv:
return syms.longType.constType(
- new Long(longValue(l) / longValue(r)));
+ Long.valueOf(longValue(l) / longValue(r)));
case lmod:
return syms.longType.constType(
- new Long(longValue(l) % longValue(r)));
+ Long.valueOf(longValue(l) % longValue(r)));
case land:
return syms.longType.constType(
- new Long(longValue(l) & longValue(r)));
+ Long.valueOf(longValue(l) & longValue(r)));
case lor:
return syms.longType.constType(
- new Long(longValue(l) | longValue(r)));
+ Long.valueOf(longValue(l) | longValue(r)));
case lxor:
return syms.longType.constType(
- new Long(longValue(l) ^ longValue(r)));
+ Long.valueOf(longValue(l) ^ longValue(r)));
case lshl: case lshll:
return syms.longType.constType(
- new Long(longValue(l) << intValue(r)));
+ Long.valueOf(longValue(l) << intValue(r)));
case lshr: case lshrl:
return syms.longType.constType(
- new Long(longValue(l) >> intValue(r)));
+ Long.valueOf(longValue(l) >> intValue(r)));
case lushr:
return syms.longType.constType(
- new Long(longValue(l) >>> intValue(r)));
+ Long.valueOf(longValue(l) >>> intValue(r)));
case lcmp:
if (longValue(l) < longValue(r))
return syms.intType.constType(minusOne);
@@ -256,19 +256,19 @@
return syms.intType.constType(zero);
case fadd:
return syms.floatType.constType(
- new Float(floatValue(l) + floatValue(r)));
+ Float.valueOf(floatValue(l) + floatValue(r)));
case fsub:
return syms.floatType.constType(
- new Float(floatValue(l) - floatValue(r)));
+ Float.valueOf(floatValue(l) - floatValue(r)));
case fmul:
return syms.floatType.constType(
- new Float(floatValue(l) * floatValue(r)));
+ Float.valueOf(floatValue(l) * floatValue(r)));
case fdiv:
return syms.floatType.constType(
- new Float(floatValue(l) / floatValue(r)));
+ Float.valueOf(floatValue(l) / floatValue(r)));
case fmod:
return syms.floatType.constType(
- new Float(floatValue(l) % floatValue(r)));
+ Float.valueOf(floatValue(l) % floatValue(r)));
case fcmpg: case fcmpl:
if (floatValue(l) < floatValue(r))
return syms.intType.constType(minusOne);
@@ -282,19 +282,19 @@
return syms.intType.constType(minusOne);
case dadd:
return syms.doubleType.constType(
- new Double(doubleValue(l) + doubleValue(r)));
+ Double.valueOf(doubleValue(l) + doubleValue(r)));
case dsub:
return syms.doubleType.constType(
- new Double(doubleValue(l) - doubleValue(r)));
+ Double.valueOf(doubleValue(l) - doubleValue(r)));
case dmul:
return syms.doubleType.constType(
- new Double(doubleValue(l) * doubleValue(r)));
+ Double.valueOf(doubleValue(l) * doubleValue(r)));
case ddiv:
return syms.doubleType.constType(
- new Double(doubleValue(l) / doubleValue(r)));
+ Double.valueOf(doubleValue(l) / doubleValue(r)));
case dmod:
return syms.doubleType.constType(
- new Double(doubleValue(l) % doubleValue(r)));
+ Double.valueOf(doubleValue(l) % doubleValue(r)));
case dcmpg: case dcmpl:
if (doubleValue(l) < doubleValue(r))
return syms.intType.constType(minusOne);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java Thu Apr 28 23:08:17 2016 -0700
@@ -86,6 +86,7 @@
private final TypeEnvs typeEnvs;
private final Name dollarAssertionsDisabled;
private final Name classDollar;
+ private final Name dollarCloseResource;
private final Types types;
private final boolean debugLower;
private final PkgInfo pkginfoOpt;
@@ -109,6 +110,8 @@
fromString(target.syntheticNameChar() + "assertionsDisabled");
classDollar = names.
fromString("class" + target.syntheticNameChar());
+ dollarCloseResource = names.
+ fromString(target.syntheticNameChar() + "closeResource");
types = Types.instance(context);
Options options = Options.instance(context);
@@ -1648,9 +1651,11 @@
ListBuffer<JCStatement> stats = new ListBuffer<>();
JCTree resource = resources.head;
JCExpression expr = null;
+ boolean resourceNonNull;
if (resource instanceof JCVariableDecl) {
JCVariableDecl var = (JCVariableDecl) resource;
expr = make.Ident(var.sym).setType(resource.type);
+ resourceNonNull = var.init != null && TreeInfo.skipParens(var.init).hasTag(NEWCLASS);
stats.add(var);
} else {
Assert.check(resource instanceof JCExpression);
@@ -1665,6 +1670,7 @@
JCVariableDecl syntheticTwrVarDecl =
make.VarDef(syntheticTwrVar, (JCExpression)resource);
expr = (JCExpression)make.Ident(syntheticTwrVar);
+ resourceNonNull = TreeInfo.skipParens(resource).hasTag(NEWCLASS);
stats.add(syntheticTwrVarDecl);
}
@@ -1694,7 +1700,7 @@
int oldPos = make.pos;
make.at(TreeInfo.endPos(block));
- JCBlock finallyClause = makeTwrFinallyClause(primaryException, expr);
+ JCBlock finallyClause = makeTwrFinallyClause(primaryException, expr, resourceNonNull);
make.at(oldPos);
JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block,
finallyCanCompleteNormally, depth + 1),
@@ -1706,7 +1712,96 @@
return newBlock;
}
- private JCBlock makeTwrFinallyClause(Symbol primaryException, JCExpression resource) {
+ /**If the estimated number of copies the close resource code in a single class is above this
+ * threshold, generate and use a method for the close resource code, leading to smaller code.
+ * As generating a method has overhead on its own, generating the method for cases below the
+ * threshold could lead to an increase in code size.
+ */
+ public static final int USE_CLOSE_RESOURCE_METHOD_THRESHOLD = 4;
+
+ private JCBlock makeTwrFinallyClause(Symbol primaryException, JCExpression resource,
+ boolean resourceNonNull) {
+ MethodSymbol closeResource = (MethodSymbol)lookupSynthetic(dollarCloseResource,
+ currentClass.members());
+
+ if (closeResource == null && shouldUseCloseResourceMethod()) {
+ closeResource = new MethodSymbol(
+ PRIVATE | STATIC | SYNTHETIC,
+ dollarCloseResource,
+ new MethodType(
+ List.of(syms.throwableType, syms.autoCloseableType),
+ syms.voidType,
+ List.<Type>nil(),
+ syms.methodClass),
+ currentClass);
+ enterSynthetic(resource.pos(), closeResource, currentClass.members());
+
+ JCMethodDecl md = make.MethodDef(closeResource, null);
+ List<JCVariableDecl> params = md.getParameters();
+ md.body = make.Block(0, List.<JCStatement>of(makeTwrCloseStatement(params.get(0).sym,
+ make.Ident(params.get(1)))));
+
+ JCClassDecl currentClassDecl = classDef(currentClass);
+ currentClassDecl.defs = currentClassDecl.defs.prepend(md);
+ }
+
+ JCStatement closeStatement;
+
+ if (closeResource != null) {
+ //$closeResource(#primaryException, #resource)
+ closeStatement = make.Exec(make.Apply(List.<JCExpression>nil(),
+ make.Ident(closeResource),
+ List.of(make.Ident(primaryException),
+ resource)
+ ).setType(syms.voidType));
+ } else {
+ closeStatement = makeTwrCloseStatement(primaryException, resource);
+ }
+
+ JCStatement finallyStatement;
+
+ if (resourceNonNull) {
+ finallyStatement = closeStatement;
+ } else {
+ // if (#resource != null) { $closeResource(...); }
+ finallyStatement = make.If(makeNonNullCheck(resource),
+ closeStatement,
+ null);
+ }
+
+ return make.Block(0L,
+ List.<JCStatement>of(finallyStatement));
+ }
+ //where:
+ private boolean shouldUseCloseResourceMethod() {
+ class TryFinder extends TreeScanner {
+ int closeCount;
+ @Override
+ public void visitTry(JCTry tree) {
+ boolean empty = tree.body.stats.isEmpty();
+
+ for (JCTree r : tree.resources) {
+ closeCount += empty ? 1 : 2;
+ empty = false; //with multiple resources, only the innermost try can be empty.
+ }
+ super.visitTry(tree);
+ }
+ @Override
+ public void scan(JCTree tree) {
+ if (useCloseResourceMethod())
+ return;
+ super.scan(tree);
+ }
+ boolean useCloseResourceMethod() {
+ return closeCount >= USE_CLOSE_RESOURCE_METHOD_THRESHOLD;
+ }
+ }
+ TryFinder tryFinder = new TryFinder();
+ tryFinder.scan(classDef(currentClass));
+ return tryFinder.useCloseResourceMethod();
+ }
+
+ private JCStatement makeTwrCloseStatement(Symbol primaryException, JCExpression resource) {
// primaryException.addSuppressed(catchException);
VarSymbol catchException =
new VarSymbol(SYNTHETIC, make.paramName(2),
@@ -1731,11 +1826,7 @@
tryTree,
makeResourceCloseInvocation(resource));
- // if (#resource != null) { if (primaryException ... }
- return make.Block(0L,
- List.<JCStatement>of(make.If(makeNonNullCheck(resource),
- closeIfStatement,
- null)));
+ return closeIfStatement;
}
private JCStatement makeResourceCloseInvocation(JCExpression resource) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,27 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
package com.sun.tools.javac.file;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu Apr 28 23:08:17 2016 -0700
@@ -457,13 +457,13 @@
poolObj[i] = getInt(index + 1);
break;
case CONSTANT_Float:
- poolObj[i] = new Float(getFloat(index + 1));
+ poolObj[i] = Float.valueOf(getFloat(index + 1));
break;
case CONSTANT_Long:
- poolObj[i] = new Long(getLong(index + 1));
+ poolObj[i] = Long.valueOf(getLong(index + 1));
break;
case CONSTANT_Double:
- poolObj[i] = new Double(getDouble(index + 1));
+ poolObj[i] = Double.valueOf(getDouble(index + 1));
break;
case CONSTANT_MethodHandle:
skipBytes(4);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java Thu Apr 28 23:08:17 2016 -0700
@@ -203,7 +203,7 @@
*/
void emitMinusOne(int tc) {
if (tc == LONGcode) {
- items.makeImmediateItem(syms.longType, new Long(-1)).load();
+ items.makeImmediateItem(syms.longType, Long.valueOf(-1)).load();
} else {
code.emitop0(iconst_m1);
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Apr 28 23:08:17 2016 -0700
@@ -686,7 +686,7 @@
try {
t = F.at(pos).Literal(
TypeTag.LONG,
- new Long(Convert.string2long(strval(prefix), token.radix())));
+ Long.valueOf(Convert.string2long(strval(prefix), token.radix())));
} catch (NumberFormatException ex) {
error(token.pos, "int.number.too.large", strval(prefix));
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java Thu Apr 28 23:08:17 2016 -0700
@@ -26,8 +26,6 @@
package com.sun.tools.sjavac;
import java.io.File;
-import java.io.IOException;
-import java.io.Writer;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
@@ -42,9 +40,8 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
-import java.util.regex.Pattern;
-import java.util.stream.Stream;
+import com.sun.tools.javac.main.Main.Result;
import com.sun.tools.sjavac.comp.CompilationService;
import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.pubapi.PubApi;
@@ -283,7 +280,7 @@
}
// Check the return values.
- if (subResult.returnCode != 0) {
+ if (subResult.result != Result.OK) {
rc = false;
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/ClientMain.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/ClientMain.java Thu Apr 28 23:08:17 2016 -0700
@@ -28,6 +28,8 @@
import java.io.OutputStreamWriter;
import java.io.Writer;
+import com.sun.tools.javac.main.Main;
+import com.sun.tools.javac.main.Main.Result;
import com.sun.tools.sjavac.AutoFlushWriter;
import com.sun.tools.sjavac.Log;
import com.sun.tools.sjavac.Util;
@@ -58,7 +60,7 @@
options = Options.parseArgs(args);
} catch (IllegalArgumentException e) {
Log.error(e.getMessage());
- return -1;
+ return Result.CMDERR.exitCode;
}
Log.setLogLevel(options.getLogLevel());
@@ -73,13 +75,13 @@
Sjavac sjavac = useServer ? new SjavacClient(options) : new SjavacImpl();
// Perform compilation
- int rc = sjavac.compile(args);
+ Result result = sjavac.compile(args);
// If sjavac is running in the foreground we should shut it down at this point
if (!useServer) {
sjavac.shutdown();
}
- return rc;
+ return result.exitCode;
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java Thu Apr 28 23:08:17 2016 -0700
@@ -26,23 +26,20 @@
package com.sun.tools.sjavac.client;
import java.io.BufferedReader;
-import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
-import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Reader;
-import java.io.Writer;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import java.util.Scanner;
-import java.util.stream.Stream;
+import com.sun.tools.javac.main.Main;
+import com.sun.tools.javac.main.Main.Result;
import com.sun.tools.sjavac.Log;
import com.sun.tools.sjavac.Util;
import com.sun.tools.sjavac.options.OptionHelper;
@@ -116,8 +113,8 @@
}
@Override
- public int compile(String[] args) {
- int result = -1;
+ public Result compile(String[] args) {
+ Result result = null;
try (Socket socket = tryConnect()) {
PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
@@ -150,22 +147,28 @@
}
if (type.equals(SjavacServer.LINE_TYPE_RC)) {
- result = Integer.parseInt(content);
+ result = Main.Result.valueOf(content);
}
}
} catch (PortFileInaccessibleException e) {
Log.error("Port file inaccessible.");
- result = CompilationSubResult.ERROR_FATAL;
+ result = Result.ERROR;
} catch (IOException ioe) {
Log.error("IOException caught during compilation: " + ioe.getMessage());
Log.debug(ioe);
- result = CompilationSubResult.ERROR_FATAL;
+ result = Result.ERROR;
} catch (InterruptedException ie) {
Thread.currentThread().interrupt(); // Restore interrupt
Log.error("Compilation interrupted.");
Log.debug(ie);
- result = CompilationSubResult.ERROR_FATAL;
+ result = Result.ERROR;
}
+
+ if (result == null) {
+ // No LINE_TYPE_RC was found.
+ result = Result.ERROR;
+ }
+
return result;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/CompilationService.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/CompilationService.java Thu Apr 28 23:08:17 2016 -0700
@@ -42,6 +42,8 @@
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.main.Main;
+import com.sun.tools.javac.main.Main.Result;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Dependencies;
import com.sun.tools.javac.util.ListBuffer;
@@ -80,7 +82,7 @@
Dependencies.GraphDependencies.preRegister(context);
// Now setup the actual compilation
- CompilationSubResult compilationResult = new CompilationSubResult(0);
+ CompilationSubResult compilationResult = new CompilationSubResult(Result.OK);
// First deal with explicit source files on cmdline and in at file
ListBuffer<JavaFileObject> explicitJFOs = new ListBuffer<>();
@@ -97,7 +99,7 @@
// Create a log to capture compiler output
StringWriter stderrLog = new StringWriter();
- com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK;
+ Result result;
PublicApiCollector pubApiCollector = new PublicApiCollector(context, explicitJFOs);
PathAndPackageVerifier papVerifier = new PathAndPackageVerifier();
NewDependencyCollector depsCollector = new NewDependencyCollector(context, explicitJFOs);
@@ -120,20 +122,23 @@
task.addTaskListener(pubApiCollector);
task.addTaskListener(papVerifier);
logJavacInvocation(args);
- rc = task.doCall();
- Log.debug("javac returned with code " + rc);
+ result = task.doCall();
+ Log.debug("javac result: " + result);
sfm.flush();
+ } else {
+ result = Result.ERROR;
}
} catch (Exception e) {
Log.error(Util.getStackTrace(e));
stderrLog.append(Util.getStackTrace(e));
- rc = com.sun.tools.javac.main.Main.Result.ERROR;
+ result = Result.ERROR;
}
compilationResult.packageArtifacts = sfm.getPackageArtifacts();
- if (papVerifier.errorsDiscovered())
- rc = com.sun.tools.javac.main.Main.Result.ERROR;
+ if (papVerifier.errorsDiscovered()) {
+ result = Result.ERROR;
+ }
compilationResult.packageDependencies = depsCollector.getDependencies(false);
compilationResult.packageCpDependencies = depsCollector.getDependencies(true);
@@ -141,7 +146,7 @@
compilationResult.packagePubapis = pubApiCollector.getPubApis(true);
compilationResult.dependencyPubapis = pubApiCollector.getPubApis(false);
compilationResult.stderr = stderrLog.toString();
- compilationResult.returnCode = rc.exitCode;
+ compilationResult.result = result;
return compilationResult;
} catch (IOException e) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PooledSjavac.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PooledSjavac.java Thu Apr 28 23:08:17 2016 -0700
@@ -25,6 +25,7 @@
package com.sun.tools.sjavac.comp;
+import com.sun.tools.javac.main.Main.Result;
import com.sun.tools.sjavac.Log;
import com.sun.tools.sjavac.server.Sjavac;
@@ -54,7 +55,7 @@
}
@Override
- public int compile(String[] args) {
+ public Result compile(String[] args) {
Log log = Log.get();
try {
return pool.submit(() -> {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -41,6 +41,7 @@
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.main.Main;
+import com.sun.tools.javac.main.Main.Result;
import com.sun.tools.javac.util.Context;
import com.sun.tools.sjavac.JavacState;
import com.sun.tools.sjavac.Log;
@@ -69,36 +70,36 @@
public class SjavacImpl implements Sjavac {
@Override
- public int compile(String[] args) {
+ public Result compile(String[] args) {
Options options;
try {
options = Options.parseArgs(args);
} catch (IllegalArgumentException e) {
Log.error(e.getMessage());
- return RC_FATAL;
+ return Result.CMDERR;
}
if (!validateOptions(options))
- return RC_FATAL;
+ return Result.CMDERR;
if (srcDstOverlap(options.getSources(), options.getDestDir())) {
- return RC_FATAL;
+ return Result.CMDERR;
}
if (!createIfMissing(options.getDestDir()))
- return RC_FATAL;
+ return Result.ERROR;
Path stateDir = options.getStateDir();
if (stateDir != null && !createIfMissing(options.getStateDir()))
- return RC_FATAL;
+ return Result.ERROR;
Path gensrc = options.getGenSrcDir();
if (gensrc != null && !createIfMissing(gensrc))
- return RC_FATAL;
+ return Result.ERROR;
Path hdrdir = options.getHeaderDir();
if (hdrdir != null && !createIfMissing(hdrdir))
- return RC_FATAL;
+ return Result.ERROR;
if (stateDir == null) {
// Prepare context. Direct logging to our byte array stream.
@@ -113,7 +114,7 @@
.filter(arg -> !arg.startsWith(Option.SERVER.arg))
.toArray(String[]::new);
// Compile
- Main.Result result = new Main("javac", printWriter).compile(passThroughArgs, context);
+ Result result = new Main("javac", printWriter).compile(passThroughArgs, context);
// Process compiler output (which is always errors)
printWriter.flush();
@@ -128,7 +129,7 @@
throw new UncheckedIOException(es);
}
}
- return result.exitCode;
+ return result;
} else {
// Load the prev build state database.
@@ -166,7 +167,7 @@
if (sources.isEmpty()) {
Log.error("Found nothing to compile!");
- return RC_FATAL;
+ return Result.ERROR;
}
@@ -292,15 +293,15 @@
javac_state.removeSuperfluousArtifacts(recently_compiled);
}
- return rc[0] ? RC_OK : RC_FATAL;
+ return rc[0] ? Result.OK : Result.ERROR;
} catch (ProblemException e) {
// For instance make file list mismatch.
Log.error(e.getMessage());
Log.debug(e);
- return RC_FATAL;
+ return Result.ERROR;
} catch (Exception e) {
Log.error(e);
- return RC_FATAL;
+ return Result.ERROR;
}
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilationSubResult.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilationSubResult.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
import java.util.Map;
import java.util.Set;
+import com.sun.tools.javac.main.Main.Result;
import com.sun.tools.sjavac.pubapi.PubApi;
/**
@@ -44,10 +45,7 @@
static final long serialVersionUID = 46739181113L;
- // Return code constants
- public final static int ERROR_FATAL = -1;
-
- public int returnCode;
+ public Result result;
public Map<String, Set<URI>> packageArtifacts = new HashMap<>();
public Map<String, Map<String, Set<String>>> packageDependencies = new HashMap<>();
public Map<String, Map<String, Set<String>>> packageCpDependencies = new HashMap<>();
@@ -56,11 +54,11 @@
public String stdout = "";
public String stderr = "";
- public CompilationSubResult(int returnCode) {
- this.returnCode = returnCode;
+ public CompilationSubResult(Result result) {
+ this.result = result;
}
- public void setReturnCode(int returnCode) {
- this.returnCode = returnCode;
+ public void setResult(Result result) {
+ this.result = result;
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/IdleResetSjavac.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/IdleResetSjavac.java Thu Apr 28 23:08:17 2016 -0700
@@ -25,11 +25,9 @@
package com.sun.tools.sjavac.server;
+import com.sun.tools.javac.main.Main.Result;
import com.sun.tools.sjavac.Log;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
import java.util.Timer;
import java.util.TimerTask;
@@ -66,7 +64,7 @@
}
@Override
- public int compile(String[] args) {
+ public Result compile(String[] args) {
startCall();
try {
return delegate.compile(args);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/RequestHandler.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/RequestHandler.java Thu Apr 28 23:08:17 2016 -0700
@@ -25,6 +25,7 @@
package com.sun.tools.sjavac.server;
+import com.sun.tools.javac.main.Main;
import com.sun.tools.sjavac.Log;
import com.sun.tools.sjavac.Util;
@@ -100,10 +101,10 @@
checkInternalErrorLog();
// Perform compilation
- int rc = sjavac.compile(args);
+ Main.Result rc = sjavac.compile(args);
// Send return code back to client
- out.println(LINE_TYPE_RC + ":" + rc);
+ out.println(LINE_TYPE_RC + ":" + rc.name());
// Check for internal errors again.
checkInternalErrorLog();
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/ServerMain.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/ServerMain.java Thu Apr 28 23:08:17 2016 -0700
@@ -32,6 +32,8 @@
import java.io.PrintStream;
import java.lang.Thread.UncaughtExceptionHandler;
+import com.sun.tools.javac.main.Main;
+import com.sun.tools.javac.main.Main.Result;
import com.sun.tools.sjavac.Log;
import com.sun.tools.sjavac.Log.Level;
import com.sun.tools.sjavac.server.log.LazyInitFileLog;
@@ -75,7 +77,7 @@
// Any options other than --startserver?
if (args.length > 1) {
Log.error("When spawning a background server, only a single --startserver argument is allowed.");
- return 1;
+ return Result.CMDERR.exitCode;
}
int exitCode;
@@ -84,7 +86,7 @@
exitCode = server.startServer();
} catch (IOException | InterruptedException ex) {
ex.printStackTrace();
- exitCode = -1;
+ exitCode = Result.ERROR.exitCode;
}
return exitCode;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/Sjavac.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/Sjavac.java Thu Apr 28 23:08:17 2016 -0700
@@ -25,6 +25,8 @@
package com.sun.tools.sjavac.server;
+import com.sun.tools.javac.main.Main.Result;
+
import java.io.Writer;
@@ -38,10 +40,6 @@
* deletion without notice.</b>
*/
public interface Sjavac {
-
- final static int RC_FATAL = -1;
- final static int RC_OK = 0;
-
- int compile(String[] args);
+ Result compile(String[] args);
void shutdown();
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/SjavacServer.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/SjavacServer.java Thu Apr 28 23:08:17 2016 -0700
@@ -40,6 +40,8 @@
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
+import com.sun.tools.javac.main.Main;
+import com.sun.tools.javac.main.Main.Result;
import com.sun.tools.sjavac.Log;
import com.sun.tools.sjavac.Util;
import com.sun.tools.sjavac.client.PortFileInaccessibleException;
@@ -167,7 +169,7 @@
if (portFile.containsPortInfo()) {
Log.debug("Javac server not started because portfile exists!");
portFile.unlock();
- return -1;
+ return Result.ERROR.exitCode;
}
// .-----------. .--------. .------.
@@ -221,7 +223,7 @@
// Shut down
sjavac.shutdown();
- return 0;
+ return Result.OK.exitCode;
}
@Override
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteAgent.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteAgent.java Thu Apr 28 23:08:17 2016 -0700
@@ -113,7 +113,6 @@
}
Method doitMethod;
try {
- this.getClass().getModule().addReads(klass.getModule());
this.getClass().getModule().addExports(RemoteResolutionException.class.getPackage().getName(), klass.getModule());
doitMethod = klass.getDeclaredMethod(DOIT_METHOD_NAME, new Class<?>[0]);
doitMethod.setAccessible(true);
@@ -184,7 +183,6 @@
break;
}
try {
- this.getClass().getModule().addReads(klass.getModule());
Field var = klass.getDeclaredField(varname);
var.setAccessible(true);
Object res = var.get(null);
@@ -264,9 +262,14 @@
}
}
+ /**
+ * Expunge internal info from string
+ * @param s string to process
+ * @return string the display, JShell package and wrapper class names removed
+ */
static String expunge(String s) {
StringBuilder sb = new StringBuilder();
- for (String comp : prefixPattern.split(s)) {
+ for (String comp : PREFIX_PATTERN.split(s)) {
sb.append(comp);
}
return sb.toString();
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteCodes.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteCodes.java Thu Apr 28 23:08:17 2016 -0700
@@ -47,8 +47,12 @@
public static final int RESULT_CORRALLED = 103;
public static final int RESULT_KILLED = 104;
+ // String constants
+ public static final String REPL_PACKAGE = "REPL";
+ public static final String REPL_CLASS_PREFIX = "$JShell$";
public static final String DOIT_METHOD_NAME = "do_it$";
- public static final String replClass = "\\$REPL(?<num>\\d+)[A-Z]*";
- public static final Pattern prefixPattern = Pattern.compile("(REPL\\.)?" + replClass + "[\\$\\.]?");
-
+ public static final Pattern PREFIX_PATTERN = Pattern.compile(
+ "(" + REPL_PACKAGE + "\\.)?" +
+ "(?<class>" + Pattern.quote(REPL_CLASS_PREFIX) +
+ "\\w+" + ")" + "[\\$\\.]?");
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java Thu Apr 28 23:08:17 2016 -0700
@@ -606,6 +606,7 @@
fluffmsg("jshell.msg.feedback.mode", mode.name);
} else {
fluffmsg("jshell.msg.see", "/help /set feedback");
+ printFeedbackModes();
}
return valid;
}
@@ -671,13 +672,17 @@
} else {
errorat("jshell.err.feedback.ambiguous.mode", umode);
}
- fluffmsg("jshell.msg.feedback.mode.following");
- modeMap.keySet().stream()
- .forEach(mk -> fluff(" %s", mk));
+ printFeedbackModes();
return null;
}
}
+ void printFeedbackModes() {
+ fluffmsg("jshell.msg.feedback.mode.following");
+ modeMap.keySet().stream()
+ .forEach(mk -> fluff(" %s", mk));
+ }
+
// Test if the format string is correctly
final String nextFormat() {
String format = at.next();
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Thu Apr 28 23:08:17 2016 -0700
@@ -512,7 +512,7 @@
/set format verbose errorpre '| ' \n\
/set format verbose errorpost '%n' \n\
\n\
-/set format verbose errorline '{pre} {err}' \n\
+/set format verbose errorline '{post}{pre} {err}' \n\
\n\
/set format verbose action 'created' added-primary \n\
/set format verbose action 'modified' modified-primary \n\
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ClassTracker.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ClassTracker.java Thu Apr 28 23:08:17 2016 -0700
@@ -27,6 +27,7 @@
import java.util.Arrays;
import java.util.HashMap;
+import java.util.Objects;
import com.sun.jdi.ReferenceType;
/**
@@ -82,6 +83,17 @@
}
return rt;
}
+
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof ClassInfo &&
+ ((ClassInfo) o).className.equals(className);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.className);
+ }
}
ClassInfo classInfo(String className, byte[] bytes) {
@@ -93,5 +105,4 @@
ClassInfo get(String className) {
return map.get(className);
}
-
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/DeclarationSnippet.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/DeclarationSnippet.java Thu Apr 28 23:08:17 2016 -0700
@@ -84,6 +84,6 @@
@Override
String importLine(JShell state) {
- return "import static " + state.maps.classFullName(this) + "." + name() + ";\n";
+ return "import static " + classFullName() + "." + name() + ";\n";
}
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Diag.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Diag.java Thu Apr 28 23:08:17 2016 -0700
@@ -100,10 +100,12 @@
// *** Internal support ***
/**
- * Internal: If this is from a compile, extract the compilation Unit.
+ * Internal: If this is from a compile/analyze wrapped in an outer class, extract the snippet.
* Otherwise null.
*/
- abstract Unit unitOrNull();
+ Snippet snippetOrNull() {
+ return null;
+ }
/**
* This is an unreachable-statement error
@@ -124,6 +126,7 @@
*/
boolean isResolutionError() {
//TODO: try javac RESOLVE_ERROR flag
- return getCode().startsWith("compiler.err.cant.resolve");
+ return getCode().startsWith("compiler.err.cant.resolve")
+ || getCode().equals("compiler.err.cant.apply.symbol");
}
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/DiagList.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/DiagList.java Thu Apr 28 23:08:17 2016 -0700
@@ -106,7 +106,10 @@
DiagList ofUnit(Unit u) {
return this.stream()
- .filter(d -> d.unitOrNull() == u)
+ .filter(d -> {
+ Snippet snn = d.snippetOrNull();
+ return snn == u.snippet();
+ })
.collect(Collectors.toCollection(() -> new DiagList()));
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,6 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-
package jdk.jshell;
import java.util.ArrayList;
@@ -50,7 +49,6 @@
import java.io.Writer;
import java.util.LinkedHashSet;
import java.util.Set;
-import com.sun.tools.javac.util.Context;
import jdk.jshell.ClassTracker.ClassInfo;
import jdk.jshell.Key.ErroneousKey;
import jdk.jshell.Key.MethodKey;
@@ -68,7 +66,7 @@
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
import static jdk.jshell.Util.*;
import static jdk.internal.jshell.remote.RemoteCodes.DOIT_METHOD_NAME;
-import static jdk.internal.jshell.remote.RemoteCodes.prefixPattern;
+import static jdk.internal.jshell.remote.RemoteCodes.PREFIX_PATTERN;
import static jdk.jshell.Snippet.SubKind.SINGLE_TYPE_IMPORT_SUBKIND;
import static jdk.jshell.Snippet.SubKind.SINGLE_STATIC_IMPORT_SUBKIND;
import static jdk.jshell.Snippet.SubKind.TYPE_IMPORT_ON_DEMAND_SUBKIND;
@@ -339,18 +337,8 @@
return declare(snip);
}
- private OuterWrap wrapInClass(String className, Set<Key> except, String userSource, Wrap guts, Collection<Snippet> plus) {
- String imports = state.maps.packageAndImportsExcept(except, plus);
- return OuterWrap.wrapInClass(state.maps.packageName(), className, imports, userSource, guts);
- }
-
- OuterWrap wrapInClass(Snippet snip, Set<Key> except, Wrap guts, Collection<Snippet> plus) {
- return wrapInClass(snip.className(), except, snip.source(), guts, plus);
- }
-
private AnalyzeTask trialCompile(Wrap guts) {
- OuterWrap outer = wrapInClass(REPL_DOESNOTMATTER_CLASS_NAME,
- Collections.emptySet(), "", guts, null);
+ OuterWrap outer = state.outerMap.wrapInTrialClass(guts);
return state.taskFactory.new AnalyzeTask(outer);
}
@@ -468,7 +456,7 @@
if (si.status().isDefined) {
if (si.isExecutable()) {
try {
- value = state.executionControl().commandInvoke(state.maps.classFullName(si));
+ value = state.executionControl().commandInvoke(si.classFullName());
value = si.subKind().hasValue()
? expunge(value)
: "";
@@ -504,37 +492,54 @@
return events(c, outs, value, exception);
}
+ private boolean interestingEvent(SnippetEvent e) {
+ return e.isSignatureChange()
+ || e.causeSnippet() == null
+ || e.status() != e.previousStatus()
+ || e.exception() != null;
+ }
+
private List<SnippetEvent> events(Unit c, Collection<Unit> outs, String value, Exception exception) {
List<SnippetEvent> events = new ArrayList<>();
events.add(c.event(value, exception));
events.addAll(outs.stream()
.filter(u -> u != c)
.map(u -> u.event(null, null))
+ .filter(this::interestingEvent)
.collect(Collectors.toList()));
events.addAll(outs.stream()
.flatMap(u -> u.secondaryEvents().stream())
+ .filter(this::interestingEvent)
.collect(Collectors.toList()));
//System.err.printf("Events: %s\n", events);
return events;
}
+ private Set<OuterWrap> outerWrapSet(Collection<Unit> units) {
+ return units.stream()
+ .map(u -> u.snippet().outerWrap())
+ .collect(toSet());
+ }
+
private Set<Unit> compileAndLoad(Set<Unit> ins) {
if (ins.isEmpty()) {
return ins;
}
Set<Unit> replaced = new LinkedHashSet<>();
+ // Loop until dependencies and errors are stable
while (true) {
state.debug(DBG_GEN, "compileAndLoad %s\n", ins);
- ins.stream().forEach(u -> u.initialize(ins));
- AnalyzeTask at = state.taskFactory.new AnalyzeTask(ins);
+ ins.stream().forEach(u -> u.initialize());
+ ins.stream().forEach(u -> u.setWrap(ins, ins));
+ AnalyzeTask at = state.taskFactory.new AnalyzeTask(outerWrapSet(ins));
ins.stream().forEach(u -> u.setDiagnostics(at));
// corral any Snippets that need it
AnalyzeTask cat;
if (ins.stream().anyMatch(u -> u.corralIfNeeded(ins))) {
// if any were corralled, re-analyze everything
- cat = state.taskFactory.new AnalyzeTask(ins);
+ cat = state.taskFactory.new AnalyzeTask(outerWrapSet(ins));
ins.stream().forEach(u -> u.setCorralledDiagnostics(cat));
} else {
cat = at;
@@ -556,7 +561,7 @@
legit.stream().forEach(u -> u.setWrap(ins, legit));
// generate class files for those capable
- CompileTask ct = state.taskFactory.new CompileTask(legit);
+ CompileTask ct = state.taskFactory.new CompileTask(outerWrapSet(legit));
if (!ct.compile()) {
// oy! compile failed because of recursive new unresolved
if (legit.stream()
@@ -572,8 +577,8 @@
// load all new classes
load(legit.stream()
- .flatMap(u -> u.classesToLoad(ct.classInfoList(u)))
- .collect(toList()));
+ .flatMap(u -> u.classesToLoad(ct.classInfoList(u.snippet().outerWrap())))
+ .collect(toSet()));
// attempt to redefine the remaining classes
List<Unit> toReplace = legit.stream()
.filter(u -> !u.doRedefines())
@@ -607,7 +612,7 @@
}
}
- private void load(List<ClassInfo> cil) {
+ private void load(Set<ClassInfo> cil) {
if (!cil.isEmpty()) {
state.executionControl().commandLoad(cil);
}
@@ -625,20 +630,14 @@
StackTraceElement[] elems = new StackTraceElement[last + 1];
for (int i = 0; i <= last; ++i) {
StackTraceElement r = raw[i];
- String rawKlass = r.getClassName();
- Matcher matcher = prefixPattern.matcher(rawKlass);
- String num;
- if (matcher.find() && (num = matcher.group("num")) != null) {
- int end = matcher.end();
- if (rawKlass.charAt(end - 1) == '$') {
- --end;
- }
- int id = Integer.parseInt(num);
- Snippet si = state.maps.getSnippet(id);
- String klass = expunge(rawKlass);
+ OuterSnippetsClassWrap outer = state.outerMap.getOuter(r.getClassName());
+ if (outer != null) {
+ String klass = expunge(r.getClassName());
String method = r.getMethodName().equals(DOIT_METHOD_NAME) ? "" : r.getMethodName();
- String file = "#" + id;
- int line = si.outerWrap().wrapLineToSnippetLine(r.getLineNumber() - 1) + 1;
+ int wln = r.getLineNumber() - 1;
+ int line = outer.wrapLineToSnippetLine(wln) + 1;
+ Snippet sn = outer.wrapLineToSnippet(wln);
+ String file = "#" + sn.id();
elems[i] = new StackTraceElement(klass, method, file, line);
} else if (r.getFileName().equals("<none>")) {
elems[i] = new StackTraceElement(r.getClassName(), r.getMethodName(), null, r.getLineNumber());
@@ -654,7 +653,7 @@
}
private boolean isWrap(StackTraceElement ste) {
- return prefixPattern.matcher(ste.getClassName()).find();
+ return PREFIX_PATTERN.matcher(ste.getClassName()).find();
}
private DiagList modifierDiagnostics(ModifiersTree modtree,
@@ -714,11 +713,6 @@
public String getMessage(Locale locale) {
return message;
}
-
- @Override
- Unit unitOrNull() {
- return null;
- }
}
List<Modifier> list = new ArrayList<>();
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ExecutionControl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ExecutionControl.java Thu Apr 28 23:08:17 2016 -0700
@@ -36,6 +36,7 @@
import java.net.Socket;
import com.sun.jdi.*;
import java.io.EOFException;
+import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -94,7 +95,7 @@
}
- boolean commandLoad(List<ClassInfo> cil) {
+ boolean commandLoad(Collection<ClassInfo> cil) {
try {
out.writeInt(CMD_LOAD);
out.writeInt(cil.size());
@@ -122,7 +123,7 @@
String result = in.readUTF();
return result;
}
- } catch (IOException | ClassNotFoundException ex) {
+ } catch (IOException | RuntimeException ex) {
if (!env.connection().isRunning()) {
env.shutdown();
} else {
@@ -204,7 +205,7 @@
}
}
- private boolean readAndReportExecutionResult() throws IOException, ClassNotFoundException, EvalException, UnresolvedReferenceException {
+ private boolean readAndReportExecutionResult() throws IOException, EvalException, UnresolvedReferenceException {
int ok = in.readInt();
switch (ok) {
case RESULT_SUCCESS:
@@ -224,7 +225,7 @@
case RESULT_CORRALLED: {
int id = in.readInt();
StackTraceElement[] elems = readStackTrace();
- Snippet si = maps.getSnippet(id);
+ Snippet si = maps.getSnippetDeadOrAlive(id);
throw new UnresolvedReferenceException((DeclarationSnippet) si, elems);
}
case RESULT_KILLED: {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Thu Apr 28 23:08:17 2016 -0700
@@ -77,6 +77,7 @@
final SnippetMaps maps;
final KeyMap keyMap;
+ final OuterWrapMap outerMap;
final TaskFactory taskFactory;
final InputStream in;
final PrintStream out;
@@ -106,8 +107,8 @@
this.idGenerator = b.idGenerator;
this.maps = new SnippetMaps(this);
- maps.setPackageName("REPL");
this.keyMap = new KeyMap(this);
+ this.outerMap = new OuterWrapMap(this);
this.taskFactory = new TaskFactory(this);
this.eval = new Eval(this);
this.classTracker = new ClassTracker(this);
@@ -563,7 +564,7 @@
throw new IllegalArgumentException(
messageFormat("jshell.exc.var.not.valid", snippet, snippet.status()));
}
- String value = executionControl().commandVarValue(maps.classFullName(snippet), snippet.name());
+ String value = executionControl().commandVarValue(snippet.classFullName(), snippet.name());
return expunge(value);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterImportSnippetWrap.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import java.util.IdentityHashMap;
+import java.util.List;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+
+/**
+ * The outer wrap for a set of snippets wrapped in a generated class
+ * @author Robert Field
+ */
+public class OuterImportSnippetWrap extends OuterWrap {
+
+ private final Snippet snippet;
+
+ OuterImportSnippetWrap(Wrap wrap, Snippet snippet) {
+ super(wrap);
+ this.snippet = snippet;
+ }
+
+ @Override
+ Diag wrapDiag(Diagnostic<? extends JavaFileObject> d) {
+ return new WrappedDiagnostic(d) {
+
+ @Override
+ Snippet snippetOrNull() {
+ return snippet;
+ }
+ };
+ }
+
+ @Override
+ public String toString() {
+ return "OISW(" + w + ")";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterSnippetsClassWrap.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+import jdk.jshell.Wrap.CompoundWrap;
+
+/**
+ * The outer wrap for a set of snippets wrapped in a generated class
+ * @author Robert Field
+ */
+public class OuterSnippetsClassWrap extends OuterWrap {
+
+ private final String className;
+ private final LinkedHashMap<Wrap, Snippet> wrapToSnippet;
+
+ OuterSnippetsClassWrap(String className, CompoundWrap w, List<Snippet> snippets, List<Wrap> wraps) {
+ super(w);
+ assert snippets == null || snippets.size() == wraps.size();
+ this.className = className;
+ wrapToSnippet = new LinkedHashMap<>();
+ for (int i = 0; i < snippets.size(); ++i) {
+ wrapToSnippet.put(wraps.get(i), snippets.get(i));
+ }
+ }
+
+ public Snippet wrapLineToSnippet(int wline) {
+ Wrap wrap = ((CompoundWrap)w).wrapLineToWrap(wline);
+ return wrapToSnippet.get(wrap);
+ }
+
+ @Override
+ Diag wrapDiag(Diagnostic<? extends JavaFileObject> d) {
+ return new WrappedDiagnostic(d) {
+
+ @Override
+ Snippet snippetOrNull() {
+ Wrap wrap = ((CompoundWrap) w).wrapIndexToWrap(diag.getPosition());
+ Snippet sn = wrapToSnippet.get(wrap);
+ if (sn != null) {
+ return sn;
+ } else {
+ return super.snippetOrNull();
+ }
+ }
+ };
+ }
+
+ int ordinal(Snippet sn) {
+ int i = 0;
+ for (Snippet si : wrapToSnippet.values()) {
+ if (si == sn) {
+ return i;
+ }
+ ++i;
+ }
+ return -1;
+ }
+
+ @Override
+ public String className() {
+ return className;
+ }
+
+ @Override
+ public String toString() {
+ return "OSCW(" + className + ":" + w + ")";
+ }
+}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterWrap.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterWrap.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015-2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,47 +25,23 @@
package jdk.jshell;
-import jdk.jshell.Wrap.CompoundWrap;
-import static jdk.jshell.Util.*;
import java.util.Locale;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
-import jdk.jshell.MemoryFileManager.SourceMemoryJavaFileObject;
-import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
+import jdk.internal.jshell.remote.RemoteCodes;
+import static jdk.jshell.Util.*;
+import static jdk.internal.jshell.remote.RemoteCodes.REPL_PACKAGE;
/**
*
* @author Robert Field
*/
-final class OuterWrap implements GeneralWrap {
-
- private final String packageName;
- private final String className;
- private final String userSource;
- private final GeneralWrap w;
- private final Wrap guts;
+class OuterWrap implements GeneralWrap {
- public static OuterWrap wrapInClass(String packageName, String className,
- String imports, String userSource, Wrap guts) {
- GeneralWrap kw = new CompoundWrap(
- imports
- + "class " + className + " {\n",
- guts,
- "}\n");
- return new OuterWrap(packageName, className, userSource, kw, guts);
- }
+ protected final Wrap w;
- public static OuterWrap wrapImport(String userSource, Wrap guts) {
- return new OuterWrap("", "", userSource, guts, guts);
- }
-
- private OuterWrap(String packageName, String className, String userSource,
- GeneralWrap w, Wrap guts) {
- this.packageName = packageName;
- this.className = className;
- this.userSource = userSource;
- this.w = w;
- this.guts = guts;
+ OuterWrap(Wrap wrap) {
+ this.w = wrap;
}
@Override
@@ -114,19 +90,28 @@
}
public String className() {
- return className;
+ return REPL_DOESNOTMATTER_CLASS_NAME;
}
public String classFullName() {
- return packageName + "." + className;
+ return REPL_PACKAGE + "." + className();
+ }
+
+ @Override
+ public int hashCode() {
+ return className().hashCode();
}
- public String getUserSource() {
- return userSource;
+ @Override
+ public boolean equals(Object o) {
+ return (o instanceof OuterWrap)
+ ? className().equals(((OuterWrap) o).className())
+ : false;
}
- Wrap guts() {
- return guts;
+ @Override
+ public String toString() {
+ return "OW(" + w + ")";
}
Diag wrapDiag(Diagnostic<? extends JavaFileObject> d) {
@@ -135,7 +120,7 @@
class WrappedDiagnostic extends Diag {
- private final Diagnostic<? extends JavaFileObject> diag;
+ final Diagnostic<? extends JavaFileObject> diag;
WrappedDiagnostic(Diagnostic<? extends JavaFileObject> diag) {
this.diag = diag;
@@ -172,25 +157,13 @@
}
@Override
- Unit unitOrNull() {
- JavaFileObject fo = diag.getSource();
- if (fo instanceof SourceMemoryJavaFileObject) {
- SourceMemoryJavaFileObject sfo = (SourceMemoryJavaFileObject) fo;
- if (sfo.getOrigin() instanceof Unit) {
- return (Unit) sfo.getOrigin();
- }
- }
- return null;
- }
-
- @Override
boolean isResolutionError() {
if (!super.isResolutionError()) {
return false;
}
for (String line : diag.getMessage(PARSED_LOCALE).split("\\r?\\n")) {
if (line.trim().startsWith("location:")) {
- if (!line.contains(REPL_CLASS_PREFIX)) {
+ if (!line.contains(RemoteCodes.REPL_CLASS_PREFIX)) {
// Resolution error must occur within a REPL class or it is not resolvable
return false;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterWrapMap.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.stream.Collectors;
+import jdk.jshell.Wrap.CompoundWrap;
+import static jdk.internal.jshell.remote.RemoteCodes.PREFIX_PATTERN;
+import static jdk.internal.jshell.remote.RemoteCodes.REPL_CLASS_PREFIX;
+import static jdk.jshell.Util.REPL_DOESNOTMATTER_CLASS_NAME;
+import static jdk.jshell.Util.asLetters;
+
+/**
+ *
+ * @author Robert Field
+ */
+public class OuterWrapMap {
+
+ private final JShell state;
+ private final Map<String,OuterSnippetsClassWrap> classOuters = new HashMap<>();
+
+ OuterWrapMap(JShell state) {
+ this.state = state;
+ }
+
+ OuterSnippetsClassWrap getOuter(String className) {
+ Matcher matcher = PREFIX_PATTERN.matcher(className);
+ String cn;
+ if (matcher.find() && (cn = matcher.group("class")) != null) {
+ return classOuters.get(cn);
+ }
+ return null;
+ }
+
+ private CompoundWrap wrappedInClass(String className, String imports, List<Wrap> wraps) {
+ List<Object> elems = new ArrayList<>(wraps.size() + 2);
+ elems.add(imports +
+ "class " + className + " {\n");
+ elems.addAll(wraps);
+ elems.add("}\n");
+ return new CompoundWrap(elems.toArray());
+ }
+
+ OuterWrap wrapInClass(Set<Key> except, Collection<Snippet> plus,
+ List<Snippet> snippets, List<Wrap> wraps) {
+ String imports = state.maps.packageAndImportsExcept(except, plus);
+ // className is unique to the set of snippets and their version (seq)
+ String className = REPL_CLASS_PREFIX + snippets.stream()
+ .sorted((sn1, sn2) -> sn1.key().index() - sn2.key().index())
+ .map(sn -> "" + sn.key().index() + asLetters(sn.sequenceNumber()))
+ .collect(Collectors.joining("_"));
+ CompoundWrap w = wrappedInClass(className, imports, wraps);
+ OuterSnippetsClassWrap now = new OuterSnippetsClassWrap(className, w, snippets, wraps);
+ classOuters.put(className, now);
+ return now;
+ }
+
+ OuterWrap wrapInTrialClass(Wrap wrap) {
+ String imports = state.maps.packageAndImportsExcept(null, null);
+ CompoundWrap w = wrappedInClass(REPL_DOESNOTMATTER_CLASS_NAME, imports,
+ Collections.singletonList(wrap));
+ return new OuterWrap(w);
+ }
+
+ OuterWrap wrapImport(Wrap guts, Snippet sn) {
+ return new OuterImportSnippetWrap(guts, sn);
+ }
+}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java Thu Apr 28 23:08:17 2016 -0700
@@ -28,8 +28,6 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import static jdk.jshell.Util.REPL_CLASS_PREFIX;
-import static jdk.jshell.Util.asLetters;
/**
* A Snippet represents a snippet of Java source code as passed to
@@ -503,7 +501,6 @@
private final SubKind subkind;
private int seq;
- private String className;
private String id;
private OuterWrap outer;
private Status status;
@@ -615,7 +612,6 @@
final void setSequenceNumber(int seq) {
this.seq = seq;
- this.className = REPL_CLASS_PREFIX + key().index() + asLetters(seq);
}
void setOuterWrap(OuterWrap outer) {
@@ -653,7 +649,11 @@
}
String className() {
- return className;
+ return outer.className();
+ }
+
+ String classFullName() {
+ return outer.classFullName();
}
/**
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetMaps.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetMaps.java Thu Apr 28 23:08:17 2016 -0700
@@ -38,8 +38,9 @@
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
-import static jdk.internal.jshell.remote.RemoteCodes.prefixPattern;
+import static jdk.internal.jshell.remote.RemoteCodes.PREFIX_PATTERN;
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_DEP;
+import static jdk.internal.jshell.remote.RemoteCodes.REPL_PACKAGE;
/**
* Maintain relationships between the significant entities: Snippets,
@@ -48,7 +49,6 @@
*/
final class SnippetMaps {
- private String packageName;
private final List<Snippet> keyIndexToSnippet = new ArrayList<>();
private final Set<Snippet> snippets = new LinkedHashSet<>();
private final Map<String, Set<Integer>> dependencies = new HashMap<>();
@@ -81,6 +81,13 @@
}
Snippet getSnippet(int ki) {
+ Snippet sn = getSnippetDeadOrAlive(ki);
+ return (sn != null && !sn.status().isActive)
+ ? null
+ : sn;
+ }
+
+ Snippet getSnippetDeadOrAlive(int ki) {
if (ki >= keyIndexToSnippet.size()) {
return null;
}
@@ -91,21 +98,9 @@
return new ArrayList<>(snippets);
}
- void setPackageName(String n) {
- packageName = n;
- }
-
- String packageName() {
- return packageName;
- }
-
- String classFullName(Snippet sn) {
- return packageName + "." + sn.className();
- }
-
String packageAndImportsExcept(Set<Key> except, Collection<Snippet> plus) {
StringBuilder sb = new StringBuilder();
- sb.append("package ").append(packageName()).append(";\n");
+ sb.append("package ").append(REPL_PACKAGE).append(";\n");
for (Snippet si : keyIndexToSnippet) {
if (si != null && si.status().isDefined && (except == null || !except.contains(si.key()))) {
sb.append(si.importLine(state));
@@ -137,7 +132,7 @@
}
List<Snippet> deps = new ArrayList<>();
for (Integer dss : depset) {
- Snippet dep = getSnippet(dss);
+ Snippet dep = getSnippetDeadOrAlive(dss);
if (dep != null) {
deps.add(dep);
state.debug(DBG_DEP, "Found dependency %s -> %s\n", snip.name(), dep.name());
@@ -161,7 +156,7 @@
}
String fullClassNameAndPackageToClass(String full, String pkg) {
- Matcher mat = prefixPattern.matcher(full);
+ Matcher mat = PREFIX_PATTERN.matcher(full);
if (mat.lookingAt()) {
return full.substring(mat.end());
}
@@ -195,6 +190,6 @@
private Stream<ImportSnippet> importSnippets() {
return state.keyMap.importKeys()
.map(key -> (ImportSnippet)getSnippet(key))
- .filter(sn -> state.status(sn).isDefined);
+ .filter(sn -> sn != null && state.status(sn).isDefined);
}
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Thu Apr 28 23:08:17 2016 -0700
@@ -211,11 +211,6 @@
throw new InternalError();
}
- private OuterWrap wrapInClass(Wrap guts) {
- String imports = proc.maps.packageAndImportsExcept(null, null);
- return OuterWrap.wrapInClass(proc.maps.packageName(), REPL_DOESNOTMATTER_CLASS_NAME, imports, "", guts);
- }
-
private Tree.Kind guessKind(String code) {
ParseTask pt = proc.taskFactory.new ParseTask(code);
List<? extends Tree> units = pt.units();
@@ -258,13 +253,13 @@
OuterWrap codeWrap;
switch (guessKind(code)) {
case IMPORT:
- codeWrap = OuterWrap.wrapImport(null, Wrap.simpleWrap(code + "any.any"));
+ codeWrap = proc.outerMap.wrapImport(Wrap.simpleWrap(code + "any.any"), null);
break;
case METHOD:
- codeWrap = wrapInClass(Wrap.classMemberWrap(code));
+ codeWrap = proc.outerMap.wrapInTrialClass(Wrap.classMemberWrap(code));
break;
default:
- codeWrap = wrapInClass(Wrap.methodWrap(code));
+ codeWrap = proc.outerMap.wrapInTrialClass(Wrap.methodWrap(code));
break;
}
String requiredPrefix = identifier;
@@ -946,7 +941,7 @@
if (guessKind(code) == Kind.IMPORT)
return null;
- OuterWrap codeWrap = wrapInClass(Wrap.methodWrap(code));
+ OuterWrap codeWrap = proc.outerMap.wrapInTrialClass(Wrap.methodWrap(code));
AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap);
SourcePositions sp = at.trees().getSourcePositions();
CompilationUnitTree topLevel = at.firstCuTree();
@@ -1064,7 +1059,7 @@
case INTERFACE: case ANNOTATION_TYPE: case VARIABLE:
return null;
default:
- codeWrap = wrapInClass(Wrap.methodWrap(code));
+ codeWrap = proc.outerMap.wrapInTrialClass(Wrap.methodWrap(code));
break;
}
AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap);
@@ -1104,10 +1099,10 @@
case IMPORT:
return new QualifiedNames(Collections.emptyList(), -1, true, false);
case METHOD:
- codeWrap = wrapInClass(Wrap.classMemberWrap(code));
+ codeWrap = proc.outerMap.wrapInTrialClass(Wrap.classMemberWrap(code));
break;
default:
- codeWrap = wrapInClass(Wrap.methodWrap(code));
+ codeWrap = proc.outerMap.wrapInTrialClass(Wrap.methodWrap(code));
break;
}
AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap);
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -148,23 +148,12 @@
public String getMessage(Locale locale) {
return expunge(d.getMessage(locale));
}
-
- @Override
- Unit unitOrNull() {
- return null;
- }
};
}
}
private class WrapSourceHandler implements SourceHandler<OuterWrap> {
- final OuterWrap wrap;
-
- WrapSourceHandler(OuterWrap wrap) {
- this.wrap = wrap;
- }
-
@Override
public JavaFileObject sourceToFileObject(MemoryFileManager fm, OuterWrap w) {
return fm.createSourceFileObject(w, w.classFullName(), w.wrapped());
@@ -172,24 +161,9 @@
@Override
public Diag diag(Diagnostic<? extends JavaFileObject> d) {
- return wrap.wrapDiag(d);
- }
- }
-
- private class UnitSourceHandler implements SourceHandler<Unit> {
-
- @Override
- public JavaFileObject sourceToFileObject(MemoryFileManager fm, Unit u) {
- return fm.createSourceFileObject(u,
- state.maps.classFullName(u.snippet()),
- u.snippet().outerWrap().wrapped());
- }
-
- @Override
- public Diag diag(Diagnostic<? extends JavaFileObject> d) {
SourceMemoryJavaFileObject smjfo = (SourceMemoryJavaFileObject) d.getSource();
- Unit u = (Unit) smjfo.getOrigin();
- return u.snippet().outerWrap().wrapDiag(d);
+ OuterWrap w = (OuterWrap) smjfo.getOrigin();
+ return w.wrapDiag(d);
}
}
@@ -242,13 +216,12 @@
private final Iterable<? extends CompilationUnitTree> cuts;
AnalyzeTask(final OuterWrap wrap) {
- this(Stream.of(wrap),
- new WrapSourceHandler(wrap),
- "-XDshouldStopPolicy=FLOW", "-proc:none");
+ this(Collections.singletonList(wrap));
}
- AnalyzeTask(final Collection<Unit> units) {
- this(units.stream(), new UnitSourceHandler(),
+ AnalyzeTask(final Collection<OuterWrap> wraps) {
+ this(wraps.stream(),
+ new WrapSourceHandler(),
"-XDshouldStopPolicy=FLOW", "-Xlint:unchecked", "-XaddExports:jdk.jshell/jdk.internal.jshell.remote=ALL-UNNAMED", "-proc:none");
}
@@ -287,10 +260,10 @@
*/
class CompileTask extends BaseTask {
- private final Map<Unit, List<OutputMemoryJavaFileObject>> classObjs = new HashMap<>();
+ private final Map<OuterWrap, List<OutputMemoryJavaFileObject>> classObjs = new HashMap<>();
- CompileTask(Collection<Unit> units) {
- super(units.stream(), new UnitSourceHandler(),
+ CompileTask(final Collection<OuterWrap> wraps) {
+ super(wraps.stream(), new WrapSourceHandler(),
"-Xlint:unchecked", "-XaddExports:jdk.jshell/jdk.internal.jshell.remote=ALL-UNNAMED", "-proc:none");
}
@@ -302,8 +275,8 @@
}
- List<ClassInfo> classInfoList(Unit u) {
- List<OutputMemoryJavaFileObject> l = classObjs.get(u);
+ List<ClassInfo> classInfoList(OuterWrap w) {
+ List<OutputMemoryJavaFileObject> l = classObjs.get(w);
if (l == null) return Collections.emptyList();
return l.stream()
.map(fo -> state.classTracker.classInfo(fo.getName(), fo.getBytes()))
@@ -315,11 +288,11 @@
//debug("listenForNewClassFile %s loc=%s kind=%s\n", className, location, kind);
if (location == CLASS_OUTPUT) {
state.debug(DBG_GEN, "Compiler generating class %s\n", className);
- Unit u = ((sibling instanceof SourceMemoryJavaFileObject)
- && (((SourceMemoryJavaFileObject) sibling).getOrigin() instanceof Unit))
- ? (Unit) ((SourceMemoryJavaFileObject) sibling).getOrigin()
+ OuterWrap w = ((sibling instanceof SourceMemoryJavaFileObject)
+ && (((SourceMemoryJavaFileObject) sibling).getOrigin() instanceof OuterWrap))
+ ? (OuterWrap) ((SourceMemoryJavaFileObject) sibling).getOrigin()
: null;
- classObjs.compute(u, (k, v) -> (v == null)? new ArrayList<>() : v)
+ classObjs.compute(w, (k, v) -> (v == null)? new ArrayList<>() : v)
.add(jfo);
}
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TreeDissector.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TreeDissector.java Thu Apr 28 23:08:17 2016 -0700
@@ -162,18 +162,28 @@
return new Range(start, end);
}
- Tree firstClassMember() {
- if (targetClass != null) {
- //TODO: missing classes
- for (Tree mem : targetClass.getMembers()) {
- if (mem.getKind() == Tree.Kind.VARIABLE) {
- return mem;
- }
- if (mem.getKind() == Tree.Kind.METHOD) {
- MethodTree mt = (MethodTree) mem;
- if (!isDoIt(mt.getName()) && !mt.getName().toString().equals("<init>")) {
+ MethodTree method(MethodSnippet msn) {
+ if (targetClass == null) {
+ return null;
+ }
+ OuterWrap ow = msn.outerWrap();
+ if (!(ow instanceof OuterSnippetsClassWrap)) {
+ return null;
+ }
+ int ordinal = ((OuterSnippetsClassWrap) ow).ordinal(msn);
+ if (ordinal < 0) {
+ return null;
+ }
+ int count = 0;
+ String name = msn.name();
+ for (Tree mem : targetClass.getMembers()) {
+ if (mem.getKind() == Tree.Kind.METHOD) {
+ MethodTree mt = (MethodTree) mem;
+ if (mt.getName().toString().equals(name)) {
+ if (count == ordinal) {
return mt;
}
+ ++count;
}
}
}
@@ -244,8 +254,8 @@
return ei;
}
- String typeOfMethod() {
- Tree unitTree = firstClassMember();
+ String typeOfMethod(MethodSnippet msn) {
+ Tree unitTree = method(msn);
if (unitTree instanceof JCMethodDecl) {
JCMethodDecl mtree = (JCMethodDecl) unitTree;
Type mt = types().erasure(mtree.type);
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Unit.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Unit.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -68,7 +68,7 @@
private final DiagList generatedDiagnostics;
private int seq;
- private int seqInitial;
+ private String classNameInitial;
private Wrap activeGuts;
private Status status;
private Status prevStatus;
@@ -95,7 +95,7 @@
this.generatedDiagnostics = generatedDiagnostics;
this.seq = isNew? 0 : siOld.sequenceNumber();
- this.seqInitial = seq;
+ this.classNameInitial = isNew? "<none>" : siOld.className();
this.prevStatus = (isNew || isDependency)
? si.status()
: siOld.status();
@@ -136,28 +136,50 @@
return isDependency;
}
- boolean isNew() {
- return isNew;
- }
-
- void initialize(Collection<Unit> working) {
+ void initialize() {
isAttemptingCorral = false;
dependenciesNeeded = false;
toRedefine = null; // assure NPE if classToLoad not called
activeGuts = si.guts();
markOldDeclarationOverwritten();
- setWrap(working, working);
}
- void setWrap(Collection<Unit> except, Collection<Unit> plus) {
- si.setOuterWrap(isImport()
- ? OuterWrap.wrapImport(si.source(), activeGuts)
- : state.eval.wrapInClass(si,
- except.stream().map(u -> u.snippet().key()).collect(toSet()),
- activeGuts,
- plus.stream().map(u -> u.snippet())
- .filter(sn -> sn != si)
- .collect(toList())));
+ // Set the outer wrap of our Snippet
+ void setWrap(Collection<Unit> exceptUnit, Collection<Unit> plusUnfiltered) {
+ if (isImport()) {
+ si.setOuterWrap(state.outerMap.wrapImport(activeGuts, si));
+ } else {
+ // Collect Units for be wrapped together. Just this except for overloaded methods
+ List<Unit> units;
+ if (snippet().kind() == Kind.METHOD) {
+ String name = ((MethodSnippet) snippet()).name();
+ units = plusUnfiltered.stream()
+ .filter(u -> u.snippet().kind() == Kind.METHOD &&
+ ((MethodSnippet) u.snippet()).name().equals(name))
+ .collect(toList());
+ } else {
+ units = Collections.singletonList(this);
+ }
+ // Keys to exclude from imports
+ Set<Key> except = exceptUnit.stream()
+ .map(u -> u.snippet().key())
+ .collect(toSet());
+ // Snippets to add to imports
+ Collection<Snippet> plus = plusUnfiltered.stream()
+ .filter(u -> !units.contains(u))
+ .map(u -> u.snippet())
+ .collect(toList());
+ // Snippets to wrap in an outer
+ List<Snippet> snippets = units.stream()
+ .map(u -> u.snippet())
+ .collect(toList());
+ // Snippet wraps to wrap in an outer
+ List<Wrap> wraps = units.stream()
+ .map(u -> u.activeGuts)
+ .collect(toList());
+ // Set the outer wrap for this snippet
+ si.setOuterWrap(state.outerMap.wrapInClass(except, plus, snippets, wraps));
+ }
}
void setDiagnostics(AnalyzeTask ct) {
@@ -302,11 +324,13 @@
private boolean sigChanged() {
return (status.isDefined != prevStatus.isDefined)
- || (seq != seqInitial && status.isDefined)
+ || (status.isDefined && !si.className().equals(classNameInitial))
|| signatureChanged;
}
Stream<Unit> effectedDependents() {
+ //System.err.printf("effectedDependents sigChanged=%b dependenciesNeeded=%b status=%s\n",
+ // sigChanged(), dependenciesNeeded, status);
return sigChanged() || dependenciesNeeded || status == RECOVERABLE_NOT_DEFINED
? dependents()
: Stream.empty();
@@ -361,7 +385,7 @@
if (replaceOldEvent != null) secondaryEvents.add(replaceOldEvent);
// Defined methods can overwrite methods of other (equivalent) snippets
- if (si.kind() == Kind.METHOD && status.isDefined) {
+ if (isNew && si.kind() == Kind.METHOD && status.isDefined) {
MethodSnippet msi = (MethodSnippet)si;
String oqpt = msi.qualifiedParameterTypes();
String nqpt = computeQualifiedParameterTypes(at, msi);
@@ -405,7 +429,7 @@
}
private String computeQualifiedParameterTypes(AnalyzeTask at, MethodSnippet msi) {
- String rawSig = TreeDissector.createBySnippet(at, msi).typeOfMethod();
+ String rawSig = TreeDissector.createBySnippet(at, msi).typeOfMethod(msi);
String signature = expunge(rawSig);
int paren = signature.lastIndexOf(')');
@@ -425,7 +449,9 @@
}
List<SnippetEvent> secondaryEvents() {
- return secondaryEvents;
+ return secondaryEvents==null
+ ? Collections.emptyList()
+ : secondaryEvents;
}
@Override
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Util.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Util.java Thu Apr 28 23:08:17 2016 -0700
@@ -30,7 +30,8 @@
import java.util.stream.StreamSupport;
import javax.lang.model.element.Name;
import static jdk.internal.jshell.remote.RemoteCodes.DOIT_METHOD_NAME;
-import static jdk.internal.jshell.remote.RemoteCodes.prefixPattern;
+import static jdk.internal.jshell.remote.RemoteCodes.PREFIX_PATTERN;
+import static jdk.internal.jshell.remote.RemoteCodes.REPL_CLASS_PREFIX;
/**
* Assorted shared utilities.
@@ -38,8 +39,7 @@
*/
class Util {
- static final String REPL_CLASS_PREFIX = "$REPL";
- static final String REPL_DOESNOTMATTER_CLASS_NAME = REPL_CLASS_PREFIX+"00DOESNOTMATTER";
+ static final String REPL_DOESNOTMATTER_CLASS_NAME = REPL_CLASS_PREFIX+"DOESNOTMATTER";
static final Locale PARSED_LOCALE = Locale.ROOT;
@@ -53,7 +53,7 @@
static String expunge(String s) {
StringBuilder sb = new StringBuilder();
- for (String comp : prefixPattern.split(s)) {
+ for (String comp : PREFIX_PATTERN.split(s)) {
sb.append(comp);
}
return sb.toString();
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Wrap.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Wrap.java Thu Apr 28 23:08:17 2016 -0700
@@ -25,6 +25,8 @@
package jdk.jshell;
+import java.util.Arrays;
+import static java.util.stream.Collectors.joining;
import static jdk.internal.jshell.remote.RemoteCodes.DOIT_METHOD_NAME;
/**
@@ -237,6 +239,27 @@
return 0;
}
+ Wrap wrapIndexToWrap(long wi) {
+ int before = 0;
+ Wrap w = null;
+ for (Object o : os) {
+ if (o instanceof String) {
+ String s = (String) o;
+ before += s.length();
+ } else if (o instanceof Wrap) {
+ w = (Wrap) o;
+ int len = w.wrapped().length();
+ if ((wi - before) <= len) {
+ //System.err.printf("Defer to wrap %s - wi: %d. before; %d -- %s >>> %s\n",
+ // w, wi, before, w.debugPos(wi - before), w.wrapped());
+ return w;
+ }
+ before += len;
+ }
+ }
+ return w;
+ }
+
@Override
public int wrapIndexToSnippetIndex(int wi) {
int before = 0;
@@ -286,6 +309,25 @@
return 0;
}
+ Wrap wrapLineToWrap(int wline) {
+ int before = 0;
+ Wrap w = null;
+ for (Object o : os) {
+ if (o instanceof String) {
+ String s = (String) o;
+ before += countLines(s);
+ } else if (o instanceof Wrap) {
+ w = (Wrap) o;
+ int lns = countLines(w.wrapped());
+ if ((wline - before) < lns) {
+ return w;
+ }
+ before += lns;
+ }
+ }
+ return w;
+ }
+
@Override
public int wrapLineToSnippetLine(int wline) {
int before = 0;
@@ -315,7 +357,10 @@
return snlineLast;
}
-
+ @Override
+ public String toString() {
+ return "CompoundWrap(" + Arrays.stream(os).map(u -> u.toString()).collect(joining(",")) + ")";
+ }
}
private static class RangeWrap extends Wrap {
@@ -404,6 +449,10 @@
return lastSnline;
}
+ @Override
+ public String toString() {
+ return "RangeWrap(" + range + ")";
+ }
}
private static class NoWrap extends RangeWrap {
--- a/langtools/test/jdk/javadoc/tool/6964914/TestStdDoclet.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/jdk/javadoc/tool/6964914/TestStdDoclet.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
*/
import java.io.*;
+import java.util.*;
/**
* Dummy javadoc comment.
@@ -54,13 +55,21 @@
// run javadoc in separate process to ensure doclet executed under
// normal user conditions w.r.t. classloader
String thisClassName = TestStdDoclet.class.getName();
- Process p = new ProcessBuilder()
- .command(javadoc.getPath(),
- "-J-Xpatch:" + System.getProperty("jdk.launcher.patch.0", ""),
+ List<String> cmdArgs = new ArrayList<>();
+ cmdArgs.add(javadoc.getPath());
+ int i = 0;
+ String prop;
+ while ((prop = System.getProperty("jdk.launcher.patch." + (i++))) != null) {
+ cmdArgs.add("-J-Xpatch:" + prop);
+ }
+ cmdArgs.addAll(Arrays.asList(
"-classpath", ".", // insulates us from ambient classpath
"-Xdoclint:none",
"-package",
- new File(testSrc, thisClassName + ".java").getPath())
+ new File(testSrc, thisClassName + ".java").getPath()
+ ));
+ Process p = new ProcessBuilder()
+ .command(cmdArgs)
.redirectErrorStream(true)
.start();
--- a/langtools/test/jdk/javadoc/tool/6964914/TestUserDoclet.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/jdk/javadoc/tool/6964914/TestUserDoclet.java Thu Apr 28 23:08:17 2016 -0700
@@ -30,7 +30,10 @@
import java.io.*;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
+import java.util.List;
import java.util.Locale;
import java.util.Set;
@@ -63,12 +66,20 @@
// run javadoc in separate process to ensure doclet executed under
// normal user conditions w.r.t. classloader
String thisClassName = TestUserDoclet.class.getName();
- Process p = new ProcessBuilder()
- .command(javadoc.getPath(),
- "-J-Xpatch:" + System.getProperty("jdk.launcher.patch.0", ""),
+ List<String> cmdArgs = new ArrayList<>();
+ cmdArgs.add(javadoc.getPath());
+ int i = 0;
+ String prop;
+ while ((prop = System.getProperty("jdk.launcher.patch." + (i++))) != null) {
+ cmdArgs.add("-J-Xpatch:" + prop);
+ }
+ cmdArgs.addAll(Arrays.asList(
"-doclet", thisClassName,
"-docletpath", testClasses.getPath(),
- new File(testSrc, thisClassName + ".java").getPath())
+ new File(testSrc, thisClassName + ".java").getPath()
+ ));
+ Process p = new ProcessBuilder()
+ .command(cmdArgs)
.redirectErrorStream(true)
.start();
--- a/langtools/test/jdk/javadoc/tool/sampleapi/lib/sampleapi/SampleApi.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/jdk/javadoc/tool/sampleapi/lib/sampleapi/SampleApi.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -53,5 +53,8 @@
public Fault(String msg) {
super(msg);
}
+ public Fault(String msg, Throwable th) {
+ super(msg, th);
+ }
}
}
--- a/langtools/test/jdk/javadoc/tool/sampleapi/lib/sampleapi/generator/DocCommentGenerator.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/jdk/javadoc/tool/sampleapi/lib/sampleapi/generator/DocCommentGenerator.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,8 @@
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.List;
+import java.util.HashMap;
+import java.util.Map;
class DocCommentGenerator {
@@ -99,14 +101,25 @@
LITERAL("@literal", "Use < and > brackets instead of < and > escapes."),
CODE("@code", "(i) -> new Abc<Object>((i > 0) ? (i << 1) : 0)"),
LINK("@link", ""),
- VALUE("@value", "");
+ VALUE("@value", ""),
+ INDEX("@index", "", true);
String tagName;
String tagValue;
+ boolean counted;
+ Map<String, Integer> counters;
InlineTag(String tagName, String tagValue) {
+ this(tagName, tagValue, false);
+ }
+
+ InlineTag(String tagName, String tagValue, boolean counted) {
this.tagName = tagName;
this.tagValue = tagValue;
+ this.counted = counted;
+ if (counted) {
+ counters = new HashMap<>();
+ }
}
public String toString() {
@@ -114,9 +127,14 @@
}
public String value(String value) {
+ String name = ((tagValue.length() != 0) ? " " + tagValue : "")
+ + ((value.length() != 0) ? " " + value : "");
+ if (counted && !counters.containsKey(name)) {
+ counters.put(name, 0);
+ }
return "{" + tagName
- + ((tagValue.length() != 0) ? " " + tagValue : "")
- + ((value.length() != 0) ? " " + value : "")
+ + name
+ + (counted ? "_" + counters.put(name, counters.get(name) + 1) : "")
+ "}";
}
}
@@ -179,7 +197,8 @@
//
public String getPackageComment() {
- return Text.LOREMIPSUM
+ return InlineTag.INDEX.value("PackageCommentLabel") + " "
+ + Text.LOREMIPSUM
+ "\n <p>" + Text.LIEUROPANLINGUES
+ "\n" + Text.CODE
+ "\n" + LinkTag.nextLink()
@@ -192,7 +211,9 @@
static int serialValIdx = 0;
public String getBaseComment(JCClassDecl baseDecl, boolean toplevel) {
- String buildComment = Text.LIEUROPANLINGUES + "\n";
+ String buildComment = InlineTag.INDEX.value("BaseCommentLabel") + " ";
+
+ buildComment += Text.LIEUROPANLINGUES + "\n";
buildComment += "<p>It is possible to see inlined code:\n"
+ InlineTag.CODE
@@ -237,8 +258,9 @@
}
public String getConstComment() {
- String buildComment = Text.NOWISTHETIME + " " + Text.BROWNFOX + "\n";
+ String buildComment = InlineTag.INDEX.value("ConstCommentLabel") + " ";
+ buildComment += Text.NOWISTHETIME + " " + Text.BROWNFOX + "\n";
buildComment += LinkTag.nextLink() + "\n";
buildComment += LinkTag.nextSee() + "\n";
buildComment += Tag.SINCE + "\n";
@@ -249,8 +271,9 @@
public String getFieldComment(JCClassDecl baseDecl,
JCVariableDecl varDecl,
boolean isFxStyle) {
- String buildComment = Text.BROWNFOX + "<p>" + Text.NOWISTHETIME + "\n";
+ String buildComment = InlineTag.INDEX.value("FieldCommentLabel") + " ";
+ buildComment += Text.BROWNFOX + "<p>" + Text.NOWISTHETIME + "\n";
Set<Modifier> mods = varDecl.getModifiers().getFlags();
String varName = varDecl.getName().toString();
@@ -299,7 +322,9 @@
public String getMethodComment(JCClassDecl baseDecl,
JCMethodDecl methodDecl,
boolean isFxStyle) {
- String buildComment = Text.BROWNFOX + "\n<p>" + Text.THISPANGRAM + "\n";
+ String buildComment = InlineTag.INDEX.value("MethodCommentLabel") + " ";
+
+ buildComment += Text.BROWNFOX + "\n<p>" + Text.THISPANGRAM + "\n";
buildComment += "<p>" + LinkTag.nextLink() + "\n";
--- a/langtools/test/jdk/javadoc/tool/sampleapi/lib/sampleapi/generator/PackageGenerator.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/jdk/javadoc/tool/sampleapi/lib/sampleapi/generator/PackageGenerator.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -125,7 +125,7 @@
processTopLevel((Element)node);
}
} catch (ParserConfigurationException | SAXException | IOException e) {
- throw new Fault("Error parsing dataset " + dsName);
+ throw new Fault("Error parsing dataset " + dsName, e);
}
fx = false;
--- a/langtools/test/jdk/jshell/ClassesTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/jdk/jshell/ClassesTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -47,6 +47,7 @@
import static jdk.jshell.Snippet.Status.DROPPED;
import static jdk.jshell.Snippet.Status.REJECTED;
import static jdk.jshell.Snippet.Status.OVERWRITTEN;
+import static jdk.jshell.Snippet.Status.NONEXISTENT;
import static jdk.jshell.Snippet.SubKind.*;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
@@ -83,7 +84,7 @@
TypeDeclSnippet c1 = (TypeDeclSnippet) assertDeclareFail("class A { void f() { return g(); } }", "compiler.err.prob.found.req");
assertTypeDeclSnippet(c1, "A", REJECTED, CLASS_SUBKIND, 0, 2);
TypeDeclSnippet c2 = classKey(assertEval("class A { int f() { return g(); } }",
- ste(c1, REJECTED, RECOVERABLE_DEFINED, true, null)));
+ ste(c1, NONEXISTENT, RECOVERABLE_DEFINED, true, null)));
assertTypeDeclSnippet(c2, "A", RECOVERABLE_DEFINED, CLASS_SUBKIND, 1, 0);
assertDrop(c2,
ste(c2, RECOVERABLE_DEFINED, DROPPED, true, null));
@@ -176,6 +177,7 @@
assertActiveKeys();
}
+ //8154496: test3 update: sig change should false
public void classesRedeclaration3() {
Snippet a = classKey(assertEval("class A { }"));
assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"));
@@ -190,7 +192,7 @@
ste(MAIN_SNIPPET, VALID, VALID, true, null),
ste(test1, VALID, VALID, true, MAIN_SNIPPET),
ste(test2, VALID, VALID, true, MAIN_SNIPPET),
- ste(test3, VALID, VALID, false, MAIN_SNIPPET),
+ ste(test3, VALID, VALID, true, MAIN_SNIPPET),
ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
assertClasses(clazz(KullaTesting.ClassType.INTERFACE, "A"));
assertMethods(method("()A", "test"), method("(A)void", "test"), method("(int)void", "test"));
@@ -201,8 +203,7 @@
Snippet b = classKey(assertEval("class B extends A { }",
added(RECOVERABLE_NOT_DEFINED)));
Snippet a = classKey(assertEval("class A extends B { }", DiagCheck.DIAG_IGNORE, DiagCheck.DIAG_IGNORE,
- added(RECOVERABLE_NOT_DEFINED),
- ste(b, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, MAIN_SNIPPET)));
+ added(REJECTED)));
/***
assertDeclareFail("class A extends B { }", "****",
added(REJECTED),
--- a/langtools/test/jdk/jshell/DropTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/jdk/jshell/DropTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -57,10 +57,10 @@
assertActiveKeys();
method = methodKey(assertEval("int mu() { return x * 4; }",
- ste(MAIN_SNIPPET, DROPPED, RECOVERABLE_DEFINED, true, null),
+ added(RECOVERABLE_DEFINED),
ste(clazz, RECOVERABLE_DEFINED, VALID, false, MAIN_SNIPPET)));
assertEval("int x = 10;", "10",
- ste(MAIN_SNIPPET, DROPPED, VALID, true, null),
+ added(VALID),
ste(method, RECOVERABLE_DEFINED, VALID, false, MAIN_SNIPPET));
PersistentSnippet c0 = varKey(assertEval("C c0 = new C();"));
assertEval("c0.v();", "\"#40\"");
@@ -189,12 +189,11 @@
assertDrop(c,
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
- ste(c, RECOVERABLE_NOT_DEFINED, DROPPED, false, null),
- ste(d, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, c));
+ ste(c, RECOVERABLE_NOT_DEFINED, DROPPED, false, null));
assertEval("interface A {}", null, null,
- DiagCheck.DIAG_OK, DiagCheck.DIAG_ERROR,
- ste(a, DROPPED, VALID, true, null),
- ste(b, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, MAIN_SNIPPET));
+ DiagCheck.DIAG_OK,
+ DiagCheck.DIAG_ERROR,
+ added(VALID));
assertClasses();
assertActiveKeys();
}
--- a/langtools/test/jdk/jshell/KullaTesting.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/jdk/jshell/KullaTesting.java Thu Apr 28 23:08:17 2016 -0700
@@ -651,7 +651,7 @@
DiagCheck.DIAG_WARNING, DiagCheck.DIAG_IGNORE, mainInfo, updates);
SnippetEvent e = events.get(0);
List<Diag> diagnostics = getState().diagnostics(e.snippet());
- assertDiagnostic(input, diagnostics.get(0), expectedDiagnostic);
+ if (expectedDiagnostic != null) assertDiagnostic(input, diagnostics.get(0), expectedDiagnostic);
return e.snippet();
}
--- a/langtools/test/jdk/jshell/MethodsTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/jdk/jshell/MethodsTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,7 +58,7 @@
MethodSnippet m1 = (MethodSnippet) assertDeclareFail("void f() { return g(); }", "compiler.err.prob.found.req");
assertMethodDeclSnippet(m1, "f", "()void", REJECTED, 0, 2);
MethodSnippet m2 = methodKey(assertEval("int f() { return g(); }",
- ste(m1, REJECTED, RECOVERABLE_DEFINED, true, null)));
+ added(RECOVERABLE_DEFINED)));
assertMethodDeclSnippet(m1, "f", "()void", REJECTED, 0, 2);
assertMethodDeclSnippet(m2, "f", "()int", RECOVERABLE_DEFINED, 1, 0);
}
@@ -115,6 +115,26 @@
assertActiveKeys();
}
+ /***
+ public void methodOverloadDependent() {
+ assertEval("String m(String s) { return s + s; }");
+ assertEval("String m(double d) { return m(\"#\" + d); }");
+ assertEval("String m(int x) { return m(2.25 * x); }");
+ assertEval("String m() { return m(3); }");
+ assertMethods(
+ method("(String)String", "m"),
+ method("(double)String", "m"),
+ method("(int)String", "m"),
+ method("()String", "m")
+ );
+ assertEval("m();", "\"#6.75#6.75\"");
+ assertEval("m(2);", "\"#4.5#4.5\"");
+ assertEval("m(3.14);", "\"#3.14#3.14\"");
+ assertEval("m(\"hi\");", "\"hihi\"");
+ assertActiveKeys();
+ }
+ ***/
+
public void methodsRedeclaration1() {
Snippet x = methodKey(assertEval("int x() { return 10; }"));
Snippet y = methodKey(assertEval("String y() { return \"\"; }"));
@@ -149,8 +169,7 @@
assertEval("double b() { return 3.14159; }",
ste(MAIN_SNIPPET, VALID, VALID, true, null),
- ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
- ste(c, VALID, VALID, false, MAIN_SNIPPET));
+ ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
assertMethods(method("()int", "a"), method("()double", "b"), method("()double", "c"));
assertEval("c();", "3.14159");
assertActiveKeys();
@@ -202,7 +221,7 @@
assertActiveKeys();
assertDeclareFail("int f() {}", "compiler.err.missing.ret.stmt",
- ste(MAIN_SNIPPET, REJECTED, REJECTED, false, null));
+ added(REJECTED));
assertNumberOfActiveMethods(0);
assertActiveKeys();
--- a/langtools/test/jdk/jshell/ReplaceTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/jdk/jshell/ReplaceTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -97,8 +97,7 @@
assertEval("mu() == 0.0;", "true");
assertEval("double x = 2.5;",
ste(MAIN_SNIPPET, VALID, VALID, true, null),
- ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
- ste(musn, VALID, VALID, false, MAIN_SNIPPET));
+ ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
Collection<MethodSnippet> meths = getState().methods();
assertEquals(meths.size(), 1);
assertTrue(musn == meths.iterator().next(), "Identity must not change");
@@ -115,8 +114,7 @@
assertEval("d();", "1060.0");
assertEval("int a() { return 5; }",
ste(MAIN_SNIPPET, VALID, VALID, true, null),
- ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
- ste(b, VALID, VALID, false, MAIN_SNIPPET));
+ ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
assertEval("d();", "1150.0");
assertActiveKeys();
}
@@ -127,8 +125,7 @@
assertEval("m();", "7");
assertEval("class C { int x = 99; int f() { return x; } }",
ste(MAIN_SNIPPET, VALID, VALID, true, null),
- ste(c, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
- ste(m, VALID, VALID, false, MAIN_SNIPPET));
+ ste(c, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
assertEval("m();", "99");
assertActiveKeys();
}
@@ -140,8 +137,7 @@
assertEval("new A().a == 0.0;", "true");
assertEval("double x = 2.5;",
ste(MAIN_SNIPPET, VALID, VALID, true, null),
- ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
- ste(c, VALID, VALID, false, MAIN_SNIPPET));
+ ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
Collection<TypeDeclSnippet> classes = getState().types();
assertEquals(classes.size(), 1);
assertTrue(c == classes.iterator().next(), "Identity must not change");
@@ -157,8 +153,7 @@
assertEval("new A().a == 0.0;", "true");
assertEval("double x() { return 2.5; }",
ste(MAIN_SNIPPET, VALID, VALID, true, null),
- ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
- ste(c, VALID, VALID, false, MAIN_SNIPPET));
+ ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
assertEval("x();", "2.5");
Collection<TypeDeclSnippet> classes = getState().types();
assertEquals(classes.size(), 1);
@@ -875,18 +870,15 @@
MethodSnippet k1 = methodKey(assertEval(ms1, added(VALID)));
VarSnippet xd = varKey(assertEval(xsd,
ste(MAIN_SNIPPET, VALID, VALID, true, null),
- ste(xi, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
- ste(k1, VALID, VALID, false, MAIN_SNIPPET)));
+ ste(xi, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
MethodSnippet k2 = methodKey(assertEval(ms2,
ste(MAIN_SNIPPET, VALID, VALID, true, null), //TODO: technically, should be false
ste(k1, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
VarSnippet xi2 = varKey(assertEval(xsi,
ste(MAIN_SNIPPET, VALID, VALID, true, null),
- ste(xd, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
- ste(k2, VALID, VALID, false, MAIN_SNIPPET)));
+ ste(xd, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
varKey(assertEval(xsd,
ste(MAIN_SNIPPET, VALID, VALID, true, null),
- ste(xi2, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
- ste(k2, VALID, VALID, false, MAIN_SNIPPET)));
+ ste(xi2, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
}
}
--- a/langtools/test/jdk/jshell/SnippetStatusListenerTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/jdk/jshell/SnippetStatusListenerTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -65,7 +65,7 @@
getState().unsubscribe(subscription1);
assertDrop(f, DiagCheck.DIAG_IGNORE, DiagCheck.DIAG_IGNORE, ste(f, REJECTED, DROPPED, false, null));
- assertEval("void f() { }", ste(MAIN_SNIPPET, DROPPED, VALID, true, null));
+ assertEval("void f() { }", added(VALID));
assertEvalException("throw new RuntimeException();");
assertEquals(listener1.getEvents(), events1, "Checking that unsubscribed listener does not get events");
--- a/langtools/test/jdk/jshell/SnippetTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/jdk/jshell/SnippetTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -142,8 +142,7 @@
assertActiveKeys();
assertEval("double f() { return 0.0; }",
ste(MAIN_SNIPPET, VALID, VALID, true, null),
- ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
- ste(g, VALID, VALID, false, MAIN_SNIPPET));
+ ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
assertKeys(method("()void", "g"), clazz(KullaTesting.ClassType.INTERFACE, "A"),
method("()double", "f"));
assertActiveKeys();
--- a/langtools/test/jdk/jshell/ToolFormatTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/jdk/jshell/ToolFormatTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8148316 8148317 8151755 8152246
+ * @bug 8148316 8148317 8151755 8152246 8153551
* @summary Tests for output customization
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
@@ -155,6 +155,12 @@
}
}
+ public void testShowFeedbackModes() {
+ test(
+ (a) -> assertCommandOutputContains(a, "/set feedback", "normal")
+ );
+ }
+
public void testSetNewModeQuiet() {
try {
test(
--- a/langtools/test/jdk/jshell/VariablesTest.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/jdk/jshell/VariablesTest.java Thu Apr 28 23:08:17 2016 -0700
@@ -83,7 +83,7 @@
public void testVarValue2() {
VarSnippet v1 = (VarSnippet) assertDeclareFail("int a = 0.0;", "compiler.err.prob.found.req");
badVarValue(v1);
- VarSnippet v2 = varKey(assertEval("int a = 0;", ste(v1, REJECTED, VALID, true, null)));
+ VarSnippet v2 = varKey(assertEval("int a = 0;", added(VALID)));
assertDrop(v2, ste(MAIN_SNIPPET, VALID, DROPPED, true, null));
badVarValue(v2);
}
@@ -111,7 +111,7 @@
VarSnippet v1 = (VarSnippet) assertDeclareFail("int a = 0.0;", "compiler.err.prob.found.req");
assertVariableDeclSnippet(v1, "a", "int", REJECTED, SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, 0, 1);
VarSnippet v2 = varKey(assertEval("int a = 0;",
- ste(v1, REJECTED, VALID, true, null)));
+ added(VALID)));
assertVariableDeclSnippet(v2, "a", "int", VALID, SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, 0, 0);
assertDrop(v2, ste(MAIN_SNIPPET, VALID, DROPPED, true, null));
assertVariableDeclSnippet(v2, "a", "int", DROPPED, SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, 0, 0);
--- a/langtools/test/tools/javac/6520152/T.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/6520152/T.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
import java.io.Serializable;
public class T {
--- a/langtools/test/tools/javac/6520152/T6520152.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/6520152/T6520152.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
/**
* @test
* @bug 6520152
--- a/langtools/test/tools/javac/6521805/T6521805e.out Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/6521805/T6521805e.out Thu Apr 28 23:08:17 2016 -0700
@@ -1,2 +1,2 @@
-Sub.java:8:11: compiler.err.synthetic.name.conflict: this$0, p.Inner
+Sub.java:10:11: compiler.err.synthetic.name.conflict: this$0, p.Inner
1 error
--- a/langtools/test/tools/javac/6521805/p/Outer.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/6521805/p/Outer.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,5 @@
+/* /nodynamiccopyright/ */
+
package p;
class Outer {
--- a/langtools/test/tools/javac/6521805/p/Sub.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/6521805/p/Sub.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,5 @@
+/* /nodynamiccopyright/ */
+
package p;
class Inner extends Outer.Super {
--- a/langtools/test/tools/javac/6547131/T.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/6547131/T.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
/**
* @test
* @bug 6547131
--- a/langtools/test/tools/javac/6589361/T6589361.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/6589361/T6589361.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
/**
* @test
* @bug 6589361
--- a/langtools/test/tools/javac/6668794/badSource/Test.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/6668794/badSource/Test.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * @test /nodynamiccopyight/
+ * @test /nodynamiccopyright/
* @bug 6668794 6668796
* @summary javac puts localized text in raw diagnostics
* bad diagnostic "bad class file" given for source files
--- a/langtools/test/tools/javac/CaptureInSubtype.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/CaptureInSubtype.java Thu Apr 28 23:08:17 2016 -0700
@@ -33,7 +33,7 @@
public static class ShowFlaw extends SuperOfShowFlaw {
- static Flaw<Number> fn = new Flaw<Number>(new Integer(3));
+ static Flaw<Number> fn = new Flaw<Number>(Integer.valueOf(3));
Flaw<?> m(){return fn;}
}
--- a/langtools/test/tools/javac/OverrideChecks/T4721069.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/OverrideChecks/T4721069.java Thu Apr 28 23:08:17 2016 -0700
@@ -12,7 +12,7 @@
static class T {
static void f(I i) {
if (i == null) {
- Integer x = new Integer(2);
+ Integer x = Integer.valueOf(2);
} else {
I x = i;
x.getClass();
--- a/langtools/test/tools/javac/SerialWarn.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-/*
- * @test /nodynamiccopyright/
- * @bug 4854628
- * @summary include Throwable subclasses in missing serialVersionUID warning
- * @author gafter
- *
- * @compile -Werror SerialWarn.java
- * @compile/fail/ref=SerialWarn.out -XDrawDiagnostics -Xlint:serial -Werror SerialWarn.java
- */
-
-class SerialWarn extends Throwable {}
--- a/langtools/test/tools/javac/SerialWarn.out Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-SerialWarn.java:11:1: compiler.warn.missing.SVUID: SerialWarn
-- compiler.err.warnings.and.werror
-1 error
-1 warning
--- a/langtools/test/tools/javac/T6554097.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/T6554097.java Thu Apr 28 23:08:17 2016 -0700
@@ -3,24 +3,27 @@
* @bug 6554097
* @summary "final" confuses at-SuppressWarnings
* @compile T6554097.java
- * @compile/fail/ref=T6554097.out -XDrawDiagnostics -Werror -Xlint:serial T6554097.java
+ * @compile/fail/ref=T6554097.out -XDrawDiagnostics -Werror -Xlint:rawtypes T6554097.java
*/
+import java.util.ArrayList;
+
class T6554097 {
- @SuppressWarnings("serial") final Throwable[] v1 = { new Throwable() {} };
- @SuppressWarnings("serial") Throwable[] v2 = { new Throwable() {} };
+
+ @SuppressWarnings("unchecked") final ArrayList[] v1 = { new ArrayList() {} };
+ @SuppressWarnings("unchecked") ArrayList[] v2 = { new ArrayList() {} };
public static void m1() throws Throwable {
- @SuppressWarnings("serial") final Throwable[] v3 = { new Throwable() {} };
- @SuppressWarnings("serial") Throwable[] v4 = { new Throwable() {} };
+ @SuppressWarnings("unchecked") final ArrayList[] v3 = { new ArrayList() {} };
+ @SuppressWarnings("unchecked") ArrayList[] v4 = { new ArrayList() {} };
}
- final Throwable[] v5 = { new Throwable() {} };
- Throwable[] v6 = { new Throwable() {} };
+ final ArrayList[] v5 = { new ArrayList() {} };
+ ArrayList[] v6 = { new ArrayList() {} };
public static void m2() throws Throwable {
- final Throwable[] v7 = { new Throwable() {} };
- Throwable[] v8 = { new Throwable() {} };
+ final ArrayList[] v7 = { new ArrayList() {} };
+ ArrayList[] v8 = { new ArrayList() {} };
}
}
--- a/langtools/test/tools/javac/T6554097.out Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/T6554097.out Thu Apr 28 23:08:17 2016 -0700
@@ -1,7 +1,19 @@
-T6554097.java:18:46: compiler.warn.missing.SVUID: compiler.misc.anonymous.class: T6554097$5
-T6554097.java:19:46: compiler.warn.missing.SVUID: compiler.misc.anonymous.class: T6554097$6
-T6554097.java:22:50: compiler.warn.missing.SVUID: compiler.misc.anonymous.class: T6554097$7
-T6554097.java:23:54: compiler.warn.missing.SVUID: compiler.misc.anonymous.class: T6554097$8
+T6554097.java:13:42: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:13:65: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:14:42: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:14:65: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:17:50: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:17:73: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:18:50: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:18:73: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:21:11: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:21:34: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:22:11: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:22:34: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:25:15: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:25:38: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:26:15: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:26:38: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
- compiler.err.warnings.and.werror
1 error
-4 warnings
+16 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrAvoidNullCheck.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7020499
+ * @summary Verify that try-with-resources desugaring is not generating unnecessary null checks
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.code
+ * jdk.compiler/com.sun.tools.javac.comp
+ * jdk.compiler/com.sun.tools.javac.main
+ * jdk.compiler/com.sun.tools.javac.tree
+ * jdk.compiler/com.sun.tools.javac.util
+ * @build toolbox.ToolBox toolbox.JavacTask TwrAvoidNullCheck
+ * @run main TwrAvoidNullCheck
+ */
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.comp.AttrContext;
+import com.sun.tools.javac.comp.Env;
+import com.sun.tools.javac.comp.Lower;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCBinary;
+import com.sun.tools.javac.tree.TreeInfo;
+import com.sun.tools.javac.tree.TreeMaker;
+import com.sun.tools.javac.tree.TreeScanner;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Context.Factory;
+import com.sun.tools.javac.util.List;
+
+import toolbox.ToolBox;
+
+public class TwrAvoidNullCheck {
+ public static void main(String... args) throws IOException {
+ new TwrAvoidNullCheck().run();
+ }
+ void run() throws IOException {
+ run("new Test()", false);
+ run("null", true);
+ run("System.getProperty(\"test\") != null ? new Test() : null", true);
+ }
+ void run(String resourceSpecification, boolean expected) throws IOException {
+ String template = "public class Test implements AutoCloseable {\n" +
+ " void t() {\n" +
+ " try (Test resource = RESOURCE) { }\n" +
+ " }\n" +
+ " public void close() { }\n" +
+ "}\n";
+ String code = template.replace("RESOURCE", resourceSpecification);
+ Context ctx = new Context();
+ DumpLower.preRegister(ctx);
+ Iterable<ToolBox.JavaSource> files = Arrays.asList(new ToolBox.JavaSource(code));
+ JavacTask task = JavacTool.create().getTask(null, null, null, null, null, files, ctx);
+ task.call();
+
+ boolean hasNullCheck = ((DumpLower) DumpLower.instance(ctx)).hasNullCheck;
+
+ if (hasNullCheck != expected) {
+ throw new IllegalStateException("expected: " + expected +
+ "; actual: " + hasNullCheck +
+ "; code: " + code);
+ }
+ }
+
+ static class DumpLower extends Lower {
+
+ public static void preRegister(Context ctx) {
+ ctx.put(lowerKey, new Factory<Lower>() {
+ @Override
+ public Lower make(Context c) {
+ return new DumpLower(c);
+ }
+ });
+ }
+
+ public DumpLower(Context context) {
+ super(context);
+ }
+
+ boolean hasNullCheck;
+
+ @Override
+ public List<JCTree> translateTopLevelClass(Env<AttrContext> env, JCTree cdef, TreeMaker make) {
+ List<JCTree> result = super.translateTopLevelClass(env, cdef, make);
+
+ new TreeScanner() {
+ @Override
+ public void visitBinary(JCBinary tree) {
+ hasNullCheck |= tree.operator.getSimpleName().contentEquals("!=") &&
+ "resource".equals(String.valueOf(TreeInfo.name(tree.lhs))) &&
+ TreeInfo.isNull(tree.rhs);
+ super.visitBinary(tree);
+ }
+ }.scan(result);
+
+ return result;
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrClose.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7020499
+ * @summary Verify that the close resource code works properly in all cases
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.comp
+ * jdk.compiler/com.sun.tools.javac.main
+ * @build toolbox.ToolBox TwrClose
+ * @run main TwrClose
+ */
+
+import javax.tools.JavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+import com.sun.tools.javac.comp.Lower;
+
+import toolbox.JavacTask;
+import toolbox.ToolBox;
+
+public class TwrClose {
+
+ public static void main(String... args) throws Exception {
+ for (int i = 1; i < Lower.USE_CLOSE_RESOURCE_METHOD_THRESHOLD * 2; i++) {
+ new TwrClose().compile(i);
+ }
+ }
+
+ ToolBox tb = new ToolBox();
+ JavaFileManager fm = ToolProvider.getSystemJavaCompiler()
+ .getStandardFileManager(null, null, null);
+
+ void compile(int trysCount) throws Exception {
+ StringBuilder testInvocations = new StringBuilder();
+ StringBuilder testMethods = new StringBuilder();
+
+ for (int i = 0; i < trysCount; i++) {
+ testInvocations.append(TEST_INVOCATIONS_TEMPLATE.replace("#N", Integer.toString(i)));
+ testMethods.append(TEST_METHOD_TEMPLATE.replace("#N", Integer.toString(i)));
+ }
+
+ String sourceCode = FILE_TEMPLATE.replace("#TEST_INVOCATIONS", testInvocations.toString())
+ .replace("#TEST_METHODS", testMethods.toString());
+
+ System.err.println("analyzing:");
+ System.err.println(sourceCode);
+
+ try (ToolBox.MemoryFileManager mfm = new ToolBox.MemoryFileManager()) {
+ new JavacTask(tb).fileManager(mfm)
+ .sources(sourceCode)
+ .run()
+ .writeAll();
+ ClassLoader cl = new ClassLoader(TwrClose.class.getClassLoader()) {
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ byte[] data = mfm.getFileBytes(StandardLocation.CLASS_OUTPUT, name);
+ if (data != null) {
+ return defineClass(name, data, 0, data.length);
+ }
+ return super.findClass(name);
+ }
+ };
+
+ ((Runnable) cl.loadClass("Test").newInstance()).run();
+ }
+ }
+
+ final String TEST_INVOCATIONS_TEMPLATE =
+ " test#N(false, false, Arrays.asList(\"close\"));\n" +
+ " test#N(false, true, Arrays.asList(\"close\", \"close-exception\"));\n" +
+ " test#N(true, false, Arrays.asList(\"close\", \"inTwr\"));\n" +
+ " test#N(true, true, Arrays.asList(\"close\", \"inTwr\", \"close-exception\"));\n";
+
+ final String TEST_METHOD_TEMPLATE =
+ " private void test#N(boolean failInTwr, boolean failOnClose,\n" +
+ " List<String> expectedMessages) {\n" +
+ " List<String> messages = new ArrayList<>();\n" +
+ " try {\n" +
+ " try (CloseableImpl c = new CloseableImpl(messages, failOnClose)) {\n" +
+ " if (failInTwr)\n" +
+ " throw new IllegalStateException(\"inTwr\");\n" +
+ " }\n" +
+ " } catch (IllegalStateException ex) {\n" +
+ " messages.add(ex.getMessage());\n" +
+ " for (Throwable t : ex.getSuppressed()) {\n" +
+ " messages.add(t.getMessage());\n" +
+ " }\n" +
+ " }\n" +
+ " if (!expectedMessages.equals(messages))\n" +
+ " throw new AssertionError(\"Expected and actual messages differ; expectedMessages=\" +\n" +
+ " expectedMessages + \"; actual=\" + messages);\n" +
+ " }\n";
+
+ final String FILE_TEMPLATE =
+ "import java.util.*;\n" +
+ "public class Test implements Runnable {\n" +
+ " public void run() {\n" +
+ "#TEST_INVOCATIONS" +
+ " }\n" +
+ "#TEST_METHODS" +
+ " static class CloseableImpl implements AutoCloseable {\n" +
+ " private final List<String> messages;\n" +
+ " private final boolean failOnClose;\n" +
+ " public CloseableImpl(List<String> messages, boolean failOnClose) {\n" +
+ " this.messages = messages;\n" +
+ " this.failOnClose = failOnClose;\n" +
+ " }\n" +
+ " @Override\n" +
+ " public void close() {\n" +
+ " messages.add(\"close\");\n" +
+ " if (failOnClose)\n" +
+ " throw new IllegalStateException(\"close-exception\");\n" +
+ " }\n" +
+ " }\n" +
+ "}\n";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrShareCloseCode.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7020499
+ * @summary Verify that the code that closes the resources is shared by among try-with-resources
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.code
+ * jdk.compiler/com.sun.tools.javac.comp
+ * jdk.compiler/com.sun.tools.javac.tree
+ * jdk.compiler/com.sun.tools.javac.util
+ * @build toolbox.ToolBox TwrShareCloseCode
+ * @run main TwrShareCloseCode
+ */
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.comp.AttrContext;
+import com.sun.tools.javac.comp.Env;
+import com.sun.tools.javac.comp.Lower;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
+import com.sun.tools.javac.tree.TreeInfo;
+import com.sun.tools.javac.tree.TreeMaker;
+import com.sun.tools.javac.tree.TreeScanner;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Context.Factory;
+import com.sun.tools.javac.util.List;
+
+import toolbox.ToolBox;
+
+public class TwrShareCloseCode {
+ public static void main(String... args) throws IOException {
+ new TwrShareCloseCode().run();
+ }
+
+ void run() throws IOException {
+ run("try (Test t1 = new Test()) { }", true);
+ run("try (Test t1 = new Test()) { }\n" +
+ "try (Test t2 = new Test()) { }", true);
+ run("try (Test t1 = new Test();\n" +
+ " Test t2 = new Test()) { }", true);
+ run("try (Test t1 = new Test()) { }\n" +
+ "try (Test t2 = new Test()) { }\n" +
+ "try (Test t3 = new Test()) { }", true);
+ run("try (Test t1 = new Test();\n" +
+ " Test t2 = new Test();\n" +
+ " Test t3 = new Test()) { }", false);
+ run("try (Test t1 = new Test()) { }\n" +
+ "try (Test t2 = new Test()) { }\n" +
+ "try (Test t3 = new Test()) { }\n" +
+ "try (Test t4 = new Test()) { }", false);
+
+ run("try (Test t1 = new Test()) { i++; }", true);
+ run("try (Test t1 = new Test()) { i++; }\n" +
+ "try (Test t2 = new Test()) { i++; }", false);
+
+ run("try (Test t1 = new Test(); Test t2 = new Test()) { i++; }", false);
+
+ run("try (Test t1 = new Test()) { i++; }\n" +
+ "try (Test t2 = new Test()) { }", true);
+
+ run("try (Test t1 = new Test()) { i++; }\n" +
+ "try (Test t2 = new Test()) { }\n" +
+ "try (Test t3 = new Test()) { }", false);
+
+ run("try (Test t1 = new Test()) { i++; }\n" +
+ "try (Test t2 = new Test()) { i++; }\n" +
+ "try (Test t3 = new Test()) { }", false);
+ }
+ void run(String trySpec, boolean expected) throws IOException {
+ String template = "public class Test implements AutoCloseable {\n" +
+ " void t(int i) {\n" +
+ " TRY\n" +
+ " }\n" +
+ " public void close() { }\n" +
+ "}\n";
+ String code = template.replace("TRY", trySpec);
+ Context ctx = new Context();
+ DumpLower.preRegister(ctx);
+ Iterable<ToolBox.JavaSource> files = Arrays.asList(new ToolBox.JavaSource(code));
+ JavacTask task = JavacTool.create().getTask(null, null, null, null, null, files, ctx);
+ task.call();
+ boolean actual = ((DumpLower) DumpLower.instance(ctx)).closeSeen;
+
+ if (expected != actual) {
+ throw new IllegalStateException("expected: " + expected + "; actual: " + actual + "; code:\n" + code);
+ }
+ }
+
+ static class DumpLower extends Lower {
+
+ public static void preRegister(Context ctx) {
+ ctx.put(lowerKey, new Factory<Lower>() {
+ @Override
+ public Lower make(Context c) {
+ return new DumpLower(c);
+ }
+ });
+ }
+
+ public DumpLower(Context context) {
+ super(context);
+ }
+
+ boolean closeSeen;
+
+ @Override
+ public List<JCTree> translateTopLevelClass(Env<AttrContext> env, JCTree cdef, TreeMaker make) {
+ List<JCTree> result = super.translateTopLevelClass(env, cdef, make);
+
+ new TreeScanner() {
+ @Override
+ public void visitMethodDef(JCMethodDecl tree) {
+ if (!tree.name.contentEquals("t"))
+ return;
+
+ super.visitMethodDef(tree);
+ }
+
+ @Override
+ public void visitApply(JCMethodInvocation tree) {
+ closeSeen |= TreeInfo.symbol(tree.meth).name.contentEquals("close");
+ super.visitApply(tree);
+ }
+ }.scan(result);
+
+ return result;
+ }
+
+ }
+}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ResourceVariable.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ResourceVariable.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,9 +36,9 @@
public class ResourceVariable {
@TADescription(annotation = "TA", type = RESOURCE_VARIABLE,
- lvarOffset = {10}, lvarLength = {118}, lvarIndex = {1})
+ lvarOffset = {10}, lvarLength = {106}, lvarIndex = {1})
@TADescription(annotation = "TB", type = RESOURCE_VARIABLE,
- lvarOffset = {22}, lvarLength = {35}, lvarIndex = {3})
+ lvarOffset = {22}, lvarLength = {31}, lvarIndex = {3})
public String testResourceVariable() {
return
"public void f() throws IOException {" + lineSeparator() +
@@ -49,7 +49,7 @@
}
@TADescription(annotation = "RTAs", type = RESOURCE_VARIABLE,
- lvarOffset = {10}, lvarLength = {30}, lvarIndex = {1})
+ lvarOffset = {10}, lvarLength = {26}, lvarIndex = {1})
public String testRepeatedAnnotation1() {
return
"public void f() throws IOException {" + lineSeparator() +
@@ -58,7 +58,7 @@
}
@TADescription(annotation = "RTAs", type = RESOURCE_VARIABLE,
- lvarOffset = {10}, lvarLength = {30}, lvarIndex = {1})
+ lvarOffset = {10}, lvarLength = {26}, lvarIndex = {1})
public String testRepeatedAnnotation2() {
return
"public void f() throws IOException {" + lineSeparator() +
@@ -67,9 +67,9 @@
}
@TADescription(annotation = "TA", type = RESOURCE_VARIABLE,
- lvarOffset = {10}, lvarLength = {118}, lvarIndex = {1})
+ lvarOffset = {10}, lvarLength = {106}, lvarIndex = {1})
@TADescription(annotation = "TB", type = RESOURCE_VARIABLE,
- lvarOffset = {22}, lvarLength = {35}, lvarIndex = {3})
+ lvarOffset = {22}, lvarLength = {31}, lvarIndex = {3})
public String testSeveralVariablesInTryWithResources() {
return
"public void f() throws IOException {" + lineSeparator() +
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Test.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Test.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,25 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
import java.util.*;
import java.lang.annotation.*;
--- a/langtools/test/tools/javac/api/6731573/Erroneous.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/api/6731573/Erroneous.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,5 @@
+/* /nodynamiccopyright/ */
+
class A {
boolean b;
boolean b;
--- a/langtools/test/tools/javac/diags/examples/AnonymousClass.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/diags/examples/AnonymousClass.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,12 +22,15 @@
*/
// key: compiler.misc.anonymous.class
-// key: compiler.warn.missing.SVUID
-// options: -Xlint:serial
+// key: compiler.err.prob.found.req
+// key: compiler.misc.inconvertible.types
+// options: -Xlint:rawtypes
// run: simple
+import java.util.ArrayList;
+
class AnonymousClass {
- Exception m() {
- return new Exception() { };
+ Object m() {
+ return (ArrayList<String>) new ArrayList<Object>() { };
}
}
--- a/langtools/test/tools/javac/flow/T8062747.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/flow/T8062747.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
/**
* @test
* @bug 8062747
--- a/langtools/test/tools/javac/flow/tests/TestCaseTry.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/flow/tests/TestCaseTry.java Thu Apr 28 23:08:17 2016 -0700
@@ -52,9 +52,9 @@
o = "";
}
- @AliveRange(varName="o", bytecodeStart=22, bytecodeLength=38)
- @AliveRange(varName="o", bytecodeStart=103, bytecodeLength=3)
- @AliveRange(varName="o", bytecodeStart=110, bytecodeLength=1)
+ @AliveRange(varName="o", bytecodeStart=22, bytecodeLength=13)
+ @AliveRange(varName="o", bytecodeStart=53, bytecodeLength=3)
+ @AliveRange(varName="o", bytecodeStart=60, bytecodeLength=1)
void m3() {
Object o;
try (BufferedReader br =
@@ -65,8 +65,8 @@
o = "";
}
- @AliveRange(varName="o", bytecodeStart=12, bytecodeLength=96)
- @AliveRange(varName="o", bytecodeStart=112, bytecodeLength=1)
+ @AliveRange(varName="o", bytecodeStart=12, bytecodeLength=46)
+ @AliveRange(varName="o", bytecodeStart=62, bytecodeLength=1)
void m4() {
String o;
try (BufferedReader br =
--- a/langtools/test/tools/javac/generics/Nonlinear.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/generics/Nonlinear.java Thu Apr 28 23:08:17 2016 -0700
@@ -22,7 +22,7 @@
// the program.
public static void main (String [] args) {
- Integer x = new Integer (5);
+ Integer x = Integer.valueOf(5);
String y = castit (x);
System.out.println (y);
}
--- a/langtools/test/tools/javac/generics/odersky/BadTest4.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/generics/odersky/BadTest4.java Thu Apr 28 23:08:17 2016 -0700
@@ -30,7 +30,7 @@
static <A> Cell<A> makeCell(A x) { return new Cell<A>(x); }
static <A> A id(A x) { return x; }
- static Integer i = new Integer(1);
+ static Integer i = Integer.valueOf(1);
static Number n = i;
public static void main(String[] args) {
--- a/langtools/test/tools/javac/jvm/6397652/com/test/Test$Test$Test.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/jvm/6397652/com/test/Test$Test$Test.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * 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 com.test;
public class Test$Test$Test {
--- a/langtools/test/tools/javac/jvm/6397652/com/test/Test$Test.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/jvm/6397652/com/test/Test$Test.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * 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 com.test;
public class Test$Test {
--- a/langtools/test/tools/javac/lambda/8074381/T8074381a.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/lambda/8074381/T8074381a.java Thu Apr 28 23:08:17 2016 -0700
@@ -13,6 +13,7 @@
boolean m(String s);
}
+ @SuppressWarnings("deprecation")
void testRaw() {
Sub s1 = c -> true;
Sub s2 = Boolean::new;
@@ -22,6 +23,7 @@
};
}
+ @SuppressWarnings("deprecation")
void testNonRaw() {
Sub<Integer> s1 = c -> true;
Sub<Integer> s2 = Boolean::new;
--- a/langtools/test/tools/javac/lambda/8074381/T8074381a.out Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/lambda/8074381/T8074381a.out Thu Apr 28 23:08:17 2016 -0700
@@ -1,4 +1,4 @@
-T8074381a.java:17:18: compiler.err.prob.found.req: (compiler.misc.no.suitable.functional.intf.inst: T8074381a.Sub)
T8074381a.java:18:18: compiler.err.prob.found.req: (compiler.misc.no.suitable.functional.intf.inst: T8074381a.Sub)
-T8074381a.java:19:28: compiler.err.does.not.override.abstract: compiler.misc.anonymous.class: T8074381a$1, m(java.lang.Object), T8074381a.Sup
+T8074381a.java:19:18: compiler.err.prob.found.req: (compiler.misc.no.suitable.functional.intf.inst: T8074381a.Sub)
+T8074381a.java:20:28: compiler.err.does.not.override.abstract: compiler.misc.anonymous.class: T8074381a$1, m(java.lang.Object), T8074381a.Sup
3 errors
--- a/langtools/test/tools/javac/lambda/TargetType27.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType27.java Thu Apr 28 23:08:17 2016 -0700
@@ -15,6 +15,6 @@
<A, R> F<A, R> m(F<A, R> f) { return null; }
void test() {
- m((String s1) -> (String s2) -> new Integer(1));
+ m((String s1) -> (String s2) -> Integer.valueOf(1));
}
}
--- a/langtools/test/tools/javac/lambda/badMemberRefBytecode/Main.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/lambda/badMemberRefBytecode/Main.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
import java.util.Collections;
public class Main {
@@ -6,4 +29,5 @@
Collections.<String>sort(null, String::compareTo);
}
+
}
--- a/langtools/test/tools/javac/lambda/badMemberRefBytecode/Use.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/lambda/badMemberRefBytecode/Use.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
public class Use {
private Main m;
}
--- a/langtools/test/tools/javac/lambda/lambdaExecution/TBlock.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/lambda/lambdaExecution/TBlock.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
/**
* Performs operations upon an input object which may modify that object and/or
* external state (other objects).
--- a/langtools/test/tools/javac/policy/test3/A.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/policy/test3/A.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,5 @@
+/* /nodynamiccopyright/ */
+
class A {
void m1() {
System.err.println("hello");
--- a/langtools/test/tools/javac/positions/T6253161.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * @test /nodynamiccopyright/
- * @bug 6253161
- * @summary Compiler will fail to find the correct location of serial warnings for anonymous inner classes
- * @author Seetharama Avadhanam
- * @compile -Xlint:serial -XDdev T6253161.java
- * @compile/ref=T6253161.out -Xlint:serial -XDdev -XDrawDiagnostics T6253161.java
- */
-import java.util.List;
-import java.util.ArrayList;
-
-public class T6253161 {
- @SuppressWarnings("unchecked")
- public void anonymousMethod(){
- List list = new ArrayList<String>(){
- static final long serialVersionUID = 1;
- List list = new ArrayList<Integer>();
- public List<Integer> getMyList(){
- final List floatList = new ArrayList<Float>(){
- List integerList = new ArrayList<Float>();
- public List<Float> getMyList(){
- for(int i=0;i<10;i++)
- integerList.add((int)((Float.parseFloat(i+""))+(1.11F)));
- return (List)(Object)integerList;
- }
- public void testMethods(){
- //...
- }
- }.getMyList();
- for(int i=0;i<10;i++)
- list.add((Float)(floatList.get(i)) * 11.232F * i);
- return list;
- }
- }.getMyList();
- }
-}
--- a/langtools/test/tools/javac/positions/T6253161.out Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-T6253161.java:19:62: compiler.warn.missing.SVUID: compiler.misc.anonymous.class: T6253161$1$1
-1 warning
--- a/langtools/test/tools/javac/positions/T6253161a.java Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * @test /nodynamiccopyright/
- * @bug 6253161
- * @summary Compiler will fail to find the correct location of serial warnings for anonymous inner classes
- * @author Seetharama Avadhanam
- * @compile -Xlint:serial -XDdev T6253161a.java
- * @compile/ref=T6253161a.out -Xlint:serial -XDdev -XDrawDiagnostics T6253161a.java
- */
-import java.util.List;
-import java.util.ArrayList;
-
-public class T6253161a {
- @SuppressWarnings("unchecked")
- public void anonymousMethod(){
- List list = new ArrayList<String>(){
- static final long serialVersionUID = 1;
- List list = new ArrayList<Integer>();
- public List<Integer> getMyList(){
- final List floatList = new ArrayList<Float>(){
- // Blank ....
- };
- for(int i=0;i<10;i++)
- list.add((Float)(floatList.get(i)) * 11.232F * i);
- return list;
- }
- }.getMyList();
- }
-}
--- a/langtools/test/tools/javac/positions/T6253161a.out Thu Apr 28 00:38:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-T6253161a.java:19:62: compiler.warn.missing.SVUID: compiler.misc.anonymous.class: T6253161a$1$1
-1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/serial/SerialWarn.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,11 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 4854628
+ * @summary include Throwable subclasses in missing serialVersionUID warning
+ * @author gafter
+ *
+ * @compile -Werror SerialWarn.java
+ * @compile/fail/ref=SerialWarn.out -XDrawDiagnostics -Xlint:serial -Werror SerialWarn.java
+ */
+
+class SerialWarn extends Throwable {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/serial/SerialWarn.out Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,4 @@
+SerialWarn.java:11:1: compiler.warn.missing.SVUID: SerialWarn
+- compiler.err.warnings.and.werror
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/serial/SerialWarnAnon.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7152104
+ * @summary Make sure no warning is emitted for anonymous classes
+ * without serialVersionUID
+ * @compile SerialWarn.java
+ * @compile -Werror -XDrawDiagnostics -Xlint:serial SerialWarnAnon.java
+ */
+
+class SerialWarnAnon {
+ interface SerialWarnAnonInterface extends java.io.Serializable { }
+ Object m() {
+ return new SerialWarnAnonInterface() { };
+ }
+}
--- a/langtools/test/tools/javac/synthesize/src/Double.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/synthesize/src/Double.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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;
public class Double extends Number
--- a/langtools/test/tools/javac/synthesize/src/Float.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/synthesize/src/Float.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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;
public class Float extends Number
--- a/langtools/test/tools/javac/warnings/6594914/Auxiliary.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/warnings/6594914/Auxiliary.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,5 @@
+/* /nodynamiccopyright/ */
+
import java.io.StringBufferInputStream;
public class Auxiliary {
--- a/langtools/test/tools/javac/warnings/6594914/ExplicitCompilation.out Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/warnings/6594914/ExplicitCompilation.out Thu Apr 28 23:08:17 2016 -0700
@@ -1,2 +1,2 @@
-Auxiliary.java:1:15: compiler.warn.has.been.deprecated: java.io.StringBufferInputStream, java.io
+Auxiliary.java:3:15: compiler.warn.has.been.deprecated: java.io.StringBufferInputStream, java.io
1 warning
--- a/langtools/test/tools/javac/warnings/6594914/ImplicitCompilation.out Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javac/warnings/6594914/ImplicitCompilation.out Thu Apr 28 23:08:17 2016 -0700
@@ -1,2 +1,2 @@
-Auxiliary.java:1:15: compiler.warn.has.been.deprecated: java.io.StringBufferInputStream, java.io
+Auxiliary.java:3:15: compiler.warn.has.been.deprecated: java.io.StringBufferInputStream, java.io
1 warning
--- a/langtools/test/tools/javadoc/6964914/TestStdDoclet.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javadoc/6964914/TestStdDoclet.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
*/
import java.io.*;
+import java.util.*;
/**
* Dummy javadoc comment.
@@ -54,13 +55,21 @@
// run javadoc in separate process to ensure doclet executed under
// normal user conditions w.r.t. classloader
String thisClassName = TestStdDoclet.class.getName();
- Process p = new ProcessBuilder()
- .command(javadoc.getPath(),
- "-J-Xpatch:" + System.getProperty("jdk.launcher.patch.0", ""),
+ List<String> cmdArgs = new ArrayList<>();
+ cmdArgs.add(javadoc.getPath());
+ int i = 0;
+ String prop;
+ while ((prop = System.getProperty("jdk.launcher.patch." + (i++))) != null) {
+ cmdArgs.add("-J-Xpatch:" + prop);
+ }
+ cmdArgs.addAll(Arrays.asList(
"-classpath", ".", // insulates us from ambient classpath
"-Xdoclint:none",
"-package",
- new File(testSrc, thisClassName + ".java").getPath())
+ new File(testSrc, thisClassName + ".java").getPath()
+ ));
+ Process p = new ProcessBuilder()
+ .command(cmdArgs)
.redirectErrorStream(true)
.start();
--- a/langtools/test/tools/javadoc/6964914/TestUserDoclet.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javadoc/6964914/TestUserDoclet.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,8 @@
*/
import java.io.*;
+import java.util.*;
+
import com.sun.javadoc.Doclet;
import com.sun.javadoc.RootDoc;
@@ -55,12 +57,20 @@
// run javadoc in separate process to ensure doclet executed under
// normal user conditions w.r.t. classloader
String thisClassName = TestUserDoclet.class.getName();
- Process p = new ProcessBuilder()
- .command(javadoc.getPath(),
- "-J-Xpatch:" + System.getProperty("jdk.launcher.patch.0", ""),
+ List<String> cmdArgs = new ArrayList<>();
+ cmdArgs.add(javadoc.getPath());
+ int i = 0;
+ String prop;
+ while ((prop = System.getProperty("jdk.launcher.patch." + (i++))) != null) {
+ cmdArgs.add("-J-Xpatch:" + prop);
+ }
+ cmdArgs.addAll(Arrays.asList(
"-doclet", thisClassName,
"-docletpath", testClasses.getPath(),
- new File(testSrc, thisClassName + ".java").getPath())
+ new File(testSrc, thisClassName + ".java").getPath()
+ ));
+ Process p = new ProcessBuilder()
+ .command(cmdArgs)
.redirectErrorStream(true)
.start();
--- a/langtools/test/tools/javadoc/sampleapi/lib/sampleapi/SampleApi.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javadoc/sampleapi/lib/sampleapi/SampleApi.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -53,5 +53,8 @@
public Fault(String msg) {
super(msg);
}
+ public Fault(String msg, Throwable th) {
+ super(msg, th);
+ }
}
}
--- a/langtools/test/tools/javadoc/sampleapi/lib/sampleapi/generator/DocCommentGenerator.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javadoc/sampleapi/lib/sampleapi/generator/DocCommentGenerator.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,8 @@
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.List;
+import java.util.HashMap;
+import java.util.Map;
class DocCommentGenerator {
@@ -99,14 +101,25 @@
LITERAL("@literal", "Use < and > brackets instead of < and > escapes."),
CODE("@code", "(i) -> new Abc<Object>((i > 0) ? (i << 1) : 0)"),
LINK("@link", ""),
- VALUE("@value", "");
+ VALUE("@value", ""),
+ INDEX("@index", "", true);
String tagName;
String tagValue;
+ boolean counted;
+ Map<String, Integer> counters;
InlineTag(String tagName, String tagValue) {
+ this(tagName, tagValue, false);
+ }
+
+ InlineTag(String tagName, String tagValue, boolean counted) {
this.tagName = tagName;
this.tagValue = tagValue;
+ this.counted = counted;
+ if (counted) {
+ counters = new HashMap<>();
+ }
}
public String toString() {
@@ -114,9 +127,14 @@
}
public String value(String value) {
+ String name = ((tagValue.length() != 0) ? " " + tagValue : "")
+ + ((value.length() != 0) ? " " + value : "");
+ if (counted && !counters.containsKey(name)) {
+ counters.put(name, 0);
+ }
return "{" + tagName
- + ((tagValue.length() != 0) ? " " + tagValue : "")
- + ((value.length() != 0) ? " " + value : "")
+ + name
+ + (counted ? "_" + counters.put(name, counters.get(name) + 1) : "")
+ "}";
}
}
@@ -179,7 +197,8 @@
//
public String getPackageComment() {
- return Text.LOREMIPSUM
+ return InlineTag.INDEX.value("PackageCommentLabel") + " "
+ + Text.LOREMIPSUM
+ "\n <p>" + Text.LIEUROPANLINGUES
+ "\n" + Text.CODE
+ "\n" + LinkTag.nextLink()
@@ -192,7 +211,9 @@
static int serialValIdx = 0;
public String getBaseComment(JCClassDecl baseDecl, boolean toplevel) {
- String buildComment = Text.LIEUROPANLINGUES + "\n";
+ String buildComment = InlineTag.INDEX.value("BaseCommentLabel") + " ";
+
+ buildComment += Text.LIEUROPANLINGUES + "\n";
buildComment += "<p>It is possible to see inlined code:\n"
+ InlineTag.CODE
@@ -237,8 +258,9 @@
}
public String getConstComment() {
- String buildComment = Text.NOWISTHETIME + " " + Text.BROWNFOX + "\n";
+ String buildComment = InlineTag.INDEX.value("ConstCommentLabel") + " ";
+ buildComment += Text.NOWISTHETIME + " " + Text.BROWNFOX + "\n";
buildComment += LinkTag.nextLink() + "\n";
buildComment += LinkTag.nextSee() + "\n";
buildComment += Tag.SINCE + "\n";
@@ -249,8 +271,9 @@
public String getFieldComment(JCClassDecl baseDecl,
JCVariableDecl varDecl,
boolean isFxStyle) {
- String buildComment = Text.BROWNFOX + "<p>" + Text.NOWISTHETIME + "\n";
+ String buildComment = InlineTag.INDEX.value("FieldCommentLabel") + " ";
+ buildComment += Text.BROWNFOX + "<p>" + Text.NOWISTHETIME + "\n";
Set<Modifier> mods = varDecl.getModifiers().getFlags();
String varName = varDecl.getName().toString();
@@ -299,7 +322,9 @@
public String getMethodComment(JCClassDecl baseDecl,
JCMethodDecl methodDecl,
boolean isFxStyle) {
- String buildComment = Text.BROWNFOX + "\n<p>" + Text.THISPANGRAM + "\n";
+ String buildComment = InlineTag.INDEX.value("MethodCommentLabel") + " ";
+
+ buildComment += Text.BROWNFOX + "\n<p>" + Text.THISPANGRAM + "\n";
buildComment += "<p>" + LinkTag.nextLink() + "\n";
--- a/langtools/test/tools/javadoc/sampleapi/lib/sampleapi/generator/PackageGenerator.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javadoc/sampleapi/lib/sampleapi/generator/PackageGenerator.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -125,7 +125,7 @@
processTopLevel((Element)node);
}
} catch (ParserConfigurationException | SAXException | IOException e) {
- throw new Fault("Error parsing dataset " + dsName);
+ throw new Fault("Error parsing dataset " + dsName, e);
}
fx = false;
--- a/langtools/test/tools/javap/4111861/A.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/javap/4111861/A.java Thu Apr 28 23:08:17 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
class A {
public static final int i = 42;
public static final boolean b = true;
--- a/langtools/test/tools/sjavac/HiddenFiles.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/sjavac/HiddenFiles.java Thu Apr 28 23:08:17 2016 -0700
@@ -36,6 +36,7 @@
* @run main Wrapper HiddenFiles
*/
+import com.sun.tools.javac.main.Main.Result;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.sjavac.server.Sjavac;
@@ -62,6 +63,6 @@
"-d", BIN.toString(),
"--state-dir=" + STATE_DIR);
- Assert.check(rc == Sjavac.RC_FATAL, "Compilation succeeded unexpectedly.");
+ Assert.check(rc == Result.ERROR.exitCode, "Compilation succeeded unexpectedly.");
}
}
--- a/langtools/test/tools/sjavac/IdleShutdown.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/sjavac/IdleShutdown.java Thu Apr 28 23:08:17 2016 -0700
@@ -29,9 +29,9 @@
* @build Wrapper
* @run main Wrapper IdleShutdown
*/
-import java.io.Writer;
import java.util.concurrent.atomic.AtomicLong;
+import com.sun.tools.javac.main.Main.Result;
import com.sun.tools.sjavac.server.IdleResetSjavac;
import com.sun.tools.sjavac.server.Sjavac;
import com.sun.tools.sjavac.server.Terminable;
@@ -103,13 +103,13 @@
public void shutdown() {
}
@Override
- public int compile(String[] args) {
+ public Result compile(String[] args) {
// Attempt to trigger idle timeout during a call by sleeping
try {
Thread.sleep(TIMEOUT_MS + 1000);
} catch (InterruptedException e) {
}
- return 0;
+ return Result.OK;
}
}
}
--- a/langtools/test/tools/sjavac/IncludeExcludePatterns.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/sjavac/IncludeExcludePatterns.java Thu Apr 28 23:08:17 2016 -0700
@@ -33,6 +33,7 @@
* @run main Wrapper IncludeExcludePatterns
*/
+import com.sun.tools.javac.main.Main.Result;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.sjavac.server.Sjavac;
@@ -131,7 +132,7 @@
int rc = compile((Object[]) args.split(" "));
// Compilation should always pass in these tests
- Assert.check(rc == Sjavac.RC_OK, "Compilation failed unexpectedly.");
+ Assert.check(rc == Result.OK.exitCode, "Compilation failed unexpectedly.");
// The resulting .class files should correspond to the visible source files
Set<Path> result = allFilesInDir(BIN);
--- a/langtools/test/tools/sjavac/PooledExecution.java Thu Apr 28 00:38:21 2016 -0700
+++ b/langtools/test/tools/sjavac/PooledExecution.java Thu Apr 28 23:08:17 2016 -0700
@@ -30,12 +30,10 @@
* @build Wrapper
* @run main Wrapper PooledExecution
*/
-import java.io.PrintWriter;
-import java.io.Writer;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
-import com.sun.tools.sjavac.Log;
+import com.sun.tools.javac.main.Main.Result;
import com.sun.tools.sjavac.comp.PooledSjavac;
import com.sun.tools.sjavac.server.Sjavac;
@@ -111,7 +109,7 @@
AtomicInteger activeRequests = new AtomicInteger(0);
@Override
- public int compile(String[] args) {
+ public Result compile(String[] args) {
leftToStart.countDown();
int numActiveRequests = activeRequests.incrementAndGet();
System.out.printf("Left to start: %2d / Currently active: %2d%n",
@@ -125,7 +123,7 @@
}
activeRequests.decrementAndGet();
System.out.println("Task completed");
- return 0;
+ return Result.OK;
}
@Override
--- a/make/CompileJavaModules.gmk Thu Apr 28 00:38:21 2016 -0700
+++ b/make/CompileJavaModules.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -98,7 +98,8 @@
################################################################################
-java.desktop_ADD_JAVAC_FLAGS := -Xdoclint:all/protected,-reference '-Xdoclint/package:java.*,javax.*'
+java.desktop_ADD_JAVAC_FLAGS := -Xdoclint:all/protected,-reference \
+ '-Xdoclint/package:java.*,javax.*' -Xlint:-deprecation
java.desktop_COPY := .gif .png .wav .txt .xml .css .pf
java.desktop_CLEAN := iio-plugin.properties cursors.properties
--- a/make/InitSupport.gmk Thu Apr 28 00:38:21 2016 -0700
+++ b/make/InitSupport.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -331,7 +331,7 @@
BUILD_LOG := $(OUTPUT_ROOT)/build.log
BUILD_TRACE_LOG := $(OUTPUT_ROOT)/build-trace-time.log
- BUILD_LOG_PIPE := > >($(TEE) -a $(BUILD_LOG)) 2> >($(TEE) -a $(BUILD_LOG) >&2)
+ BUILD_LOG_PIPE := > >($(TEE) -a $(BUILD_LOG)) 2> >($(TEE) -a $(BUILD_LOG) >&2) && wait
# Sanity check the spec file, so it matches this source code
define CheckSpecSanity
--- a/make/Jprt.gmk Thu Apr 28 00:38:21 2016 -0700
+++ b/make/Jprt.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -108,7 +108,9 @@
SRC_JRE_MACOSX_BUNDLE_DIR := $(JRE_MACOSX_BUNDLE_DIR)
# Bundle up the images
-bundles: all
+JPRT_TARGET ?= all
+ifeq ($(JPRT_TARGET), all)
+ bundles: $(JPRT_TARGET)
@$(call TargetEnter)
$(MKDIR) -p $(BUILD_OUTPUT)/bundles
$(CD) $(SRC_JDK_IMAGE_DIR) && $(ZIP) -y -q -r \
@@ -128,9 +130,24 @@
$(BUILD_OUTPUT)/bundles/$(SYMBOLS_IMAGE_SUBDIR).zip . ; \
fi
@$(call TargetExit)
+else
+ # Just fake the bundles
+ bundles: $(JPRT_TARGET)
+ @$(call TargetEnter)
+ $(MKDIR) -p $(BUILD_OUTPUT)/bundles
+ $(CD) $(TOPDIR) && $(ZIP) -y -q -r \
+ $(BUILD_OUTPUT)/bundles/$(JDK_IMAGE_SUBDIR).zip README
+ $(CD) $(TOPDIR) && $(ZIP) -y -q -r \
+ $(BUILD_OUTPUT)/bundles/$(JRE_IMAGE_SUBDIR).zip README
+ $(CD) $(TOPDIR) && $(ZIP) -y -q -r \
+ $(BUILD_OUTPUT)/bundles/$(TEST_IMAGE_SUBDIR).zip README
+ $(CD) $(TOPDIR) && $(ZIP) -y -q -r \
+ $(BUILD_OUTPUT)/bundles/modules.zip README
+ @$(call TargetExit)
+endif
# Copy images to one unified location regardless of platform etc.
-final-images: all
+final-images: $(JPRT_TARGET)
@$(call TargetEnter)
$(RM) -r $(BUILD_OUTPUT)/final-images
$(MKDIR) -p $(BUILD_OUTPUT)/final-images/$(JDK_IMAGE_SUBDIR)
--- a/make/Main.gmk Thu Apr 28 00:38:21 2016 -0700
+++ b/make/Main.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -229,10 +229,17 @@
ifeq ($(BUILD_HOTSPOT),true)
hotspot:
- +($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f HotspotWrapper.gmk)
+ ifeq ($(USE_NEW_HOTSPOT_BUILD), true)
+ +($(CD) $(HOTSPOT_TOPDIR)/makefiles && $(MAKE) $(MAKE_ARGS) -f BuildHotspot.gmk)
+ else
+ +($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f HotspotWrapper.gmk)
+ endif
endif
-ALL_TARGETS += hotspot
+hotspot-ide-project:
+ +($(CD) $(HOTSPOT_TOPDIR)/makefiles && $(MAKE) $(MAKE_ARGS) -f ide/CreateVSProject.gmk)
+
+ALL_TARGETS += hotspot hotspot-ide-project
################################################################################
# Build demos and samples targets
@@ -484,6 +491,8 @@
$(JAVA_TARGETS): interim-langtools
+ hotspot-ide-project: hotspot exploded-image
+
import-hotspot: hotspot
generate-exported-symbols: java.base-libs jdk.jdwp.agent-libs
--- a/make/common/MakeBase.gmk Thu Apr 28 00:38:21 2016 -0700
+++ b/make/common/MakeBase.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -706,10 +706,10 @@
ExecuteWithLog = \
$(call LogCmdlines, Exececuting: [$(strip $2)]) \
$(call WriteFile, $2, $(strip $1).cmdline) \
- ( $(strip $2) > >($(TEE) $(strip $1).log) 2> >($(TEE) $(strip $1).log >&2) || \
+ ( ( $(strip $2) > >($(TEE) $(strip $1).log) 2> >($(TEE) $(strip $1).log >&2) || \
( exitcode=$(DOLLAR)? && \
$(CP) $(strip $1).log $(MAKESUPPORT_OUTPUTDIR)/failure-logs/$(subst /,_,$(patsubst $(BUILD_OUTPUT)/%,%,$(strip $1))).log && \
- exit $(DOLLAR)exitcode ) )
+ exit $(DOLLAR)exitcode ) ) && wait )
################################################################################
# Find lib dir for module
@@ -732,6 +732,16 @@
"$(subst $(SPACE),$(PATH_SEP),$(strip $(subst $(DQUOTE),,$1)))"
################################################################################
+# Check if a specified hotspot variant is being built, or at least one of a
+# list of variants. Will return 'true' or 'false'.
+# $1 - the variant to test for
+check-jvm-variant = \
+ $(strip \
+ $(if $(filter-out $(VALID_JVM_VARIANTS), $1), \
+ $(error Internal error: Invalid variant tested: $1)) \
+ $(if $(filter $1, $(JVM_VARIANTS)), true, false))
+
+################################################################################
# Hook to include the corresponding custom file, if present.
$(eval $(call IncludeCustomExtension, , common/MakeBase.gmk))
--- a/make/common/NativeCompilation.gmk Thu Apr 28 00:38:21 2016 -0700
+++ b/make/common/NativeCompilation.gmk Thu Apr 28 23:08:17 2016 -0700
@@ -197,14 +197,51 @@
$1_$2_THIS_FILE = -DTHIS_FILE='"$$(<F)"'
endif
+ ifeq ($$($1_$(notdir $2)_OPTIMIZATION), )
+ $1_$(notdir $2)_OPT_CFLAGS := $$($1_OPT_CFLAGS)
+ $1_$(notdir $2)_OPT_CXXFLAGS := $$($1_OPT_CXXFLAGS)
+ else
+ ifeq (NONE, $$($1_$(notdir $2)_OPTIMIZATION))
+ $1_$(notdir $2)_OPT_CFLAGS := $(C_O_FLAG_NONE)
+ $1_$(notdir $2)_OPT_CXXFLAGS := $(CXX_O_FLAG_NONE)
+ else ifeq (LOW, $$($1_$(notdir $2)_OPTIMIZATION))
+ $1_$(notdir $2)_OPT_CFLAGS := $(C_O_FLAG_NORM)
+ $1_$(notdir $2)_OPT_CXXFLAGS := $(CXX_O_FLAG_NORM)
+ else ifeq (HIGH, $$($1_$(notdir $2)_OPTIMIZATION))
+ $1_$(notdir $2)_OPT_CFLAGS := $(C_O_FLAG_HI)
+ $1_$(notdir $2)_OPT_CXXFLAGS := $(CXX_O_FLAG_HI)
+ else ifeq (HIGHEST, $$($1_$(notdir $2)_OPTIMIZATION))
+ $1_$(notdir $2)_OPT_CFLAGS := $(C_O_FLAG_HIGHEST)
+ $1_$(notdir $2)_OPT_CXXFLAGS := $(CXX_O_FLAG_HIGHEST)
+ else ifeq (HIGHEST_JVM, $$($1_$(notdir $2)_OPTIMIZATION))
+ $1_$(notdir $2)_OPT_CFLAGS := $(C_O_FLAG_HIGHEST_JVM)
+ $1_$(notdir $2)_OPT_CXXFLAGS := $(CXX_O_FLAG_HIGHEST_JVM)
+ else ifeq (SIZE, $$($1_$(notdir $2)_OPTIMIZATION))
+ $1_$(notdir $2)_OPT_CFLAGS := $(C_O_FLAG_SIZE)
+ $1_$(notdir $2)_OPT_CXXFLAGS := $(CXX_O_FLAG_SIZE)
+ else
+ $$(error Unknown value for OPTIMIZATION: $$($1_$(notdir $2)_OPTIMIZATION))
+ endif
+ endif
+
+ ifneq ($$($1_PRECOMPILED_HEADER), )
+ ifeq ($$(filter $$(notdir $2), $$($1_PRECOMPILED_HEADER_EXCLUDE)), )
+ $1_$2_USE_PCH_FLAGS := $$($1_USE_PCH_FLAGS)
+ endif
+ endif
+
ifneq (,$$(filter %.c,$2))
# Compile as a C file
- $1_$2_FLAGS=$(CFLAGS_CCACHE) $4 $$($1_$(notdir $2)_CFLAGS) $$($1_$2_THIS_FILE) -c
+ $1_$2_FLAGS=$(CFLAGS_CCACHE) $$($1_$2_USE_PCH_FLAGS) $4 \
+ $$($1_$(notdir $2)_OPT_CFLAGS) \
+ $$($1_$(notdir $2)_CFLAGS) $$($1_$2_THIS_FILE) -c
$1_$2_COMP=$5
$1_$2_DEP_FLAG:=$(C_FLAG_DEPS)
else ifneq (,$$(filter %.m,$2))
# Compile as an Objective-C file
- $1_$2_FLAGS=-x objective-c $(CFLAGS_CCACHE) $4 $$($1_$(notdir $2)_CFLAGS) $$($1_$2_THIS_FILE) -c
+ $1_$2_FLAGS=-x objective-c $(CFLAGS_CCACHE) $$($1_$2_USE_PCH_FLAGS) $4 \
+ $$($1_$(notdir $2)_OPT_CFLAGS) \
+ $$($1_$(notdir $2)_CFLAGS) $$($1_$2_THIS_FILE) -c
$1_$2_COMP=$5
$1_$2_DEP_FLAG:=$(C_FLAG_DEPS)
else ifneq (,$$(filter %.s %.S,$2))
@@ -214,7 +251,9 @@
$1_$2_DEP_FLAG:=
else ifneq (,$$(filter %.cpp,$2)$$(filter %.cc,$2)$$(filter %.mm,$2))
# Compile as a C++ or Objective-C++ file
- $1_$2_FLAGS=$(CFLAGS_CCACHE) $6 $$($1_$(notdir $2)_CXXFLAGS) $$($1_$2_THIS_FILE) -c
+ $1_$2_FLAGS=$(CFLAGS_CCACHE) $$($1_$2_USE_PCH_FLAGS) $6 \
+ $$($1_$(notdir $2)_OPT_CXXFLAGS) \
+ $$($1_$(notdir $2)_CXXFLAGS) $$($1_$2_THIS_FILE) -c
$1_$2_COMP=$7
$1_$2_DEP_FLAG:=$(CXX_FLAG_DEPS)
else
@@ -245,8 +284,10 @@
endif
endif
- ifneq ($$($1_$(notdir $2)_CFLAGS)$$($1_$(notdir $2)_CXXFLAGS), )
- $1_$2_VARDEPS := $$($1_$(notdir $2)_CFLAGS) $$($1_$(notdir $2)_CXXFLAGS)
+ ifneq ($$(strip $$($1_$(notdir $2)_CFLAGS) $$($1_$(notdir $2)_CXXFLAGS) \
+ $$($1_$(notdir $2)_OPTIMIZATION)), )
+ $1_$2_VARDEPS := $$($1_$(notdir $2)_CFLAGS) $$($1_$(notdir $2)_CXXFLAGS) \
+ $$($1_$(notdir $2)_OPT_CFLAGS) $$($1_$(notdir $2)_OPT_CXXFLAGS)
$1_$2_VARDEPS_FILE := $$(call DependOnVariable, $1_$2_VARDEPS, \
$$(patsubst %$(OBJ_SUFFIX),%.vardeps,$$($1_$2_OBJ)))
endif
@@ -323,7 +364,7 @@
# mapfile for the output symbols file
# CC the compiler to use, default is $(CC)
# LD the linker to use, default is $(LD)
-# OPTIMIZATION sets optimization level to NONE, LOW, HIGH, HIGHEST
+# OPTIMIZATION sets optimization level to NONE, LOW, HIGH, HIGHEST, HIGHEST_JVM, SIZE
# DISABLED_WARNINGS_<toolchain> Disable the given warnings for the specified toolchain
# DISABLED_WARNINGS_C_<toolchain> Disable the given warnings for the specified toolchain
# when compiling C code
@@ -331,7 +372,11 @@
# toolchain when compiling C++ code
# STRIP_SYMBOLS Set to true to strip the final binary if the toolchain allows for it
# DEBUG_SYMBOLS Set to false to disable generation of debug symbols
+# CFLAGS_DEBUG_SYMBOLS Overrides the default cflags for enabling debug symbols
+# CXXFLAGS_DEBUG_SYMBOLS Overrides the default cxxflags for enabling debug symbols
# STRIPFLAGS Optionally change the flags given to the strip command
+# PRECOMPILED_HEADER Header file to use as precompiled header
+# PRECOMPILED_HEADER_EXCLUDE List of source files that should not use PCH
SetupNativeCompilation = $(NamedParamsMacroTemplate)
define SetupNativeCompilationBody
@@ -556,8 +601,10 @@
endif
ifeq ($(COMPILE_WITH_DEBUG_SYMBOLS), true)
- $1_EXTRA_CFLAGS += $(CFLAGS_DEBUG_SYMBOLS)
- $1_EXTRA_CXXFLAGS += $(CXXFLAGS_DEBUG_SYMBOLS)
+ $$(call SetIfEmpty, $1_CFLAGS_DEBUG_SYMBOLS, $(CFLAGS_DEBUG_SYMBOLS))
+ $$(call SetIfEmpty, $1_CXXFLAGS_DEBUG_SYMBOLS, $(CXXFLAGS_DEBUG_SYMBOLS))
+ $1_EXTRA_CFLAGS += $$($1_CFLAGS_DEBUG_SYMBOLS)
+ $1_EXTRA_CXXFLAGS += $$($1_CXXFLAGS_DEBUG_SYMBOLS)
endif
ifneq (,$$($1_REORDER))
@@ -597,17 +644,23 @@
endif
ifeq (NONE, $$($1_OPTIMIZATION))
- $1_EXTRA_CFLAGS += $(C_O_FLAG_NONE)
- $1_EXTRA_CXXFLAGS += $(CXX_O_FLAG_NONE)
+ $1_OPT_CFLAGS := $(C_O_FLAG_NONE)
+ $1_OPT_CXXFLAGS := $(CXX_O_FLAG_NONE)
else ifeq (LOW, $$($1_OPTIMIZATION))
- $1_EXTRA_CFLAGS += $(C_O_FLAG_NORM)
- $1_EXTRA_CXXFLAGS += $(CXX_O_FLAG_NORM)
+ $1_OPT_CFLAGS := $(C_O_FLAG_NORM)
+ $1_OPT_CXXFLAGS := $(CXX_O_FLAG_NORM)
else ifeq (HIGH, $$($1_OPTIMIZATION))
- $1_EXTRA_CFLAGS += $(C_O_FLAG_HI)
- $1_EXTRA_CXXFLAGS += $(CXX_O_FLAG_HI)
+ $1_OPT_CFLAGS := $(C_O_FLAG_HI)
+ $1_OPT_CXXFLAGS := $(CXX_O_FLAG_HI)
else ifeq (HIGHEST, $$($1_OPTIMIZATION))
- $1_EXTRA_CFLAGS += $(C_O_FLAG_HIGHEST)
- $1_EXTRA_CXXFLAGS += $(CXX_O_FLAG_HIGHEST)
+ $1_OPT_CFLAGS := $(C_O_FLAG_HIGHEST)
+ $1_OPT_CXXFLAGS := $(CXX_O_FLAG_HIGHEST)
+ else ifeq (HIGHEST_JVM, $$($1_OPTIMIZATION))
+ $1_OPT_CFLAGS := $(C_O_FLAG_HIGHEST_JVM)
+ $1_OPT_CXXFLAGS := $(CXX_O_FLAG_HIGHEST_JVM)
+ else ifeq (SIZE, $$($1_OPTIMIZATION))
+ $1_OPT_CFLAGS := $(C_O_FLAG_SIZE)
+ $1_OPT_CXXFLAGS := $(CXX_O_FLAG_SIZE)
else ifneq (, $$($1_OPTIMIZATION))
$$(error Unknown value for OPTIMIZATION: $$($1_OPTIMIZATION))
endif
@@ -618,11 +671,65 @@
# lines for all object files in this setup. This includes at least all the
# variables used in the call to add_native_source below.
$1_COMPILE_VARDEPS := $$($1_CFLAGS) $$($1_EXTRA_CFLAGS) $$($1_SYSROOT_CFLAGS) \
- $$($1_CXXFLAGS) $$($1_EXTRA_CXXFLAGS) \
+ $$($1_CXXFLAGS) $$($1_EXTRA_CXXFLAGS) $$($1_OPT_CFLAGS) $$($1_OPT_CXXFLAGS) \
$$($1_CC) $$($1_CXX) $$($1_AS) $$($1_ASFLAGS)
$1_COMPILE_VARDEPS_FILE := $$(call DependOnVariable, $1_COMPILE_VARDEPS, \
$$($1_OBJECT_DIR)/$$($1_NOSUFFIX).comp.vardeps)
+ ifneq ($$($1_PRECOMPILED_HEADER), )
+ ifeq ($(USE_PRECOMPILED_HEADER), 1)
+ ifeq ($(TOOLCHAIN_TYPE), microsoft)
+ $1_PCH_FILE := $$($1_OBJECT_DIR)/$1.pch
+ $1_GENERATED_PCH_SRC := $$($1_OBJECT_DIR)/$1_pch.cpp
+ $1_GENERATED_PCH_OBJ := $$($1_OBJECT_DIR)/$1_pch.obj
+
+ $$(eval $$(call add_native_source,$1,$$($1_GENERATED_PCH_SRC), \
+ $$($1_OBJECT_DIR),,, \
+ $$($1_CXXFLAGS) $$($1_EXTRA_CXXFLAGS) $$($1_SYSROOT_CFLAGS) \
+ -Fp$$($1_PCH_FILE) -Yc$$(notdir $$($1_PRECOMPILED_HEADER)), \
+ $$($1_CXX),,no_this_file))
+
+ $1_USE_PCH_FLAGS := \
+ -Fp$$($1_PCH_FILE) -Yu$$(notdir $$($1_PRECOMPILED_HEADER))
+
+ $$($1_ALL_OBJS): $$($1_GENERATED_PCH_OBJ)
+
+ # Explicitly add the pch obj file first to ease comparing to old
+ # hotspot build.
+ $1_ALL_OBJS := $$($1_GENERATED_PCH_OBJ) $$($1_ALL_OBJS)
+
+ $$($1_GENERATED_PCH_SRC):
+ $(ECHO) "#include \"$$(notdir $$($1_PRECOMPILED_HEADER))\"" > $$@
+
+ else ifneq ($(findstring $(TOOLCHAIN_TYPE), gcc clang), )
+ ifeq ($(TOOLCHAIN_TYPE), gcc)
+ $1_PCH_FILE := $$($1_OBJECT_DIR)/precompiled/$$(notdir $$($1_PRECOMPILED_HEADER)).gch
+ $1_USE_PCH_FLAGS := -I$$($1_OBJECT_DIR)/precompiled
+ else ifeq ($(TOOLCHAIN_TYPE), clang)
+ $1_PCH_FILE := $$($1_OBJECT_DIR)/precompiled/$$(notdir $$($1_PRECOMPILED_HEADER)).pch
+ $1_USE_PCH_FLAGS := -include-pch $$($1_PCH_FILE)
+ endif
+ $1_PCH_DEP := $$($1_PCH_FILE).d
+ $1_PCH_DEP_TARGETS := $$($1_PCH_FILE).d.targets
+
+ -include $$($1_PCH_DEP)
+ -include $$($1_PCH_DEP_TARGETS)
+
+ $$($1_PCH_FILE): $$($1_PRECOMPILED_HEADER) $$($1_COMPILE_VARDEPS_FILE)
+ $$(call LogInfo, Generating precompiled header)
+ $$(call MakeDir, $$(@D))
+ $$(call ExecuteWithLog, $$@, \
+ $$($1_CC) $$($1_CFLAGS) $$($1_EXTRA_CFLAGS) $$($1_SYSROOT_CFLAGS) \
+ $$($1_OPT_CFLAGS) \
+ -x c++-header -c $(C_FLAG_DEPS) $$($1_PCH_DEP) $$< -o $$@)
+ $(SED) $(DEPENDENCY_TARGET_SED_PATTERN) $$($1_PCH_DEP) > $$($1_PCH_DEP_TARGETS)
+
+ $$($1_ALL_OBJS): $$($1_PCH_FILE)
+
+ endif
+ endif
+ endif
+
# Now call add_native_source for each source file we are going to compile.
$$(foreach p,$$($1_SRCS), \
$$(eval $$(call add_native_source,$1,$$p,$$($1_OBJECT_DIR), \
--- a/make/jprt.properties Thu Apr 28 00:38:21 2016 -0700
+++ b/make/jprt.properties Thu Apr 28 23:08:17 2016 -0700
@@ -129,9 +129,15 @@
jprt.build.flavor.optimizedOpen.target=jprt_bundle
jprt.build.flavor.slowdebug.target=jprt_bundle
-# Use these configure args to define debug level
+# Use these configure args to define debug level or provide specific
+# configuration details not covered by Jib profiles.
jprt.slowdebug.build.configure.args=
jprt.fastdebug.build.configure.args=--disable-precompiled-headers
+# Don't disable precompiled headers on windows. It's simply too slow.
+jprt.windows_i586.fastdebug.build.configure.args=
+jprt.windows_x64.fastdebug.build.configure.args=
+jprt.windows_i586.fastdebugOpen.build.configure.args=
+jprt.windows_x64.fastdebugOpen.build.configure.args=
jprt.product.build.configure.args=
jprt.optimized.build.configure.args=--with-debug-level=optimized
jprt.slowdebugOpen.build.configure.args=${jprt.slowdebug.build.configure.args}
--- a/nashorn/.hgtags Thu Apr 28 00:38:21 2016 -0700
+++ b/nashorn/.hgtags Thu Apr 28 23:08:17 2016 -0700
@@ -348,3 +348,4 @@
c261f8440c5578b34596e6b0419a81aec431a884 jdk-9+112
a5d1990fd32d908da8154d79116fce8013ba4d40 jdk-9+113
ba21793a0e4816283cc0ecdab5142a4959363529 jdk-9+114
+295ac208a4443d433214d0c1f32d2ea45a3a32d2 jdk-9+115
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jtreg-ext/requires/VMProps.java Thu Apr 28 23:08:17 2016 -0700
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package requires;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * The Class to be invoked by jtreg prior Test Suite execution to
+ * collect information about VM.
+ * Properties set by this Class will be available in the @requires expressions.
+ */
+public class VMProps implements Callable<Map<String, String>> {
+
+ /**
+ * Collects information about VM properties.
+ * This method will be invoked by jtreg.
+ *
+ * @return Map of property-value pairs.
+ */
+ @Override
+ public Map<String, String> call() {
+ Map<String, String> map = new HashMap<>();
+ map.put("vm.flavor", vmFlavor());
+ map.put("vm.compMode", vmCompMode());
+ map.put("vm.bits", vmBits());
+ dump(map);
+ return map;
+ }
+
+ /**
+ * @return VM type value extracted from the "java.vm.name" property.
+ */
+ protected String vmFlavor() {
+ // E.g. "Java HotSpot(TM) 64-Bit Server VM"
+ String vmName = System.getProperty("java.vm.name");
+ if (vmName == null) {
+ return null;
+ }
+
+ Pattern startP = Pattern.compile(".* (\\S+) VM");
+ Matcher m = startP.matcher(vmName);
+ if (m.matches()) {
+ return m.group(1).toLowerCase();
+ }
+ return null;
+ }
+
+ /**
+ * @return VM compilation mode extracted from the "java.vm.info" property.
+ */
+ protected String vmCompMode() {
+ // E.g. "mixed mode"
+ String vmInfo = System.getProperty("java.vm.info");
+ if (vmInfo == null) {
+ return null;
+ }
+ int k = vmInfo.toLowerCase().indexOf(" mode");
+ if (k < 0) {
+ return null;
+ }
+ vmInfo = vmInfo.substring(0, k);
+ switch (vmInfo) {
+ case "mixed" : return "Xmixed";
+ case "compiled" : return "Xcomp";
+ case "interpreted" : return "Xint";
+ default: return null;
+ }
+ }
+
+ /**
+ * @return VM bitness, the value of the "sun.arch.data.model" property.
+ */
+ protected String vmBits() {
+ return System.getProperty("sun.arch.data.model");
+ }
+
+ /**
+ * Dumps the map to the file if the file name is given as the property.
+ * This functionality could be helpful to know context in the real
+ * execution.
+ *
+ * @param map
+ */
+ protected void dump(Map<String, String> map) {
+ String dumpFileName = System.getProperty("vmprops.dump");
+ if (dumpFileName == null) {
+ return;
+ }
+ List<String> lines = new ArrayList<>();
+ map.forEach((k,v) -> lines.add(k + ":" + v));
+ try {
+ Files.write(Paths.get(dumpFileName), lines);
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to dump properties into '"
+ + dumpFileName + "'", e);
+ }
+ }
+
+ /**
+ * This method is for the testing purpose only.
+ * @param args
+ */
+ public static void main(String args[]) {
+ Map<String, String> map = new VMProps().call();
+ map.forEach((k,v) -> System.out.println(k + ": '" + v + "'"));
+ }
+}