diff --git a/.hgtags b/.hgtags
index f59b4028db2..a3f78b33edc 100644
--- a/.hgtags
+++ b/.hgtags
@@ -228,3 +228,5 @@ bbe43d712fe08e650808d774861b256ccb34e500 jdk8-b102
b5ed503c26ad38869c247c5e32debec217fd056b jdk8-b104
589f4fdc584e373a47cde0162e9eceec9165c381 jdk8-b105
514b0b69fb9683ef52062fd962a3e0644431f64d jdk8-b106
+892889f445755790ae90e61775bfb59ddc6182b5 jdk8-b107
+74049f7a28b48c14910106a75d9f2504169c352e jdk8-b108
diff --git a/.hgtags-top-repo b/.hgtags-top-repo
index ca1497b3968..fbcdb0977c0 100644
--- a/.hgtags-top-repo
+++ b/.hgtags-top-repo
@@ -228,3 +228,5 @@ b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103
96c1b9b7524b52c3fcefc90ffad4c767396727c8 jdk8-b104
5166118c59178b5d31001bc4058e92486ee07d9b jdk8-b105
8e7b4d9fb00fdf1334376aeac050c9bca6d1b383 jdk8-b106
+0874bb4707b723d5bb108d379c557cf41529d1a7 jdk8-b107
+9286a6e61291246d88af713f1ef79adeea30fe2e jdk8-b108
diff --git a/Makefile b/Makefile
index f7b9d1b35e3..2ef4bb99853 100644
--- a/Makefile
+++ b/Makefile
@@ -404,7 +404,6 @@ COMPILER_PATH.desc = Compiler install directory
CACERTS_FILE.desc = Location of certificates file
DEVTOOLS_PATH.desc = Directory containing zip and gnumake
CUPS_HEADERS_PATH.desc = Include directory location for CUPS header files
-DXSDK_PATH.desc = Root directory of DirectX SDK
# Make variables to print out (description and value)
VARIABLE_PRINTVAL_LIST += \
@@ -429,17 +428,6 @@ VARIABLE_CHECKDIR_LIST += \
VARIABLE_CHECKFIL_LIST += \
CACERTS_FILE
-# Some are windows specific
-ifeq ($(PLATFORM), windows)
-
-VARIABLE_PRINTVAL_LIST += \
- DXSDK_PATH
-
-VARIABLE_CHECKDIR_LIST += \
- DXSDK_PATH
-
-endif
-
# For pattern rules below, so all are treated the same
DO_PRINTVAL_LIST=$(VARIABLE_PRINTVAL_LIST:%=%.printval)
DO_CHECKDIR_LIST=$(VARIABLE_CHECKDIR_LIST:%=%.checkdir)
diff --git a/README-builds.html b/README-builds.html
index 71c05c0fbf4..14796a27e87 100644
--- a/README-builds.html
+++ b/README-builds.html
@@ -444,10 +444,6 @@
Install
Visual Studio 2010
-
--with-freetype= path |
diff --git a/common/autoconf/basics.m4 b/common/autoconf/basics.m4
index 126993b5cd7..f3911ff9bd9 100644
--- a/common/autoconf/basics.m4
+++ b/common/autoconf/basics.m4
@@ -203,6 +203,15 @@ AC_DEFUN([BASIC_REMOVE_SYMBOLIC_LINKS],
fi
])
+# Register a --with argument but mark it as deprecated
+# $1: The name of the with argument to deprecate, not including --with-
+AC_DEFUN([BASIC_DEPRECATED_ARG_WITH],
+[
+ AC_ARG_WITH($1, [AS_HELP_STRING([--with-$1],
+ [Deprecated. Option is kept for backwards compatibility and is ignored])],
+ [AC_MSG_WARN([Option --with-$1 is deprecated and will be ignored.])])
+])
+
AC_DEFUN_ONCE([BASIC_INIT],
[
# Save the original command line. This is passed to us by the wrapper configure script.
diff --git a/common/autoconf/basics_windows.m4 b/common/autoconf/basics_windows.m4
index 9ddb9e8c5c0..0a26d830239 100644
--- a/common/autoconf/basics_windows.m4
+++ b/common/autoconf/basics_windows.m4
@@ -211,7 +211,7 @@ AC_DEFUN([BASIC_FIXUP_EXECUTABLE_CYGWIN],
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
diff --git a/common/autoconf/build-aux/autoconf-config.guess b/common/autoconf/build-aux/autoconf-config.guess
index 3aa7f690629..15ee4389269 100644
--- a/common/autoconf/build-aux/autoconf-config.guess
+++ b/common/autoconf/build-aux/autoconf-config.guess
@@ -26,10 +26,10 @@
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
-# Free Software Foundation, Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+# 2011, 2012 Free Software Foundation, Inc.
-timestamp='2008-01-23'
+timestamp='2012-02-10'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -42,9 +42,7 @@ timestamp='2008-01-23'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see .
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -52,16 +50,16 @@ timestamp='2008-01-23'
# the same distribution terms that you use for the rest of that program.
-# Originally written by Per Bothner .
-# Please send patches to . Submit a context
-# diff and a properly formatted ChangeLog entry.
+# Originally written by Per Bothner. Please send patches (context
+# diff format) to and include a ChangeLog
+# entry.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
# exits with 0. Otherwise, it exits with 1.
#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit build system type.
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
me=`echo "$0" | sed -e 's,.*/,,'`
@@ -81,8 +79,9 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -169,7 +168,7 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
- # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
@@ -195,7 +194,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep __ELF__ >/dev/null
+ | grep -q __ELF__
then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX?
@@ -205,7 +204,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
fi
;;
*)
- os=netbsd
+ os=netbsd
;;
esac
# The OS release
@@ -248,7 +247,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
@@ -294,7 +293,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- exit ;;
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
@@ -320,7 +322,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo s390-ibm-zvmoe
exit ;;
*:OS400:*:*)
- echo powerpc-ibm-os400
+ echo powerpc-ibm-os400
exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
@@ -349,14 +351,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
@@ -400,23 +421,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
+ exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit ;;
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit ;;
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit ;;
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
m68k:machten:*:*)
echo m68k-apple-machten${UNAME_RELEASE}
exit ;;
@@ -486,8 +507,8 @@ EOF
echo m88k-motorola-sysv3
exit ;;
AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
@@ -500,7 +521,7 @@ EOF
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
- exit ;;
+ exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit ;;
@@ -557,7 +578,7 @@ EOF
echo rs6000-ibm-aix3.2
fi
exit ;;
- *:AIX:*:[456])
+ *:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
@@ -600,52 +621,52 @@ EOF
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- 532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
- esac ;;
- esac
+ esac ;;
+ esac
fi
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ sed 's/^ //' << EOF >$dummy.c
- #define _HPUX_SOURCE
- #include
- #include
+ #define _HPUX_SOURCE
+ #include
+ #include
- int main ()
- {
- #if defined(_SC_KERNEL_BITS)
- long bits = sysconf(_SC_KERNEL_BITS);
- #endif
- long cpu = sysconf (_SC_CPU_VERSION);
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- case CPU_PA_RISC2_0:
- #if defined(_SC_KERNEL_BITS)
- switch (bits)
- {
- case 64: puts ("hppa2.0w"); break;
- case 32: puts ("hppa2.0n"); break;
- default: puts ("hppa2.0"); break;
- } break;
- #else /* !defined(_SC_KERNEL_BITS) */
- puts ("hppa2.0"); break;
- #endif
- default: puts ("hppa1.0"); break;
- }
- exit (0);
- }
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
EOF
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
@@ -665,7 +686,7 @@ EOF
# => hppa64-hp-hpux11.23
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
- grep __LP64__ >/dev/null
+ grep -q __LP64__
then
HP_ARCH="hppa2.0w"
else
@@ -736,22 +757,22 @@ EOF
exit ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
- exit ;;
+ exit ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
- exit ;;
+ exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
- exit ;;
+ exit ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
- exit ;;
+ exit ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
- exit ;;
+ exit ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
@@ -775,14 +796,14 @@ EOF
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
@@ -794,13 +815,12 @@ EOF
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
- case ${UNAME_MACHINE} in
- pc98)
- echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
amd64)
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
*)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
esac
exit ;;
i*:CYGWIN*:*)
@@ -809,19 +829,22 @@ EOF
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
+ i*:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
exit ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
- *:Interix*:[3456]*)
- case ${UNAME_MACHINE} in
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
x86)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
- EM64T | authenticamd)
+ authenticamd | genuineintel | EM64T)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
IA64)
@@ -831,6 +854,9 @@ EOF
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
@@ -860,92 +886,13 @@ EOF
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
- arm*:Linux:*:*)
- eval $set_cc_for_build
- if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ARM_EABI__
- then
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- else
- echo ${UNAME_MACHINE}-unknown-linux-gnueabi
- fi
- exit ;;
- avr32*:Linux:*:*)
+ aarch64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
- cris:Linux:*:*)
- echo cris-axis-linux-gnu
- exit ;;
- crisv32:Linux:*:*)
- echo crisv32-axis-linux-gnu
- exit ;;
- frv:Linux:*:*)
- echo frv-unknown-linux-gnu
- exit ;;
- ia64:Linux:*:*)
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
- m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- mips:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips
- #undef mipsel
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mipsel
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips
- #else
- CPU=
- #endif
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips64
- #undef mips64el
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mips64el
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips64
- #else
- CPU=
- #endif
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- or32:Linux:*:*)
- echo or32-unknown-linux-gnu
- exit ;;
- ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
- exit ;;
- ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
- exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;;
@@ -955,11 +902,90 @@ EOF
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
- esac
- objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ cris:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-gnu
+ exit ;;
+ crisv32:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-gnu
+ exit ;;
+ frv:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ i*86:Linux:*:*)
+ LIBC=gnu
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+ echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ ;;
+ or32:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-gnu
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
@@ -968,14 +994,17 @@ EOF
*) echo hppa-unknown-linux-gnu ;;
esac
exit ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
exit ;;
sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
@@ -983,78 +1012,18 @@ EOF
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
vax:Linux:*:*)
echo ${UNAME_MACHINE}-dec-linux-gnu
exit ;;
x86_64:Linux:*:*)
- echo x86_64-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
xtensa*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
- i*86:Linux:*:*)
- # The BFD linker knows what the default object file format is, so
- # first see if it will tell us. cd to the root directory to prevent
- # problems with other programs or directories called `ld' in the path.
- # Set LC_ALL=C to ensure ld outputs messages in English.
- ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
- | sed -ne '/supported targets:/!d
- s/[ ][ ]*/ /g
- s/.*supported targets: *//
- s/ .*//
- p'`
- case "$ld_supported_targets" in
- elf32-i386)
- TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
- ;;
- a.out-i386-linux)
- echo "${UNAME_MACHINE}-pc-linux-gnuaout"
- exit ;;
- coff-i386)
- echo "${UNAME_MACHINE}-pc-linux-gnucoff"
- exit ;;
- "")
- # Either a pre-BFD a.out linker (linux-gnuoldld) or
- # one that does not give us useful --help.
- echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
- exit ;;
- esac
- # Determine whether the default compiler is a.out or elf
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include
- #ifdef __ELF__
- # ifdef __GLIBC__
- # if __GLIBC__ >= 2
- LIBC=gnu
- # else
- LIBC=gnulibc1
- # endif
- # else
- LIBC=gnulibc1
- # endif
- #else
- #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
- LIBC=gnu
- #else
- LIBC=gnuaout
- #endif
- #endif
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^LIBC/{
- s: ::g
- p
- }'`"
- test x"${LIBC}" != x && {
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
- exit
- }
- test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
- ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
@@ -1062,11 +1031,11 @@ EOF
echo i386-sequent-sysv4
exit ;;
i*86:UNIX_SV:4.2MP:2.*)
- # Unixware is an offshoot of SVR4, but it has its own version
- # number series starting with 2...
- # I am not positive that other SVR4 systems won't match this,
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
+ # Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit ;;
i*86:OS/2:*:*)
@@ -1083,7 +1052,7 @@ EOF
i*86:syllable:*:*)
echo ${UNAME_MACHINE}-pc-syllable
exit ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit ;;
i*86:*DOS:*:*)
@@ -1098,7 +1067,7 @@ EOF
fi
exit ;;
i*86:*:5:[678]*)
- # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
@@ -1126,10 +1095,13 @@ EOF
exit ;;
pc:*:*:*)
# Left here for compatibility:
- # uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i386.
- echo i386-pc-msdosdjgpp
- exit ;;
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit ;;
@@ -1164,8 +1136,18 @@ EOF
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4; exit; } ;;
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit ;;
@@ -1178,7 +1160,7 @@ EOF
rs6000:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
echo powerpc-unknown-lynxos${UNAME_RELEASE}
exit ;;
SM[BE]S:UNIX_SV:*:*)
@@ -1198,10 +1180,10 @@ EOF
echo ns32k-sni-sysv
fi
exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- # says
- echo i586-unisys-sysv4
- exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says
+ echo i586-unisys-sysv4
+ exit ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes .
# How about differentiating between stratus architectures? -djm
@@ -1227,11 +1209,11 @@ EOF
exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
+ echo mips-nec-sysv${UNAME_RELEASE}
else
- echo mips-unknown-sysv${UNAME_RELEASE}
+ echo mips-unknown-sysv${UNAME_RELEASE}
fi
- exit ;;
+ exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit ;;
@@ -1241,6 +1223,9 @@ EOF
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
@@ -1267,12 +1252,17 @@ EOF
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- eval $set_cc_for_build
- echo "int main(){}" > $dummy.c
- if test "`$CC_FOR_BUILD -o $dummy $dummy.c; file $dummy | grep -c x86_64`" = 1 ; then
- UNAME_PROCESSOR=x86_64
- fi
case $UNAME_PROCESSOR in
+ i386)
+ eval $set_cc_for_build
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ UNAME_PROCESSOR="x86_64"
+ fi
+ fi ;;
unknown) UNAME_PROCESSOR=powerpc ;;
esac
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
@@ -1288,6 +1278,9 @@ EOF
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
NSE-?:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
@@ -1333,13 +1326,13 @@ EOF
echo pdp10-unknown-its
exit ;;
SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
+ echo mips-sei-seiux${UNAME_RELEASE}
exit ;;
*:DragonFly:*:*)
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
*:*VMS:*:*)
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
case "${UNAME_MACHINE}" in
A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;;
@@ -1354,6 +1347,12 @@ EOF
i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos
exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
@@ -1376,11 +1375,11 @@ main ()
#include
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
- "4"
+ "4"
#else
- ""
+ ""
#endif
- ); exit (0);
+ ); exit (0);
#endif
#endif
diff --git a/common/autoconf/configure b/common/autoconf/configure
index 8e4560df114..7378efe379d 100644
--- a/common/autoconf/configure
+++ b/common/autoconf/configure
@@ -219,9 +219,4 @@ else
echo configure exiting with result code $conf_result_code
fi
-# Move the log file to the output root, if this was successfully created
-if test -d "$OUTPUT_ROOT"; then
- mv -f config.log "$OUTPUT_ROOT" 2> /dev/null
-fi
-
exit $conf_result_code
diff --git a/common/autoconf/configure.ac b/common/autoconf/configure.ac
index 274f278fb3d..ad8bd97cea3 100644
--- a/common/autoconf/configure.ac
+++ b/common/autoconf/configure.ac
@@ -232,9 +232,15 @@ CUSTOM_LATE_HOOK
# 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="$OUTPUT_ROOT/config.status"
+
# Create the actual output files. Now the main work of configure is done.
AC_OUTPUT
+# Try to move the config.log file to the output directory.
+if test -e ./config.log; then
+ $MV -f ./config.log "$OUTPUT_ROOT/config.log" 2> /dev/null
+fi
+
# Make the compare script executable
$CHMOD +x $OUTPUT_ROOT/compare.sh
diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh
index 7679cc5c4df..7a65a92ecc4 100644
--- a/common/autoconf/generated-configure.sh
+++ b/common/autoconf/generated-configure.sh
@@ -709,7 +709,6 @@ STATIC_LIBRARY
SHARED_LIBRARY
OBJ_SUFFIX
COMPILER_NAME
-TARGET_BITS_FLAG
JT_HOME
JTREGEXE
LIPO
@@ -766,8 +765,6 @@ BUILD_LD
BUILD_CXX
BUILD_CC
MSVCR_DLL
-DXSDK_INCLUDE_PATH
-DXSDK_LIB_PATH
VS_PATH
VS_LIB
VS_INCLUDE
@@ -1031,6 +1028,7 @@ with_override_corba
with_override_jaxp
with_override_jaxws
with_override_hotspot
+with_override_nashorn
with_override_jdk
with_import_hotspot
with_msvcr_dll
@@ -1784,17 +1782,19 @@ Optional Packages:
--with-override-jaxp use this jaxp dir for the build
--with-override-jaxws use this jaxws dir for the build
--with-override-hotspot use this hotspot dir for the build
+ --with-override-nashorn use this nashorn dir for the build
--with-override-jdk use this jdk dir for the build
--with-import-hotspot import hotspot binaries from this jdk image or
hotspot build dist dir instead of building from
source
--with-msvcr-dll copy this msvcr100.dll into the built JDK (Windows
only) [probed]
- --with-dxsdk the DirectX SDK (Windows only) [probed]
- --with-dxsdk-lib the DirectX SDK lib directory (Windows only)
- [probed]
- --with-dxsdk-include the DirectX SDK include directory (Windows only)
- [probed]
+ --with-dxsdk Deprecated. Option is kept for backwards
+ compatibility and is ignored
+ --with-dxsdk-lib Deprecated. Option is kept for backwards
+ compatibility and is ignored
+ --with-dxsdk-include Deprecated. Option is kept for backwards
+ compatibility and is ignored
--with-jtreg Regression Test Harness [probed]
--with-extra-cflags extra flags to be used when compiling jdk c-files
--with-extra-cxxflags extra flags to be used when compiling jdk c++-files
@@ -3144,6 +3144,10 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+# Register a --with argument but mark it as deprecated
+# $1: The name of the with argument to deprecate, not including --with-
+
+
# Test that variable $1 denoting a program is not empty. If empty, exit with an error.
@@ -3805,10 +3809,6 @@ fi
-# Setup the DXSDK paths
-
-
-
@@ -3818,7 +3818,7 @@ fi
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1378914658
+DATE_WHEN_GENERATED=1379504921
###############################################################################
#
@@ -8352,7 +8352,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -8709,7 +8709,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -9063,7 +9063,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -9422,7 +9422,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -9775,7 +9775,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -11075,7 +11075,7 @@ elif test "x$with_user_release_suffix" != x; then
else
BUILD_DATE=`date '+%Y_%m_%d_%H_%M'`
# Avoid [:alnum:] since it depends on the locale.
- CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyz0123456789'`
+ CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'`
USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
fi
@@ -16102,6 +16102,10 @@ if test "x$with_add_source_root" != x; then
test -f $with_add_source_root/hotspot/make/Makefile; then
as_fn_error $? "Your add source root seems to contain a full hotspot repo! An add source root should only contain additional sources." "$LINENO" 5
fi
+ if test -f $with_add_source_root/nashorn/makefiles/Makefile || \
+ test -f $with_add_source_root/nashorn/make/Makefile; then
+ as_fn_error $? "Your add source root seems to contain a full nashorn repo! An add source root should only contain additional sources." "$LINENO" 5
+ fi
if test -f $with_add_source_root/jdk/makefiles/Makefile || \
test -f $with_add_source_root/jdk/make/Makefile; then
as_fn_error $? "Your add source root seems to contain a full JDK repo! An add source root should only contain additional sources." "$LINENO" 5
@@ -16137,6 +16141,10 @@ if test "x$with_override_source_root" != x; then
test -f $with_override_source_root/hotspot/make/Makefile; then
as_fn_error $? "Your override source root seems to contain a full hotspot repo! An override source root should only contain sources that override." "$LINENO" 5
fi
+ if test -f $with_override_source_root/nashorn/makefiles/Makefile || \
+ test -f $with_override_source_root/nashorn/make/Makefile; then
+ as_fn_error $? "Your override source root seems to contain a full nashorn repo! An override source root should only contain sources that override." "$LINENO" 5
+ fi
if test -f $with_override_source_root/jdk/makefiles/Makefile || \
test -f $with_override_source_root/jdk/make/Makefile; then
as_fn_error $? "Your override source root seems to contain a full JDK repo! An override source root should only contain sources that override." "$LINENO" 5
@@ -16199,6 +16207,13 @@ fi
+# Check whether --with-override-nashorn was given.
+if test "${with_override_nashorn+set}" = set; then :
+ withval=$with_override_nashorn;
+fi
+
+
+
# Check whether --with-override-jdk was given.
if test "${with_override_jdk+set}" = set; then :
withval=$with_override_jdk;
@@ -16276,7 +16291,7 @@ if test "x$with_override_nashorn" != x; then
cd "$with_override_nashorn"
NASHORN_TOPDIR="`pwd`"
cd "$CURDIR"
- if ! test -f $NASHORN_TOPDIR/makefiles/BuildNashorn.gmk; then
+ if ! test -f $NASHORN_TOPDIR/makefiles/Makefile; then
as_fn_error $? "You have to override nashorn with a full nashorn repo!" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if nashorn should be overridden" >&5
@@ -17086,7 +17101,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -17586,437 +17601,29 @@ $as_echo "$as_me: The path of MSVCR_DLL, which resolves as \"$path\", is invalid
# Check whether --with-dxsdk was given.
if test "${with_dxsdk+set}" = set; then :
- withval=$with_dxsdk;
+ withval=$with_dxsdk; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-dxsdk is deprecated and will be ignored." >&5
+$as_echo "$as_me: WARNING: Option --with-dxsdk is deprecated and will be ignored." >&2;}
fi
+
+
# Check whether --with-dxsdk-lib was given.
if test "${with_dxsdk_lib+set}" = set; then :
- withval=$with_dxsdk_lib;
+ withval=$with_dxsdk_lib; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-dxsdk-lib is deprecated and will be ignored." >&5
+$as_echo "$as_me: WARNING: Option --with-dxsdk-lib is deprecated and will be ignored." >&2;}
fi
+
+
# Check whether --with-dxsdk-include was given.
if test "${with_dxsdk_include+set}" = set; then :
- withval=$with_dxsdk_include;
+ withval=$with_dxsdk_include; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-dxsdk-include is deprecated and will be ignored." >&5
+$as_echo "$as_me: WARNING: Option --with-dxsdk-include is deprecated and will be ignored." >&2;}
fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DirectX SDK" >&5
-$as_echo_n "checking for DirectX SDK... " >&6; }
-
- if test "x$with_dxsdk" != x; then
- dxsdk_path="$with_dxsdk"
- elif test "x$DXSDK_DIR" != x; then
- dxsdk_path="$DXSDK_DIR"
- elif test -d "C:/DXSDK"; then
- dxsdk_path="C:/DXSDK"
- else
- as_fn_error $? "Could not find the DirectX SDK" "$LINENO" 5
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dxsdk_path" >&5
-$as_echo "$dxsdk_path" >&6; }
-
- if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
-
- # Input might be given as Windows format, start by converting to
- # unix format.
- path="$dxsdk_path"
- new_path=`$CYGPATH -u "$path"`
-
- # Cygwin tries to hide some aspects of the Windows file system, such that binaries are
- # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered
- # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
- # "foo.exe" is OK but "foo" is an error.
- #
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
- # It is also a way to make sure we got the proper file name for the real test later on.
- test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
- if test "x$test_shortpath" = x; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&5
-$as_echo "$as_me: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&6;}
- as_fn_error $? "Cannot locate the the path of dxsdk_path" "$LINENO" 5
- fi
-
- # Call helper function which possibly converts this using DOS-style short mode.
- # If so, the updated path is stored in $new_path.
-
- input_path="$new_path"
- # Check if we need to convert this using DOS-style short mode. If the path
- # contains just simple characters, use it. Otherwise (spaces, weird characters),
- # take no chances and rewrite it.
- # Note: m4 eats our [], so we need to use [ and ] instead.
- has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]`
- if test "x$has_forbidden_chars" != x; then
- # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
- shortmode_path=`$CYGPATH -s -m -a "$input_path"`
- path_after_shortmode=`$CYGPATH -u "$shortmode_path"`
- if test "x$path_after_shortmode" != "x$input_to_shortpath"; then
- # Going to short mode and back again did indeed matter. Since short mode is
- # case insensitive, let's make it lowercase to improve readability.
- shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- # Now convert it back to Unix-stile (cygpath)
- input_path=`$CYGPATH -u "$shortmode_path"`
- new_path="$input_path"
- fi
- fi
-
- test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/`
- if test "x$test_cygdrive_prefix" = x; then
- # As a simple fix, exclude /usr/bin since it's not a real path.
- if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then
- # The path is in a Cygwin special directory (e.g. /home). We need this converted to
- # a path prefixed by /cygdrive for fixpath to work.
- new_path="$CYGWIN_ROOT_PATH$input_path"
- fi
- fi
-
-
- if test "x$path" != "x$new_path"; then
- dxsdk_path="$new_path"
- { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting dxsdk_path to \"$new_path\"" >&5
-$as_echo "$as_me: Rewriting dxsdk_path to \"$new_path\"" >&6;}
- fi
-
- elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
-
- path="$dxsdk_path"
- has_colon=`$ECHO $path | $GREP ^.:`
- new_path="$path"
- if test "x$has_colon" = x; then
- # Not in mixed or Windows style, start by that.
- new_path=`cmd //c echo $path`
- fi
-
-
- input_path="$new_path"
- # Check if we need to convert this using DOS-style short mode. If the path
- # contains just simple characters, use it. Otherwise (spaces, weird characters),
- # take no chances and rewrite it.
- # Note: m4 eats our [], so we need to use [ and ] instead.
- has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]`
- if test "x$has_forbidden_chars" != x; then
- # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
- new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- fi
-
-
- windows_path="$new_path"
- if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
- unix_path=`$CYGPATH -u "$windows_path"`
- new_path="$unix_path"
- elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
- unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
- new_path="$unix_path"
- fi
-
- if test "x$path" != "x$new_path"; then
- dxsdk_path="$new_path"
- { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting dxsdk_path to \"$new_path\"" >&5
-$as_echo "$as_me: Rewriting dxsdk_path to \"$new_path\"" >&6;}
- fi
-
- # Save the first 10 bytes of this path to the storage, so fixpath can work.
- all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}")
-
- else
- # We're on a posix platform. Hooray! :)
- path="$dxsdk_path"
- has_space=`$ECHO "$path" | $GREP " "`
- if test "x$has_space" != x; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&5
-$as_echo "$as_me: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&6;}
- as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
- fi
-
- # Use eval to expand a potential ~
- eval path="$path"
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of dxsdk_path, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
- dxsdk_path="`cd "$path"; $THEPWDCMD -L`"
- fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DirectX SDK lib dir" >&5
-$as_echo_n "checking for DirectX SDK lib dir... " >&6; }
- if test "x$with_dxsdk_lib" != x; then
- DXSDK_LIB_PATH="$with_dxsdk_lib"
- elif test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then
- DXSDK_LIB_PATH="$dxsdk_path/Lib/x64"
- else
- DXSDK_LIB_PATH="$dxsdk_path/Lib"
- fi
- # dsound.lib is linked to in jsoundds
- if test ! -f "$DXSDK_LIB_PATH/dsound.lib"; then
- as_fn_error $? "Invalid DirectX SDK lib dir" "$LINENO" 5
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DXSDK_LIB_PATH" >&5
-$as_echo "$DXSDK_LIB_PATH" >&6; }
-
- if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
-
- # Input might be given as Windows format, start by converting to
- # unix format.
- path="$DXSDK_LIB_PATH"
- new_path=`$CYGPATH -u "$path"`
-
- # Cygwin tries to hide some aspects of the Windows file system, such that binaries are
- # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered
- # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
- # "foo.exe" is OK but "foo" is an error.
- #
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
- # It is also a way to make sure we got the proper file name for the real test later on.
- test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
- if test "x$test_shortpath" = x; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&5
-$as_echo "$as_me: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&6;}
- as_fn_error $? "Cannot locate the the path of DXSDK_LIB_PATH" "$LINENO" 5
- fi
-
- # Call helper function which possibly converts this using DOS-style short mode.
- # If so, the updated path is stored in $new_path.
-
- input_path="$new_path"
- # Check if we need to convert this using DOS-style short mode. If the path
- # contains just simple characters, use it. Otherwise (spaces, weird characters),
- # take no chances and rewrite it.
- # Note: m4 eats our [], so we need to use [ and ] instead.
- has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]`
- if test "x$has_forbidden_chars" != x; then
- # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
- shortmode_path=`$CYGPATH -s -m -a "$input_path"`
- path_after_shortmode=`$CYGPATH -u "$shortmode_path"`
- if test "x$path_after_shortmode" != "x$input_to_shortpath"; then
- # Going to short mode and back again did indeed matter. Since short mode is
- # case insensitive, let's make it lowercase to improve readability.
- shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- # Now convert it back to Unix-stile (cygpath)
- input_path=`$CYGPATH -u "$shortmode_path"`
- new_path="$input_path"
- fi
- fi
-
- test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/`
- if test "x$test_cygdrive_prefix" = x; then
- # As a simple fix, exclude /usr/bin since it's not a real path.
- if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then
- # The path is in a Cygwin special directory (e.g. /home). We need this converted to
- # a path prefixed by /cygdrive for fixpath to work.
- new_path="$CYGWIN_ROOT_PATH$input_path"
- fi
- fi
-
-
- if test "x$path" != "x$new_path"; then
- DXSDK_LIB_PATH="$new_path"
- { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&5
-$as_echo "$as_me: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&6;}
- fi
-
- elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
-
- path="$DXSDK_LIB_PATH"
- has_colon=`$ECHO $path | $GREP ^.:`
- new_path="$path"
- if test "x$has_colon" = x; then
- # Not in mixed or Windows style, start by that.
- new_path=`cmd //c echo $path`
- fi
-
-
- input_path="$new_path"
- # Check if we need to convert this using DOS-style short mode. If the path
- # contains just simple characters, use it. Otherwise (spaces, weird characters),
- # take no chances and rewrite it.
- # Note: m4 eats our [], so we need to use [ and ] instead.
- has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]`
- if test "x$has_forbidden_chars" != x; then
- # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
- new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- fi
-
-
- windows_path="$new_path"
- if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
- unix_path=`$CYGPATH -u "$windows_path"`
- new_path="$unix_path"
- elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
- unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
- new_path="$unix_path"
- fi
-
- if test "x$path" != "x$new_path"; then
- DXSDK_LIB_PATH="$new_path"
- { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&5
-$as_echo "$as_me: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&6;}
- fi
-
- # Save the first 10 bytes of this path to the storage, so fixpath can work.
- all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}")
-
- else
- # We're on a posix platform. Hooray! :)
- path="$DXSDK_LIB_PATH"
- has_space=`$ECHO "$path" | $GREP " "`
- if test "x$has_space" != x; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&5
-$as_echo "$as_me: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&6;}
- as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
- fi
-
- # Use eval to expand a potential ~
- eval path="$path"
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of DXSDK_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
- DXSDK_LIB_PATH="`cd "$path"; $THEPWDCMD -L`"
- fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DirectX SDK include dir" >&5
-$as_echo_n "checking for DirectX SDK include dir... " >&6; }
- if test "x$with_dxsdk_include" != x; then
- DXSDK_INCLUDE_PATH="$with_dxsdk_include"
- else
- DXSDK_INCLUDE_PATH="$dxsdk_path/Include"
- fi
- # dsound.h is included in jsoundds
- if test ! -f "$DXSDK_INCLUDE_PATH/dsound.h"; then
- as_fn_error $? "Invalid DirectX SDK lib dir" "$LINENO" 5
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DXSDK_INCLUDE_PATH" >&5
-$as_echo "$DXSDK_INCLUDE_PATH" >&6; }
-
- if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
-
- # Input might be given as Windows format, start by converting to
- # unix format.
- path="$DXSDK_INCLUDE_PATH"
- new_path=`$CYGPATH -u "$path"`
-
- # Cygwin tries to hide some aspects of the Windows file system, such that binaries are
- # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered
- # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
- # "foo.exe" is OK but "foo" is an error.
- #
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
- # It is also a way to make sure we got the proper file name for the real test later on.
- test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
- if test "x$test_shortpath" = x; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&5
-$as_echo "$as_me: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&6;}
- as_fn_error $? "Cannot locate the the path of DXSDK_INCLUDE_PATH" "$LINENO" 5
- fi
-
- # Call helper function which possibly converts this using DOS-style short mode.
- # If so, the updated path is stored in $new_path.
-
- input_path="$new_path"
- # Check if we need to convert this using DOS-style short mode. If the path
- # contains just simple characters, use it. Otherwise (spaces, weird characters),
- # take no chances and rewrite it.
- # Note: m4 eats our [], so we need to use [ and ] instead.
- has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]`
- if test "x$has_forbidden_chars" != x; then
- # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
- shortmode_path=`$CYGPATH -s -m -a "$input_path"`
- path_after_shortmode=`$CYGPATH -u "$shortmode_path"`
- if test "x$path_after_shortmode" != "x$input_to_shortpath"; then
- # Going to short mode and back again did indeed matter. Since short mode is
- # case insensitive, let's make it lowercase to improve readability.
- shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- # Now convert it back to Unix-stile (cygpath)
- input_path=`$CYGPATH -u "$shortmode_path"`
- new_path="$input_path"
- fi
- fi
-
- test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/`
- if test "x$test_cygdrive_prefix" = x; then
- # As a simple fix, exclude /usr/bin since it's not a real path.
- if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then
- # The path is in a Cygwin special directory (e.g. /home). We need this converted to
- # a path prefixed by /cygdrive for fixpath to work.
- new_path="$CYGWIN_ROOT_PATH$input_path"
- fi
- fi
-
-
- if test "x$path" != "x$new_path"; then
- DXSDK_INCLUDE_PATH="$new_path"
- { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&5
-$as_echo "$as_me: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&6;}
- fi
-
- elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
-
- path="$DXSDK_INCLUDE_PATH"
- has_colon=`$ECHO $path | $GREP ^.:`
- new_path="$path"
- if test "x$has_colon" = x; then
- # Not in mixed or Windows style, start by that.
- new_path=`cmd //c echo $path`
- fi
-
-
- input_path="$new_path"
- # Check if we need to convert this using DOS-style short mode. If the path
- # contains just simple characters, use it. Otherwise (spaces, weird characters),
- # take no chances and rewrite it.
- # Note: m4 eats our [], so we need to use [ and ] instead.
- has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]`
- if test "x$has_forbidden_chars" != x; then
- # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
- new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- fi
-
-
- windows_path="$new_path"
- if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
- unix_path=`$CYGPATH -u "$windows_path"`
- new_path="$unix_path"
- elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
- unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
- new_path="$unix_path"
- fi
-
- if test "x$path" != "x$new_path"; then
- DXSDK_INCLUDE_PATH="$new_path"
- { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&5
-$as_echo "$as_me: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&6;}
- fi
-
- # Save the first 10 bytes of this path to the storage, so fixpath can work.
- all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}")
-
- else
- # We're on a posix platform. Hooray! :)
- path="$DXSDK_INCLUDE_PATH"
- has_space=`$ECHO "$path" | $GREP " "`
- if test "x$has_space" != x; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&5
-$as_echo "$as_me: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&6;}
- as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
- fi
-
- # Use eval to expand a potential ~
- eval path="$path"
- if test ! -f "$path" && test ! -d "$path"; then
- as_fn_error $? "The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5
- fi
-
- DXSDK_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`"
- fi
-
-
-
-
- LDFLAGS_JDK="$LDFLAGS_JDK -libpath:$DXSDK_LIB_PATH"
-
fi
@@ -18140,7 +17747,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -18451,7 +18058,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -18757,7 +18364,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -19350,7 +18957,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -19786,7 +19393,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -20922,7 +20529,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -21358,7 +20965,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -22259,7 +21866,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -22640,7 +22247,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -22987,7 +22594,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -23324,7 +22931,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -23645,7 +23252,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -24020,7 +23627,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -24326,7 +23933,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -24737,7 +24344,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -25137,7 +24744,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -25466,7 +25073,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -25778,7 +25385,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -26084,7 +25691,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -26390,7 +25997,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -26696,7 +26303,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -27055,7 +26662,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -27415,7 +27022,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -27788,7 +27395,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -28159,7 +27766,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -28468,7 +28075,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
- # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
@@ -28830,35 +28437,41 @@ done
if test "x$OPENJDK_TARGET_OS" = xsolaris; then
# Always specify -m flags on Solaris
- # keep track of c/cxx flags that we added outselves...
- # to prevent emitting warning...
- TARGET_BITS_FLAG="-m${OPENJDK_TARGET_CPU_BITS}"
+ # When we add flags to the "official" CFLAGS etc, we need to
+ # keep track of these additions in ADDED_CFLAGS etc. These
+ # will later be checked to make sure only controlled additions
+ # have been made to CFLAGS etc.
+ ADDED_CFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}"
+ ADDED_CXXFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}"
+ ADDED_LDFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}"
+ CFLAGS="${CFLAGS}${ADDED_CFLAGS}"
+ CXXFLAGS="${CXXFLAGS}${ADDED_CXXFLAGS}"
+ LDFLAGS="${LDFLAGS}${ADDED_LDFLAGS}"
- CFLAGS="${CFLAGS} ${TARGET_BITS_FLAG}"
- CXXFLAGS="${CXXFLAGS} ${TARGET_BITS_FLAG}"
- LDFLAGS="${LDFLAGS} ${TARGET_BITS_FLAG}"
-
- CFLAGS_JDK="${CFLAGS_JDK} ${TARGET_BITS_FLAG}"
- CXXFLAGS_JDK="${CXXFLAGS_JDK} ${TARGET_BITS_FLAG}"
- LDFLAGS_JDK="${LDFLAGS_JDK} ${TARGET_BITS_FLAG}"
+ CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}"
+ CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
+ LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
elif test "x$COMPILE_TYPE" = xreduced; then
if test "x$OPENJDK_TARGET_OS" != xwindows; then
# Specify -m if running reduced on other Posix platforms
- # keep track of c/cxx flags that we added outselves...
- # to prevent emitting warning...
- TARGET_BITS_FLAG="-m${OPENJDK_TARGET_CPU_BITS}"
+ # When we add flags to the "official" CFLAGS etc, we need to
+ # keep track of these additions in ADDED_CFLAGS etc. These
+ # will later be checked to make sure only controlled additions
+ # have been made to CFLAGS etc.
+ ADDED_CFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}"
+ ADDED_CXXFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}"
+ ADDED_LDFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}"
+ CFLAGS="${CFLAGS}${ADDED_CFLAGS}"
+ CXXFLAGS="${CXXFLAGS}${ADDED_CXXFLAGS}"
+ LDFLAGS="${LDFLAGS}${ADDED_LDFLAGS}"
- CFLAGS="${CFLAGS} ${TARGET_BITS_FLAG}"
- CXXFLAGS="${CXXFLAGS} ${TARGET_BITS_FLAG}"
- LDFLAGS="${LDFLAGS} ${TARGET_BITS_FLAG}"
-
- CFLAGS_JDK="${CFLAGS_JDK} ${TARGET_BITS_FLAG}"
- CXXFLAGS_JDK="${CXXFLAGS_JDK} ${TARGET_BITS_FLAG}"
- LDFLAGS_JDK="${LDFLAGS_JDK} ${TARGET_BITS_FLAG}"
+ CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}"
+ CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
+ LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
fi
fi
@@ -33618,6 +33231,7 @@ fi
# 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="$OUTPUT_ROOT/config.status"
+
# Create the actual output files. Now the main work of configure is done.
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -34899,6 +34513,11 @@ $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi
+# Try to move the config.log file to the output directory.
+if test -e ./config.log; then
+ $MV -f ./config.log "$OUTPUT_ROOT/config.log" 2> /dev/null
+fi
+
# Make the compare script executable
$CHMOD +x $OUTPUT_ROOT/compare.sh
diff --git a/common/autoconf/jdk-options.m4 b/common/autoconf/jdk-options.m4
index ba14373e593..b1c99bbe7dc 100644
--- a/common/autoconf/jdk-options.m4
+++ b/common/autoconf/jdk-options.m4
@@ -446,7 +446,7 @@ elif test "x$with_user_release_suffix" != x; then
else
BUILD_DATE=`date '+%Y_%m_%d_%H_%M'`
# Avoid [:alnum:] since it depends on the locale.
- CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyz0123456789'`
+ CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'`
USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
fi
AC_SUBST(USER_RELEASE_SUFFIX)
diff --git a/common/autoconf/platform.m4 b/common/autoconf/platform.m4
index 71ae2ceab7b..96c710d8a18 100644
--- a/common/autoconf/platform.m4
+++ b/common/autoconf/platform.m4
@@ -422,18 +422,21 @@ AC_SUBST(OS_VERSION_MICRO)
# Add -mX to various FLAGS variables.
AC_DEFUN([PLATFORM_SET_COMPILER_TARGET_BITS_FLAGS],
[
- # keep track of c/cxx flags that we added outselves...
- # to prevent emitting warning...
- TARGET_BITS_FLAG="-m${OPENJDK_TARGET_CPU_BITS}"
- AC_SUBST(TARGET_BITS_FLAG)
+ # When we add flags to the "official" CFLAGS etc, we need to
+ # keep track of these additions in ADDED_CFLAGS etc. These
+ # will later be checked to make sure only controlled additions
+ # have been made to CFLAGS etc.
+ ADDED_CFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}"
+ ADDED_CXXFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}"
+ ADDED_LDFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}"
- CFLAGS="${CFLAGS} ${TARGET_BITS_FLAG}"
- CXXFLAGS="${CXXFLAGS} ${TARGET_BITS_FLAG}"
- LDFLAGS="${LDFLAGS} ${TARGET_BITS_FLAG}"
+ CFLAGS="${CFLAGS}${ADDED_CFLAGS}"
+ CXXFLAGS="${CXXFLAGS}${ADDED_CXXFLAGS}"
+ LDFLAGS="${LDFLAGS}${ADDED_LDFLAGS}"
- CFLAGS_JDK="${CFLAGS_JDK} ${TARGET_BITS_FLAG}"
- CXXFLAGS_JDK="${CXXFLAGS_JDK} ${TARGET_BITS_FLAG}"
- LDFLAGS_JDK="${LDFLAGS_JDK} ${TARGET_BITS_FLAG}"
+ CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}"
+ CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
+ LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
])
AC_DEFUN_ONCE([PLATFORM_SETUP_OPENJDK_TARGET_BITS],
diff --git a/common/autoconf/source-dirs.m4 b/common/autoconf/source-dirs.m4
index bb0aba1b826..e040cc82f69 100644
--- a/common/autoconf/source-dirs.m4
+++ b/common/autoconf/source-dirs.m4
@@ -101,6 +101,10 @@ if test "x$with_add_source_root" != x; then
test -f $with_add_source_root/hotspot/make/Makefile; then
AC_MSG_ERROR([Your add source root seems to contain a full hotspot repo! An add source root should only contain additional sources.])
fi
+ if test -f $with_add_source_root/nashorn/makefiles/Makefile || \
+ test -f $with_add_source_root/nashorn/make/Makefile; then
+ AC_MSG_ERROR([Your add source root seems to contain a full nashorn repo! An add source root should only contain additional sources.])
+ fi
if test -f $with_add_source_root/jdk/makefiles/Makefile || \
test -f $with_add_source_root/jdk/make/Makefile; then
AC_MSG_ERROR([Your add source root seems to contain a full JDK repo! An add source root should only contain additional sources.])
@@ -136,6 +140,10 @@ if test "x$with_override_source_root" != x; then
test -f $with_override_source_root/hotspot/make/Makefile; then
AC_MSG_ERROR([Your override source root seems to contain a full hotspot repo! An override source root should only contain sources that override.])
fi
+ if test -f $with_override_source_root/nashorn/makefiles/Makefile || \
+ test -f $with_override_source_root/nashorn/make/Makefile; then
+ AC_MSG_ERROR([Your override source root seems to contain a full nashorn repo! An override source root should only contain sources that override.])
+ fi
if test -f $with_override_source_root/jdk/makefiles/Makefile || \
test -f $with_override_source_root/jdk/make/Makefile; then
AC_MSG_ERROR([Your override source root seems to contain a full JDK repo! An override source root should only contain sources that override.])
@@ -177,6 +185,9 @@ AC_ARG_WITH(override-jaxws, [AS_HELP_STRING([--with-override-jaxws],
AC_ARG_WITH(override-hotspot, [AS_HELP_STRING([--with-override-hotspot],
[use this hotspot dir for the build])])
+AC_ARG_WITH(override-nashorn, [AS_HELP_STRING([--with-override-nashorn],
+ [use this nashorn dir for the build])])
+
AC_ARG_WITH(override-jdk, [AS_HELP_STRING([--with-override-jdk],
[use this jdk dir for the build])])
@@ -241,7 +252,7 @@ if test "x$with_override_nashorn" != x; then
cd "$with_override_nashorn"
NASHORN_TOPDIR="`pwd`"
cd "$CURDIR"
- if ! test -f $NASHORN_TOPDIR/makefiles/BuildNashorn.gmk; then
+ if ! test -f $NASHORN_TOPDIR/makefiles/Makefile; then
AC_MSG_ERROR([You have to override nashorn with a full nashorn repo!])
fi
AC_MSG_CHECKING([if nashorn should be overridden])
diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in
index d2ffb614bcc..7e186693700 100644
--- a/common/autoconf/spec.gmk.in
+++ b/common/autoconf/spec.gmk.in
@@ -291,10 +291,6 @@ X_CFLAGS:=@X_CFLAGS@
X_LIBS:=@X_LIBS@
OPENWIN_HOME:=@OPENWIN_HOME@
-# DirectX SDK
-DXSDK_LIB_PATH=@DXSDK_LIB_PATH@
-DXSDK_INCLUDE_PATH=@DXSDK_INCLUDE_PATH@
-
# The lowest required version of macosx to enforce compatiblity for
MACOSX_VERSION_MIN=@MACOSX_VERSION_MIN@
@@ -304,7 +300,6 @@ MACOSX_VERSION_MIN=@MACOSX_VERSION_MIN@
COMPILER_TYPE:=@COMPILER_TYPE@
COMPILER_NAME:=@COMPILER_NAME@
-TARGET_BITS_FLAG=@TARGET_BITS_FLAG@
COMPILER_SUPPORTS_TARGET_BITS_FLAG=@COMPILER_SUPPORTS_TARGET_BITS_FLAG@
CC_OUT_OPTION:=@CC_OUT_OPTION@
diff --git a/common/autoconf/toolchain.m4 b/common/autoconf/toolchain.m4
index efaecc18960..21733003023 100644
--- a/common/autoconf/toolchain.m4
+++ b/common/autoconf/toolchain.m4
@@ -176,7 +176,9 @@ AC_DEFUN([TOOLCHAIN_SETUP_PATHS],
[
if test "x$OPENJDK_TARGET_OS" = "xwindows"; then
TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV
- TOOLCHAIN_SETUP_DXSDK
+ BASIC_DEPRECATED_ARG_WITH([dxsdk])
+ BASIC_DEPRECATED_ARG_WITH([dxsdk-lib])
+ BASIC_DEPRECATED_ARG_WITH([dxsdk-include])
fi
AC_SUBST(MSVCR_DLL)
diff --git a/common/autoconf/toolchain_windows.m4 b/common/autoconf/toolchain_windows.m4
index e5d4fff38f9..f97713f952f 100644
--- a/common/autoconf/toolchain_windows.m4
+++ b/common/autoconf/toolchain_windows.m4
@@ -277,61 +277,3 @@ AC_DEFUN([TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV],
AC_MSG_RESULT([$MSVCR_DLL])
BASIC_FIXUP_PATH(MSVCR_DLL)
])
-
-
-# Setup the DXSDK paths
-AC_DEFUN([TOOLCHAIN_SETUP_DXSDK],
-[
- AC_ARG_WITH(dxsdk, [AS_HELP_STRING([--with-dxsdk],
- [the DirectX SDK (Windows only) @<:@probed@:>@])])
- AC_ARG_WITH(dxsdk-lib, [AS_HELP_STRING([--with-dxsdk-lib],
- [the DirectX SDK lib directory (Windows only) @<:@probed@:>@])])
- AC_ARG_WITH(dxsdk-include, [AS_HELP_STRING([--with-dxsdk-include],
- [the DirectX SDK include directory (Windows only) @<:@probed@:>@])])
-
- AC_MSG_CHECKING([for DirectX SDK])
-
- if test "x$with_dxsdk" != x; then
- dxsdk_path="$with_dxsdk"
- elif test "x$DXSDK_DIR" != x; then
- dxsdk_path="$DXSDK_DIR"
- elif test -d "C:/DXSDK"; then
- dxsdk_path="C:/DXSDK"
- else
- AC_MSG_ERROR([Could not find the DirectX SDK])
- fi
- AC_MSG_RESULT([$dxsdk_path])
- BASIC_FIXUP_PATH(dxsdk_path)
-
- AC_MSG_CHECKING([for DirectX SDK lib dir])
- if test "x$with_dxsdk_lib" != x; then
- DXSDK_LIB_PATH="$with_dxsdk_lib"
- elif test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then
- DXSDK_LIB_PATH="$dxsdk_path/Lib/x64"
- else
- DXSDK_LIB_PATH="$dxsdk_path/Lib"
- fi
- # dsound.lib is linked to in jsoundds
- if test ! -f "$DXSDK_LIB_PATH/dsound.lib"; then
- AC_MSG_ERROR([Invalid DirectX SDK lib dir])
- fi
- AC_MSG_RESULT([$DXSDK_LIB_PATH])
- BASIC_FIXUP_PATH(DXSDK_LIB_PATH)
-
- AC_MSG_CHECKING([for DirectX SDK include dir])
- if test "x$with_dxsdk_include" != x; then
- DXSDK_INCLUDE_PATH="$with_dxsdk_include"
- else
- DXSDK_INCLUDE_PATH="$dxsdk_path/Include"
- fi
- # dsound.h is included in jsoundds
- if test ! -f "$DXSDK_INCLUDE_PATH/dsound.h"; then
- AC_MSG_ERROR([Invalid DirectX SDK lib dir])
- fi
- AC_MSG_RESULT([$DXSDK_INCLUDE_PATH])
- BASIC_FIXUP_PATH(DXSDK_INCLUDE_PATH)
-
- AC_SUBST(DXSDK_LIB_PATH)
- AC_SUBST(DXSDK_INCLUDE_PATH)
- LDFLAGS_JDK="$LDFLAGS_JDK -libpath:$DXSDK_LIB_PATH"
-])
diff --git a/common/bin/hgforest.sh b/common/bin/hgforest.sh
index 12cf0234b17..1dc50390b42 100644
--- a/common/bin/hgforest.sh
+++ b/common/bin/hgforest.sh
@@ -47,7 +47,7 @@ python=""
bpython=""
if [ "#!" = "$has_hash_bang" ] ; then
- python="`head -n 1 ${whichhg} | cut -b 3-`"
+ python="`head -n 1 ${whichhg} | cut -b 3- | sed -e 's/^[ \t]*//;s/[ \t]*$//'`"
bpython="`basename "$python"`"
fi
diff --git a/corba/.hgtags b/corba/.hgtags
index f96b90eb232..7271ad7b3fa 100644
--- a/corba/.hgtags
+++ b/corba/.hgtags
@@ -228,3 +228,5 @@ a013024b07475782f1fa8e196e950b34b4077663 jdk8-b101
d411c60a8c2fe8fdc572af907775e90f7eefd513 jdk8-b104
4e38de7c767e34104fa147b5b346d9fe6b731279 jdk8-b105
2e3a056c84a71eba78945c18b05397858ffd7ad0 jdk8-b106
+23fc34133152692b725db4bd617b4c8dfd6ccb05 jdk8-b107
+a4bb3b4500164748a9c33b2283cfda76d89f25ab jdk8-b108
diff --git a/corba/make/jprt.properties b/corba/make/jprt.properties
index 360b6b22dba..b03c53ca656 100644
--- a/corba/make/jprt.properties
+++ b/corba/make/jprt.properties
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 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
@@ -39,8 +39,8 @@ jprt.build.targets= \
solaris_x64_5.10-{product|fastdebug}, \
linux_i586_2.6-{product|fastdebug}, \
linux_x64_2.6-{product|fastdebug}, \
- windows_i586_5.1-{product|fastdebug}, \
- windows_x64_5.2-{product|fastdebug}
+ windows_i586_6.1-{product|fastdebug}, \
+ windows_x64_6.1-{product|fastdebug}
# Directories to be excluded from the source bundles
jprt.bundle.exclude.src.dirs=build dist webrev
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/transport/DefaultSocketFactoryImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/transport/DefaultSocketFactoryImpl.java
index fc1ffc70197..63578b9c3d1 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/transport/DefaultSocketFactoryImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/transport/DefaultSocketFactoryImpl.java
@@ -32,6 +32,7 @@ import java.net.SocketException;
import java.net.ServerSocket;
import java.nio.channels.SocketChannel;
import java.nio.channels.ServerSocketChannel;
+import java.security.PrivilegedAction;
import com.sun.corba.se.pept.transport.Acceptor;
@@ -44,6 +45,22 @@ public class DefaultSocketFactoryImpl
implements ORBSocketFactory
{
private ORB orb;
+ private static final boolean keepAlive;
+
+ static {
+ keepAlive = java.security.AccessController.doPrivileged(
+ new PrivilegedAction() {
+ @Override
+ public Boolean run () {
+ String value =
+ System.getProperty("com.sun.CORBA.transport.enableTcpKeepAlive");
+ if (value != null)
+ return new Boolean(!"false".equalsIgnoreCase(value));
+
+ return Boolean.FALSE;
+ }
+ });
+ }
public void setORB(ORB orb)
{
@@ -85,6 +102,9 @@ public class DefaultSocketFactoryImpl
// Disable Nagle's algorithm (i.e., always send immediately).
socket.setTcpNoDelay(true);
+ if (keepAlive)
+ socket.setKeepAlive(true);
+
return socket;
}
@@ -95,6 +115,8 @@ public class DefaultSocketFactoryImpl
{
// Disable Nagle's algorithm (i.e., always send immediately).
socket.setTcpNoDelay(true);
+ if (keepAlive)
+ socket.setKeepAlive(true);
}
}
diff --git a/hotspot/.hgtags b/hotspot/.hgtags
index bc3aba45318..d218a0c962d 100644
--- a/hotspot/.hgtags
+++ b/hotspot/.hgtags
@@ -375,3 +375,7 @@ acac3bde66b2c22791c257a8d99611d6d08c6713 jdk8-b105
18b4798adbc42c6fa16f5ecb7d5cd3ca130754bf hs25-b48
aed585cafc0d9655726af6d1e1081d1c94cb3b5c jdk8-b106
50794d8ac11c9579b41dec4de23b808fef9f34a1 hs25-b49
+5b7f90aab3ad25a25b75b7b2bb18d5ae23d8231c jdk8-b107
+a09fe9d1e016c285307507a5793bc4fa6215e9c9 hs25-b50
+85072013aad46050a362d10ab78e963121c8014c jdk8-b108
+566db1b0e6efca31f181456e54c8911d0192410d hs25-b51
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java
index 1840caf9313..354f0b906b3 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java
@@ -1213,6 +1213,7 @@ public class CommandProcessor {
}
HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase();
if (t.countTokens() == 1) {
+ String name = t.nextToken();
out.println("intConstant " + name + " " + db.lookupIntConstant(name));
} else if (t.countTokens() == 0) {
Iterator i = db.getIntConstants();
@@ -1235,6 +1236,7 @@ public class CommandProcessor {
}
HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase();
if (t.countTokens() == 1) {
+ String name = t.nextToken();
out.println("longConstant " + name + " " + db.lookupLongConstant(name));
} else if (t.countTokens() == 0) {
Iterator i = db.getLongConstants();
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java
index d1b56881f13..f25d50ff23c 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java
@@ -81,7 +81,7 @@ class BsdAddress implements Address {
public Address getCompKlassAddressAt(long offset)
throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readCompOopAddress(addr + offset);
+ return debugger.readCompKlassAddress(addr + offset);
}
//
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java
index f84da894ac2..319d2430af2 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java
@@ -792,7 +792,7 @@ public class VM {
public boolean isCompressedKlassPointersEnabled() {
if (compressedKlassPointersEnabled == null) {
- Flag flag = getCommandLineFlag("UseCompressedKlassPointers");
+ Flag flag = getCommandLineFlag("UseCompressedClassPointers");
compressedKlassPointersEnabled = (flag == null) ? Boolean.FALSE:
(flag.getBool()? Boolean.TRUE: Boolean.FALSE);
}
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java
index a0123dd4c99..daab682aaef 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java
@@ -66,18 +66,18 @@ public class HeapSummary extends Tool {
printGCAlgorithm(flagMap);
System.out.println();
System.out.println("Heap Configuration:");
- printValue("MinHeapFreeRatio = ", getFlagValue("MinHeapFreeRatio", flagMap));
- printValue("MaxHeapFreeRatio = ", getFlagValue("MaxHeapFreeRatio", flagMap));
- printValMB("MaxHeapSize = ", getFlagValue("MaxHeapSize", flagMap));
- printValMB("NewSize = ", getFlagValue("NewSize", flagMap));
- printValMB("MaxNewSize = ", getFlagValue("MaxNewSize", flagMap));
- printValMB("OldSize = ", getFlagValue("OldSize", flagMap));
- printValue("NewRatio = ", getFlagValue("NewRatio", flagMap));
- printValue("SurvivorRatio = ", getFlagValue("SurvivorRatio", flagMap));
- printValMB("MetaspaceSize = ", getFlagValue("MetaspaceSize", flagMap));
- printValMB("ClassMetaspaceSize = ", getFlagValue("ClassMetaspaceSize", flagMap));
- printValMB("MaxMetaspaceSize = ", getFlagValue("MaxMetaspaceSize", flagMap));
- printValMB("G1HeapRegionSize = ", HeapRegion.grainBytes());
+ printValue("MinHeapFreeRatio = ", getFlagValue("MinHeapFreeRatio", flagMap));
+ printValue("MaxHeapFreeRatio = ", getFlagValue("MaxHeapFreeRatio", flagMap));
+ printValMB("MaxHeapSize = ", getFlagValue("MaxHeapSize", flagMap));
+ printValMB("NewSize = ", getFlagValue("NewSize", flagMap));
+ printValMB("MaxNewSize = ", getFlagValue("MaxNewSize", flagMap));
+ printValMB("OldSize = ", getFlagValue("OldSize", flagMap));
+ printValue("NewRatio = ", getFlagValue("NewRatio", flagMap));
+ printValue("SurvivorRatio = ", getFlagValue("SurvivorRatio", flagMap));
+ printValMB("MetaspaceSize = ", getFlagValue("MetaspaceSize", flagMap));
+ printValMB("CompressedClassSpaceSize = ", getFlagValue("CompressedClassSpaceSize", flagMap));
+ printValMB("MaxMetaspaceSize = ", getFlagValue("MaxMetaspaceSize", flagMap));
+ printValMB("G1HeapRegionSize = ", HeapRegion.grainBytes());
System.out.println();
System.out.println("Heap Usage:");
diff --git a/hotspot/make/bsd/makefiles/gcc.make b/hotspot/make/bsd/makefiles/gcc.make
index b98485f901d..0277bb66aa3 100644
--- a/hotspot/make/bsd/makefiles/gcc.make
+++ b/hotspot/make/bsd/makefiles/gcc.make
@@ -80,7 +80,7 @@ ifeq ($(SPEC),)
HOSTCC = $(CC)
endif
- AS = $(CC) -c -x assembler-with-cpp
+ AS = $(CC) -c
endif
@@ -347,6 +347,13 @@ ifeq ($(OS_VENDOR), Darwin)
LDFLAGS += -mmacosx-version-min=$(MACOSX_VERSION_MIN)
endif
+
+#------------------------------------------------------------------------
+# Assembler flags
+
+# Enforce prerpocessing of .s files
+ASFLAGS += -x assembler-with-cpp
+
#------------------------------------------------------------------------
# Linker flags
diff --git a/hotspot/make/excludeSrc.make b/hotspot/make/excludeSrc.make
index 7cc879a3d7b..c3a9b4dea0e 100644
--- a/hotspot/make/excludeSrc.make
+++ b/hotspot/make/excludeSrc.make
@@ -99,7 +99,7 @@ ifeq ($(INCLUDE_ALL_GCS), false)
psTasks.cpp psVirtualspace.cpp psYoungGen.cpp vmPSOperations.cpp asParNewGeneration.cpp \
parCardTableModRefBS.cpp parGCAllocBuffer.cpp parNewGeneration.cpp mutableSpace.cpp \
gSpaceCounters.cpp allocationStats.cpp spaceCounters.cpp gcAdaptivePolicyCounters.cpp \
- mutableNUMASpace.cpp immutableSpace.cpp yieldingWorkGroup.cpp
+ mutableNUMASpace.cpp immutableSpace.cpp yieldingWorkGroup.cpp hSpaceCounters.cpp
endif
ifeq ($(INCLUDE_NMT), false)
diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version
index 15223e843df..fa4d6554e16 100644
--- a/hotspot/make/hotspot_version
+++ b/hotspot/make/hotspot_version
@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
HS_MAJOR_VER=25
HS_MINOR_VER=0
-HS_BUILD_NUMBER=49
+HS_BUILD_NUMBER=51
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
diff --git a/hotspot/make/jprt.properties b/hotspot/make/jprt.properties
index 5971546c6d9..f322e7024ae 100644
--- a/hotspot/make/jprt.properties
+++ b/hotspot/make/jprt.properties
@@ -120,13 +120,13 @@ jprt.my.macosx.x64.jdk7=macosx_x64_10.7
jprt.my.macosx.x64.jdk7u8=${jprt.my.macosx.x64.jdk7}
jprt.my.macosx.x64=${jprt.my.macosx.x64.${jprt.tools.default.release}}
-jprt.my.windows.i586.jdk8=windows_i586_5.1
-jprt.my.windows.i586.jdk7=windows_i586_5.1
+jprt.my.windows.i586.jdk8=windows_i586_6.1
+jprt.my.windows.i586.jdk7=windows_i586_6.1
jprt.my.windows.i586.jdk7u8=${jprt.my.windows.i586.jdk7}
jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}}
-jprt.my.windows.x64.jdk8=windows_x64_5.2
-jprt.my.windows.x64.jdk7=windows_x64_5.2
+jprt.my.windows.x64.jdk8=windows_x64_6.1
+jprt.my.windows.x64.jdk7=windows_x64_6.1
jprt.my.windows.x64.jdk7u8=${jprt.my.windows.x64.jdk7}
jprt.my.windows.x64=${jprt.my.windows.x64.${jprt.tools.default.release}}
diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp
index 12d51571ccb..cb4c04a388b 100644
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp
@@ -105,7 +105,7 @@ bool LIR_Assembler::is_single_instruction(LIR_Op* op) {
if (src->is_address() && !src->is_stack() && (src->type() == T_OBJECT || src->type() == T_ARRAY)) return false;
}
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
if (src->is_address() && !src->is_stack() && src->type() == T_ADDRESS &&
src->as_address_ptr()->disp() == oopDesc::klass_offset_in_bytes()) return false;
}
@@ -963,7 +963,7 @@ int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType typ
case T_METADATA: __ ld_ptr(base, offset, to_reg->as_register()); break;
case T_ADDRESS:
#ifdef _LP64
- if (offset == oopDesc::klass_offset_in_bytes() && UseCompressedKlassPointers) {
+ if (offset == oopDesc::klass_offset_in_bytes() && UseCompressedClassPointers) {
__ lduw(base, offset, to_reg->as_register());
__ decode_klass_not_null(to_reg->as_register());
} else
@@ -2208,7 +2208,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
// We don't know the array types are compatible
if (basic_type != T_OBJECT) {
// Simple test for basic type arrays
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
// We don't need decode because we just need to compare
__ lduw(src, oopDesc::klass_offset_in_bytes(), tmp);
__ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2);
@@ -2342,7 +2342,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
// but not necessarily exactly of type default_type.
Label known_ok, halt;
metadata2reg(op->expected_type()->constant_encoding(), tmp);
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
// tmp holds the default type. It currently comes uncompressed after the
// load of a constant, so encode it.
__ encode_klass_not_null(tmp);
diff --git a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp
index bf4074b30fd..6d10ab81aaf 100644
--- a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp
@@ -186,7 +186,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
set((intx)markOopDesc::prototype(), t1);
}
st_ptr(t1, obj, oopDesc::mark_offset_in_bytes());
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
// Save klass
mov(klass, t1);
encode_klass_not_null(t1);
@@ -196,7 +196,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
}
if (len->is_valid()) {
st(len, obj, arrayOopDesc::length_offset_in_bytes());
- } else if (UseCompressedKlassPointers) {
+ } else if (UseCompressedClassPointers) {
// otherwise length is in the class gap
store_klass_gap(G0, obj);
}
diff --git a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp
index 093be806072..e4fe6bb00a4 100644
--- a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp
@@ -57,6 +57,7 @@ define_pd_global(intx, RegisterCostAreaRatio, 12000);
define_pd_global(bool, UseTLAB, true);
define_pd_global(bool, ResizeTLAB, true);
define_pd_global(intx, LoopUnrollLimit, 60); // Design center runs on 1.3.1
+define_pd_global(intx, MinJumpTableSize, 5);
// Peephole and CISC spilling both break the graph, and so makes the
// scheduler sick.
diff --git a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp
index d2c4e3b0261..9f1f2e53371 100644
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp
@@ -3911,7 +3911,7 @@ void MacroAssembler::load_klass(Register src_oop, Register klass) {
// The number of bytes in this code is used by
// MachCallDynamicJavaNode::ret_addr_offset()
// if this changes, change that.
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
lduw(src_oop, oopDesc::klass_offset_in_bytes(), klass);
decode_klass_not_null(klass);
} else {
@@ -3920,7 +3920,7 @@ void MacroAssembler::load_klass(Register src_oop, Register klass) {
}
void MacroAssembler::store_klass(Register klass, Register dst_oop) {
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
assert(dst_oop != klass, "not enough registers");
encode_klass_not_null(klass);
st(klass, dst_oop, oopDesc::klass_offset_in_bytes());
@@ -3930,7 +3930,7 @@ void MacroAssembler::store_klass(Register klass, Register dst_oop) {
}
void MacroAssembler::store_klass_gap(Register s, Register d) {
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
assert(s != d, "not enough registers");
st(s, d, oopDesc::klass_gap_offset_in_bytes());
}
@@ -4089,7 +4089,7 @@ void MacroAssembler::decode_heap_oop_not_null(Register src, Register dst) {
}
void MacroAssembler::encode_klass_not_null(Register r) {
- assert (UseCompressedKlassPointers, "must be compressed");
+ assert (UseCompressedClassPointers, "must be compressed");
assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
assert(r != G6_heapbase, "bad register choice");
set((intptr_t)Universe::narrow_klass_base(), G6_heapbase);
@@ -4105,7 +4105,7 @@ void MacroAssembler::encode_klass_not_null(Register src, Register dst) {
if (src == dst) {
encode_klass_not_null(src);
} else {
- assert (UseCompressedKlassPointers, "must be compressed");
+ assert (UseCompressedClassPointers, "must be compressed");
assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
set((intptr_t)Universe::narrow_klass_base(), dst);
sub(src, dst, dst);
@@ -4119,7 +4119,7 @@ void MacroAssembler::encode_klass_not_null(Register src, Register dst) {
// generated by decode_klass_not_null() and reinit_heapbase(). Hence, if
// the instructions they generate change, then this method needs to be updated.
int MacroAssembler::instr_size_for_decode_klass_not_null() {
- assert (UseCompressedKlassPointers, "only for compressed klass ptrs");
+ assert (UseCompressedClassPointers, "only for compressed klass ptrs");
// set + add + set
int num_instrs = insts_for_internal_set((intptr_t)Universe::narrow_klass_base()) + 1 +
insts_for_internal_set((intptr_t)Universe::narrow_ptrs_base());
@@ -4135,7 +4135,7 @@ int MacroAssembler::instr_size_for_decode_klass_not_null() {
void MacroAssembler::decode_klass_not_null(Register r) {
// Do not add assert code to this unless you change vtableStubs_sparc.cpp
// pd_code_size_limit.
- assert (UseCompressedKlassPointers, "must be compressed");
+ assert (UseCompressedClassPointers, "must be compressed");
assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
assert(r != G6_heapbase, "bad register choice");
set((intptr_t)Universe::narrow_klass_base(), G6_heapbase);
@@ -4151,7 +4151,7 @@ void MacroAssembler::decode_klass_not_null(Register src, Register dst) {
} else {
// Do not add assert code to this unless you change vtableStubs_sparc.cpp
// pd_code_size_limit.
- assert (UseCompressedKlassPointers, "must be compressed");
+ assert (UseCompressedClassPointers, "must be compressed");
assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
if (Universe::narrow_klass_shift() != 0) {
assert((src != G6_heapbase) && (dst != G6_heapbase), "bad register choice");
@@ -4167,7 +4167,7 @@ void MacroAssembler::decode_klass_not_null(Register src, Register dst) {
}
void MacroAssembler::reinit_heapbase() {
- if (UseCompressedOops || UseCompressedKlassPointers) {
+ if (UseCompressedOops || UseCompressedClassPointers) {
if (Universe::heap() != NULL) {
set((intptr_t)Universe::narrow_ptrs_base(), G6_heapbase);
} else {
diff --git a/hotspot/src/cpu/sparc/vm/sparc.ad b/hotspot/src/cpu/sparc/vm/sparc.ad
index a72bffdadeb..58c113a0c1a 100644
--- a/hotspot/src/cpu/sparc/vm/sparc.ad
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad
@@ -557,7 +557,7 @@ int MachCallDynamicJavaNode::ret_addr_offset() {
int entry_offset = InstanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
int klass_load_size;
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
assert(Universe::heap() != NULL, "java heap should be initialized");
klass_load_size = MacroAssembler::instr_size_for_decode_klass_not_null() + 1*BytesPerInstWord;
} else {
@@ -1657,7 +1657,7 @@ uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
st->print_cr("\nUEP:");
#ifdef _LP64
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
assert(Universe::heap() != NULL, "java heap should be initialized");
st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check - compressed klass");
st->print_cr("\tSET Universe::narrow_klass_base,R_G6_heap_base");
@@ -1897,7 +1897,7 @@ bool Matcher::narrow_oop_use_complex_address() {
bool Matcher::narrow_klass_use_complex_address() {
NOT_LP64(ShouldNotCallThis());
- assert(UseCompressedKlassPointers, "only for compressed klass code");
+ assert(UseCompressedClassPointers, "only for compressed klass code");
return false;
}
@@ -2561,7 +2561,7 @@ encode %{
int off = __ offset();
__ load_klass(O0, G3_scratch);
int klass_load_size;
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
assert(Universe::heap() != NULL, "java heap should be initialized");
klass_load_size = MacroAssembler::instr_size_for_decode_klass_not_null() + 1*BytesPerInstWord;
} else {
diff --git a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp
index 214940cdbfb..612ae118ee4 100644
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp
@@ -2945,7 +2945,7 @@ class StubGenerator: public StubCodeGenerator {
BLOCK_COMMENT("arraycopy argument klass checks");
// get src->klass()
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
__ delayed()->nop(); // ??? not good
__ load_klass(src, G3_src_klass);
} else {
@@ -2980,7 +2980,7 @@ class StubGenerator: public StubCodeGenerator {
// Load 32-bits signed value. Use br() instruction with it to check icc.
__ lduw(G3_src_klass, lh_offset, G5_lh);
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
__ load_klass(dst, G4_dst_klass);
}
// Handle objArrays completely differently...
@@ -2988,7 +2988,7 @@ class StubGenerator: public StubCodeGenerator {
__ set(objArray_lh, O5_temp);
__ cmp(G5_lh, O5_temp);
__ br(Assembler::equal, false, Assembler::pt, L_objArray);
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
__ delayed()->nop();
} else {
__ delayed()->ld_ptr(dst, oopDesc::klass_offset_in_bytes(), G4_dst_klass);
diff --git a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp
index 39663758035..ce19d4d7e7b 100644
--- a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp
@@ -218,13 +218,13 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
// ld;ld;ld,jmp,nop
const int basic = 5*BytesPerInstWord +
// shift;add for load_klass (only shift with zero heap based)
- (UseCompressedKlassPointers ?
+ (UseCompressedClassPointers ?
MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
return basic + slop;
} else {
const int basic = (28 LP64_ONLY(+ 6)) * BytesPerInstWord +
// shift;add for load_klass (only shift with zero heap based)
- (UseCompressedKlassPointers ?
+ (UseCompressedClassPointers ?
MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
return (basic + slop);
}
diff --git a/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp b/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp
index ea5d6d39da6..2d1b5f1f3c7 100644
--- a/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp
+++ b/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp
@@ -148,7 +148,7 @@
static int adjust_reg_range(int range) {
// Reduce the number of available regs (to free r12) in case of compressed oops
- if (UseCompressedOops || UseCompressedKlassPointers) return range - 1;
+ if (UseCompressedOops || UseCompressedClassPointers) return range - 1;
return range;
}
diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
index 334d0cc92db..94c2c39d26f 100644
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
@@ -341,7 +341,7 @@ int LIR_Assembler::check_icache() {
Register receiver = FrameMap::receiver_opr->as_register();
Register ic_klass = IC_Klass;
const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9);
- const bool do_post_padding = VerifyOops || UseCompressedKlassPointers;
+ const bool do_post_padding = VerifyOops || UseCompressedClassPointers;
if (!do_post_padding) {
// insert some nops so that the verified entry point is aligned on CodeEntryAlignment
while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) {
@@ -1263,7 +1263,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch
break;
case T_ADDRESS:
- if (UseCompressedKlassPointers && addr->disp() == oopDesc::klass_offset_in_bytes()) {
+ if (UseCompressedClassPointers && addr->disp() == oopDesc::klass_offset_in_bytes()) {
__ movl(dest->as_register(), from_addr);
} else {
__ movptr(dest->as_register(), from_addr);
@@ -1371,7 +1371,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch
__ verify_oop(dest->as_register());
} else if (type == T_ADDRESS && addr->disp() == oopDesc::klass_offset_in_bytes()) {
#ifdef _LP64
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
__ decode_klass_not_null(dest->as_register());
}
#endif
@@ -1716,7 +1716,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
} else if (obj == klass_RInfo) {
klass_RInfo = dst;
}
- if (k->is_loaded() && !UseCompressedKlassPointers) {
+ if (k->is_loaded() && !UseCompressedClassPointers) {
select_different_registers(obj, dst, k_RInfo, klass_RInfo);
} else {
Rtmp1 = op->tmp3()->as_register();
@@ -1724,14 +1724,6 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
}
assert_different_registers(obj, k_RInfo, klass_RInfo);
- if (!k->is_loaded()) {
- klass2reg_with_patching(k_RInfo, op->info_for_patch());
- } else {
-#ifdef _LP64
- __ mov_metadata(k_RInfo, k->constant_encoding());
-#endif // _LP64
- }
- assert(obj != k_RInfo, "must be different");
__ cmpptr(obj, (int32_t)NULL_WORD);
if (op->should_profile()) {
@@ -1748,13 +1740,21 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
} else {
__ jcc(Assembler::equal, *obj_is_null);
}
+
+ if (!k->is_loaded()) {
+ klass2reg_with_patching(k_RInfo, op->info_for_patch());
+ } else {
+#ifdef _LP64
+ __ mov_metadata(k_RInfo, k->constant_encoding());
+#endif // _LP64
+ }
__ verify_oop(obj);
if (op->fast_check()) {
// get object class
// not a safepoint as obj null check happens earlier
#ifdef _LP64
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
__ load_klass(Rtmp1, obj);
__ cmpptr(k_RInfo, Rtmp1);
} else {
@@ -3294,7 +3294,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
// We don't know the array types are compatible
if (basic_type != T_OBJECT) {
// Simple test for basic type arrays
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
__ movl(tmp, src_klass_addr);
__ cmpl(tmp, dst_klass_addr);
} else {
@@ -3456,21 +3456,21 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
Label known_ok, halt;
__ mov_metadata(tmp, default_type->constant_encoding());
#ifdef _LP64
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
__ encode_klass_not_null(tmp);
}
#endif
if (basic_type != T_OBJECT) {
- if (UseCompressedKlassPointers) __ cmpl(tmp, dst_klass_addr);
+ if (UseCompressedClassPointers) __ cmpl(tmp, dst_klass_addr);
else __ cmpptr(tmp, dst_klass_addr);
__ jcc(Assembler::notEqual, halt);
- if (UseCompressedKlassPointers) __ cmpl(tmp, src_klass_addr);
+ if (UseCompressedClassPointers) __ cmpl(tmp, src_klass_addr);
else __ cmpptr(tmp, src_klass_addr);
__ jcc(Assembler::equal, known_ok);
} else {
- if (UseCompressedKlassPointers) __ cmpl(tmp, dst_klass_addr);
+ if (UseCompressedClassPointers) __ cmpl(tmp, dst_klass_addr);
else __ cmpptr(tmp, dst_klass_addr);
__ jcc(Assembler::equal, known_ok);
__ cmpptr(src, dst);
diff --git a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
index e6638581bcf..308befddc77 100644
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
@@ -1239,7 +1239,7 @@ void LIRGenerator::do_CheckCast(CheckCast* x) {
}
LIR_Opr reg = rlock_result(x);
LIR_Opr tmp3 = LIR_OprFact::illegalOpr;
- if (!x->klass()->is_loaded() || UseCompressedKlassPointers) {
+ if (!x->klass()->is_loaded() || UseCompressedClassPointers) {
tmp3 = new_register(objectType);
}
__ checkcast(reg, obj.result(), x->klass(),
@@ -1261,7 +1261,7 @@ void LIRGenerator::do_InstanceOf(InstanceOf* x) {
}
obj.load_item();
LIR_Opr tmp3 = LIR_OprFact::illegalOpr;
- if (!x->klass()->is_loaded() || UseCompressedKlassPointers) {
+ if (!x->klass()->is_loaded() || UseCompressedClassPointers) {
tmp3 = new_register(objectType);
}
__ instanceof(reg, obj.result(), x->klass(),
diff --git a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp
index d9ae6ce5de5..805fe5a48ca 100644
--- a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp
@@ -157,7 +157,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markOopDesc::prototype());
}
#ifdef _LP64
- if (UseCompressedKlassPointers) { // Take care not to kill klass
+ if (UseCompressedClassPointers) { // Take care not to kill klass
movptr(t1, klass);
encode_klass_not_null(t1);
movl(Address(obj, oopDesc::klass_offset_in_bytes()), t1);
@@ -171,7 +171,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len);
}
#ifdef _LP64
- else if (UseCompressedKlassPointers) {
+ else if (UseCompressedClassPointers) {
xorptr(t1, t1);
store_klass_gap(obj, t1);
}
@@ -334,7 +334,7 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
int start_offset = offset();
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
load_klass(rscratch1, receiver);
cmpptr(rscratch1, iCache);
} else {
@@ -345,7 +345,7 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
jump_cc(Assembler::notEqual,
RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9);
- assert(UseCompressedKlassPointers || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry");
+ assert(UseCompressedClassPointers || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry");
}
diff --git a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp
index d49bec21fe7..a45bd9624e5 100644
--- a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp
+++ b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp
@@ -30,7 +30,6 @@
// Sets the default values for platform dependent flags used by the server compiler.
// (see c2_globals.hpp). Alpha-sorted.
-
define_pd_global(bool, BackgroundCompilation, true);
define_pd_global(bool, UseTLAB, true);
define_pd_global(bool, ResizeTLAB, true);
@@ -52,6 +51,7 @@ define_pd_global(intx, OnStackReplacePercentage, 140);
define_pd_global(intx, ConditionalMoveLimit, 3);
define_pd_global(intx, FLOATPRESSURE, 6);
define_pd_global(intx, FreqInlineSize, 325);
+define_pd_global(intx, MinJumpTableSize, 10);
#ifdef AMD64
define_pd_global(intx, INTPRESSURE, 13);
define_pd_global(intx, InteriorEntryAlignment, 16);
diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
index b331f694959..fed50ef4286 100644
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
@@ -1635,7 +1635,7 @@ void MacroAssembler::call_VM_base(Register oop_result,
#ifdef ASSERT
// TraceBytecodes does not use r12 but saves it over the call, so don't verify
// r12 is the heapbase.
- LP64_ONLY(if ((UseCompressedOops || UseCompressedKlassPointers) && !TraceBytecodes) verify_heapbase("call_VM_base: heap base corrupted?");)
+ LP64_ONLY(if ((UseCompressedOops || UseCompressedClassPointers) && !TraceBytecodes) verify_heapbase("call_VM_base: heap base corrupted?");)
#endif // ASSERT
assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result");
@@ -4802,7 +4802,7 @@ void MacroAssembler::restore_cpu_control_state_after_jni() {
void MacroAssembler::load_klass(Register dst, Register src) {
#ifdef _LP64
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
decode_klass_not_null(dst);
} else
@@ -4817,7 +4817,7 @@ void MacroAssembler::load_prototype_header(Register dst, Register src) {
void MacroAssembler::store_klass(Register dst, Register src) {
#ifdef _LP64
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
encode_klass_not_null(src);
movl(Address(dst, oopDesc::klass_offset_in_bytes()), src);
} else
@@ -4892,7 +4892,7 @@ void MacroAssembler::store_heap_oop_null(Address dst) {
#ifdef _LP64
void MacroAssembler::store_klass_gap(Register dst, Register src) {
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
// Store to klass gap in destination
movl(Address(dst, oopDesc::klass_gap_offset_in_bytes()), src);
}
@@ -5075,7 +5075,7 @@ void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
// when (Universe::heap() != NULL). Hence, if the instructions they
// generate change, then this method needs to be updated.
int MacroAssembler::instr_size_for_decode_klass_not_null() {
- assert (UseCompressedKlassPointers, "only for compressed klass ptrs");
+ assert (UseCompressedClassPointers, "only for compressed klass ptrs");
// mov64 + addq + shlq? + mov64 (for reinit_heapbase()).
return (Universe::narrow_klass_shift() == 0 ? 20 : 24);
}
@@ -5085,7 +5085,7 @@ int MacroAssembler::instr_size_for_decode_klass_not_null() {
void MacroAssembler::decode_klass_not_null(Register r) {
// Note: it will change flags
assert(Universe::narrow_klass_base() != NULL, "Base should be initialized");
- assert (UseCompressedKlassPointers, "should only be used for compressed headers");
+ assert (UseCompressedClassPointers, "should only be used for compressed headers");
assert(r != r12_heapbase, "Decoding a klass in r12");
// Cannot assert, unverified entry point counts instructions (see .ad file)
// vtableStubs also counts instructions in pd_code_size_limit.
@@ -5103,7 +5103,7 @@ void MacroAssembler::decode_klass_not_null(Register r) {
void MacroAssembler::decode_klass_not_null(Register dst, Register src) {
// Note: it will change flags
assert(Universe::narrow_klass_base() != NULL, "Base should be initialized");
- assert (UseCompressedKlassPointers, "should only be used for compressed headers");
+ assert (UseCompressedClassPointers, "should only be used for compressed headers");
if (dst == src) {
decode_klass_not_null(dst);
} else {
@@ -5141,7 +5141,7 @@ void MacroAssembler::set_narrow_oop(Address dst, jobject obj) {
}
void MacroAssembler::set_narrow_klass(Register dst, Klass* k) {
- assert (UseCompressedKlassPointers, "should only be used for compressed headers");
+ assert (UseCompressedClassPointers, "should only be used for compressed headers");
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = oop_recorder()->find_index(k);
RelocationHolder rspec = metadata_Relocation::spec(klass_index);
@@ -5149,7 +5149,7 @@ void MacroAssembler::set_narrow_klass(Register dst, Klass* k) {
}
void MacroAssembler::set_narrow_klass(Address dst, Klass* k) {
- assert (UseCompressedKlassPointers, "should only be used for compressed headers");
+ assert (UseCompressedClassPointers, "should only be used for compressed headers");
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = oop_recorder()->find_index(k);
RelocationHolder rspec = metadata_Relocation::spec(klass_index);
@@ -5175,7 +5175,7 @@ void MacroAssembler::cmp_narrow_oop(Address dst, jobject obj) {
}
void MacroAssembler::cmp_narrow_klass(Register dst, Klass* k) {
- assert (UseCompressedKlassPointers, "should only be used for compressed headers");
+ assert (UseCompressedClassPointers, "should only be used for compressed headers");
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = oop_recorder()->find_index(k);
RelocationHolder rspec = metadata_Relocation::spec(klass_index);
@@ -5183,7 +5183,7 @@ void MacroAssembler::cmp_narrow_klass(Register dst, Klass* k) {
}
void MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) {
- assert (UseCompressedKlassPointers, "should only be used for compressed headers");
+ assert (UseCompressedClassPointers, "should only be used for compressed headers");
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = oop_recorder()->find_index(k);
RelocationHolder rspec = metadata_Relocation::spec(klass_index);
@@ -5191,7 +5191,7 @@ void MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) {
}
void MacroAssembler::reinit_heapbase() {
- if (UseCompressedOops || UseCompressedKlassPointers) {
+ if (UseCompressedOops || UseCompressedClassPointers) {
if (Universe::heap() != NULL) {
if (Universe::narrow_oop_base() == NULL) {
MacroAssembler::xorptr(r12_heapbase, r12_heapbase);
diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86.hpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86.hpp
index c828c90fba1..a632fbab313 100644
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86.hpp
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86.hpp
@@ -34,9 +34,9 @@
// Run with +PrintInterpreter to get the VM to print out the size.
// Max size with JVMTI
#ifdef AMD64
- const static int InterpreterCodeSize = 200 * 1024;
+ const static int InterpreterCodeSize = 208 * 1024;
#else
- const static int InterpreterCodeSize = 168 * 1024;
+ const static int InterpreterCodeSize = 176 * 1024;
#endif // AMD64
#endif // CPU_X86_VM_TEMPLATEINTERPRETER_X86_HPP
diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp
index 518da23eb60..5f5f94f41a5 100644
--- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp
@@ -211,11 +211,11 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
if (is_vtable_stub) {
// Vtable stub size
return (DebugVtables ? 512 : 24) + (CountCompiledCalls ? 13 : 0) +
- (UseCompressedKlassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
+ (UseCompressedClassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
} else {
// Itable stub size
return (DebugVtables ? 512 : 74) + (CountCompiledCalls ? 13 : 0) +
- (UseCompressedKlassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
+ (UseCompressedClassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
}
// In order to tune these parameters, run the JVM with VM options
// +PrintMiscellaneous and +WizardMode to see information about
diff --git a/hotspot/src/cpu/x86/vm/x86_64.ad b/hotspot/src/cpu/x86/vm/x86_64.ad
index f550208e94d..ed13b3da1d1 100644
--- a/hotspot/src/cpu/x86/vm/x86_64.ad
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad
@@ -1391,7 +1391,7 @@ uint BoxLockNode::size(PhaseRegAlloc *ra_) const
#ifndef PRODUCT
void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
{
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check");
@@ -1408,7 +1408,7 @@ void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
{
MacroAssembler masm(&cbuf);
uint insts_size = cbuf.insts_size();
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
masm.load_klass(rscratch1, j_rarg0);
masm.cmpptr(rax, rscratch1);
} else {
@@ -1557,7 +1557,7 @@ bool Matcher::narrow_oop_use_complex_address() {
}
bool Matcher::narrow_klass_use_complex_address() {
- assert(UseCompressedKlassPointers, "only for compressed klass code");
+ assert(UseCompressedClassPointers, "only for compressed klass code");
return (LogKlassAlignmentInBytes <= 3);
}
diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp
index 6b636d379de..58c961b43eb 100644
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp
@@ -3589,8 +3589,6 @@ jint os::init_2(void)
#endif
}
- os::large_page_init();
-
// initialize suspend/resume support - must do this before signal_sets_init()
if (SR_initialize() != 0) {
perror("SR_initialize failed");
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
index 70837a850d8..6c794793cfe 100644
--- a/hotspot/src/os/linux/vm/os_linux.cpp
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
@@ -131,6 +131,7 @@ bool os::Linux::_is_NPTL = false;
bool os::Linux::_supports_fast_thread_cpu_time = false;
const char * os::Linux::_glibc_version = NULL;
const char * os::Linux::_libpthread_version = NULL;
+pthread_condattr_t os::Linux::_condattr[1];
static jlong initial_time_count=0;
@@ -1399,12 +1400,15 @@ void os::Linux::clock_init() {
clock_gettime_func(CLOCK_MONOTONIC, &tp) == 0) {
// yes, monotonic clock is supported
_clock_gettime = clock_gettime_func;
+ return;
} else {
// close librt if there is no monotonic clock
dlclose(handle);
}
}
}
+ warning("No monotonic clock was available - timed services may " \
+ "be adversely affected if the time-of-day clock changes");
}
#ifndef SYS_clock_getres
@@ -2165,23 +2169,49 @@ void os::print_os_info(outputStream* st) {
}
// Try to identify popular distros.
-// Most Linux distributions have /etc/XXX-release file, which contains
-// the OS version string. Some have more than one /etc/XXX-release file
-// (e.g. Mandrake has both /etc/mandrake-release and /etc/redhat-release.),
-// so the order is important.
+// Most Linux distributions have a /etc/XXX-release file, which contains
+// the OS version string. Newer Linux distributions have a /etc/lsb-release
+// file that also contains the OS version string. Some have more than one
+// /etc/XXX-release file (e.g. Mandrake has both /etc/mandrake-release and
+// /etc/redhat-release.), so the order is important.
+// Any Linux that is based on Redhat (i.e. Oracle, Mandrake, Sun JDS...) have
+// their own specific XXX-release file as well as a redhat-release file.
+// Because of this the XXX-release file needs to be searched for before the
+// redhat-release file.
+// Since Red Hat has a lsb-release file that is not very descriptive the
+// search for redhat-release needs to be before lsb-release.
+// Since the lsb-release file is the new standard it needs to be searched
+// before the older style release files.
+// Searching system-release (Red Hat) and os-release (other Linuxes) are a
+// next to last resort. The os-release file is a new standard that contains
+// distribution information and the system-release file seems to be an old
+// standard that has been replaced by the lsb-release and os-release files.
+// Searching for the debian_version file is the last resort. It contains
+// an informative string like "6.0.6" or "wheezy/sid". Because of this
+// "Debian " is printed before the contents of the debian_version file.
void os::Linux::print_distro_info(outputStream* st) {
- if (!_print_ascii_file("/etc/mandrake-release", st) &&
- !_print_ascii_file("/etc/sun-release", st) &&
- !_print_ascii_file("/etc/redhat-release", st) &&
- !_print_ascii_file("/etc/SuSE-release", st) &&
- !_print_ascii_file("/etc/turbolinux-release", st) &&
- !_print_ascii_file("/etc/gentoo-release", st) &&
- !_print_ascii_file("/etc/debian_version", st) &&
- !_print_ascii_file("/etc/ltib-release", st) &&
- !_print_ascii_file("/etc/angstrom-version", st)) {
- st->print("Linux");
- }
- st->cr();
+ if (!_print_ascii_file("/etc/oracle-release", st) &&
+ !_print_ascii_file("/etc/mandriva-release", st) &&
+ !_print_ascii_file("/etc/mandrake-release", st) &&
+ !_print_ascii_file("/etc/sun-release", st) &&
+ !_print_ascii_file("/etc/redhat-release", st) &&
+ !_print_ascii_file("/etc/lsb-release", st) &&
+ !_print_ascii_file("/etc/SuSE-release", st) &&
+ !_print_ascii_file("/etc/turbolinux-release", st) &&
+ !_print_ascii_file("/etc/gentoo-release", st) &&
+ !_print_ascii_file("/etc/ltib-release", st) &&
+ !_print_ascii_file("/etc/angstrom-version", st) &&
+ !_print_ascii_file("/etc/system-release", st) &&
+ !_print_ascii_file("/etc/os-release", st)) {
+
+ if (file_exists("/etc/debian_version")) {
+ st->print("Debian ");
+ _print_ascii_file("/etc/debian_version", st);
+ } else {
+ st->print("Linux");
+ }
+ }
+ st->cr();
}
void os::Linux::print_libversion_info(outputStream* st) {
@@ -4709,6 +4739,26 @@ void os::init(void) {
Linux::clock_init();
initial_time_count = os::elapsed_counter();
+
+ // pthread_condattr initialization for monotonic clock
+ int status;
+ pthread_condattr_t* _condattr = os::Linux::condAttr();
+ if ((status = pthread_condattr_init(_condattr)) != 0) {
+ fatal(err_msg("pthread_condattr_init: %s", strerror(status)));
+ }
+ // Only set the clock if CLOCK_MONOTONIC is available
+ if (Linux::supports_monotonic_clock()) {
+ if ((status = pthread_condattr_setclock(_condattr, CLOCK_MONOTONIC)) != 0) {
+ if (status == EINVAL) {
+ warning("Unable to use monotonic clock with relative timed-waits" \
+ " - changes to the time-of-day clock may have adverse affects");
+ } else {
+ fatal(err_msg("pthread_condattr_setclock: %s", strerror(status)));
+ }
+ }
+ }
+ // else it defaults to CLOCK_REALTIME
+
pthread_mutex_init(&dl_mutex, NULL);
// If the pagesize of the VM is greater than 8K determine the appropriate
@@ -4755,8 +4805,6 @@ jint os::init_2(void)
#endif
}
- os::large_page_init();
-
// initialize suspend/resume support - must do this before signal_sets_init()
if (SR_initialize() != 0) {
perror("SR_initialize failed");
@@ -5519,21 +5567,36 @@ void os::pause() {
static struct timespec* compute_abstime(timespec* abstime, jlong millis) {
if (millis < 0) millis = 0;
- struct timeval now;
- int status = gettimeofday(&now, NULL);
- assert(status == 0, "gettimeofday");
+
jlong seconds = millis / 1000;
millis %= 1000;
if (seconds > 50000000) { // see man cond_timedwait(3T)
seconds = 50000000;
}
- abstime->tv_sec = now.tv_sec + seconds;
- long usec = now.tv_usec + millis * 1000;
- if (usec >= 1000000) {
- abstime->tv_sec += 1;
- usec -= 1000000;
+
+ if (os::Linux::supports_monotonic_clock()) {
+ struct timespec now;
+ int status = os::Linux::clock_gettime(CLOCK_MONOTONIC, &now);
+ assert_status(status == 0, status, "clock_gettime");
+ abstime->tv_sec = now.tv_sec + seconds;
+ long nanos = now.tv_nsec + millis * NANOSECS_PER_MILLISEC;
+ if (nanos >= NANOSECS_PER_SEC) {
+ abstime->tv_sec += 1;
+ nanos -= NANOSECS_PER_SEC;
+ }
+ abstime->tv_nsec = nanos;
+ } else {
+ struct timeval now;
+ int status = gettimeofday(&now, NULL);
+ assert(status == 0, "gettimeofday");
+ abstime->tv_sec = now.tv_sec + seconds;
+ long usec = now.tv_usec + millis * 1000;
+ if (usec >= 1000000) {
+ abstime->tv_sec += 1;
+ usec -= 1000000;
+ }
+ abstime->tv_nsec = usec * 1000;
}
- abstime->tv_nsec = usec * 1000;
return abstime;
}
@@ -5625,7 +5688,7 @@ int os::PlatformEvent::park(jlong millis) {
status = os::Linux::safe_cond_timedwait(_cond, _mutex, &abst);
if (status != 0 && WorkAroundNPTLTimedWaitHang) {
pthread_cond_destroy (_cond);
- pthread_cond_init (_cond, NULL) ;
+ pthread_cond_init (_cond, os::Linux::condAttr()) ;
}
assert_status(status == 0 || status == EINTR ||
status == ETIME || status == ETIMEDOUT,
@@ -5726,32 +5789,50 @@ void os::PlatformEvent::unpark() {
static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) {
assert (time > 0, "convertTime");
+ time_t max_secs = 0;
- struct timeval now;
- int status = gettimeofday(&now, NULL);
- assert(status == 0, "gettimeofday");
+ if (!os::Linux::supports_monotonic_clock() || isAbsolute) {
+ struct timeval now;
+ int status = gettimeofday(&now, NULL);
+ assert(status == 0, "gettimeofday");
- time_t max_secs = now.tv_sec + MAX_SECS;
+ max_secs = now.tv_sec + MAX_SECS;
- if (isAbsolute) {
- jlong secs = time / 1000;
- if (secs > max_secs) {
- absTime->tv_sec = max_secs;
+ if (isAbsolute) {
+ jlong secs = time / 1000;
+ if (secs > max_secs) {
+ absTime->tv_sec = max_secs;
+ } else {
+ absTime->tv_sec = secs;
+ }
+ absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC;
+ } else {
+ jlong secs = time / NANOSECS_PER_SEC;
+ if (secs >= MAX_SECS) {
+ absTime->tv_sec = max_secs;
+ absTime->tv_nsec = 0;
+ } else {
+ absTime->tv_sec = now.tv_sec + secs;
+ absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000;
+ if (absTime->tv_nsec >= NANOSECS_PER_SEC) {
+ absTime->tv_nsec -= NANOSECS_PER_SEC;
+ ++absTime->tv_sec; // note: this must be <= max_secs
+ }
+ }
}
- else {
- absTime->tv_sec = secs;
- }
- absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC;
- }
- else {
+ } else {
+ // must be relative using monotonic clock
+ struct timespec now;
+ int status = os::Linux::clock_gettime(CLOCK_MONOTONIC, &now);
+ assert_status(status == 0, status, "clock_gettime");
+ max_secs = now.tv_sec + MAX_SECS;
jlong secs = time / NANOSECS_PER_SEC;
if (secs >= MAX_SECS) {
absTime->tv_sec = max_secs;
absTime->tv_nsec = 0;
- }
- else {
+ } else {
absTime->tv_sec = now.tv_sec + secs;
- absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000;
+ absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_nsec;
if (absTime->tv_nsec >= NANOSECS_PER_SEC) {
absTime->tv_nsec -= NANOSECS_PER_SEC;
++absTime->tv_sec; // note: this must be <= max_secs
@@ -5831,15 +5912,19 @@ void Parker::park(bool isAbsolute, jlong time) {
jt->set_suspend_equivalent();
// cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
+ assert(_cur_index == -1, "invariant");
if (time == 0) {
- status = pthread_cond_wait (_cond, _mutex) ;
+ _cur_index = REL_INDEX; // arbitrary choice when not timed
+ status = pthread_cond_wait (&_cond[_cur_index], _mutex) ;
} else {
- status = os::Linux::safe_cond_timedwait (_cond, _mutex, &absTime) ;
+ _cur_index = isAbsolute ? ABS_INDEX : REL_INDEX;
+ status = os::Linux::safe_cond_timedwait (&_cond[_cur_index], _mutex, &absTime) ;
if (status != 0 && WorkAroundNPTLTimedWaitHang) {
- pthread_cond_destroy (_cond) ;
- pthread_cond_init (_cond, NULL);
+ pthread_cond_destroy (&_cond[_cur_index]) ;
+ pthread_cond_init (&_cond[_cur_index], isAbsolute ? NULL : os::Linux::condAttr());
}
}
+ _cur_index = -1;
assert_status(status == 0 || status == EINTR ||
status == ETIME || status == ETIMEDOUT,
status, "cond_timedwait");
@@ -5868,17 +5953,24 @@ void Parker::unpark() {
s = _counter;
_counter = 1;
if (s < 1) {
- if (WorkAroundNPTLTimedWaitHang) {
- status = pthread_cond_signal (_cond) ;
- assert (status == 0, "invariant") ;
+ // thread might be parked
+ if (_cur_index != -1) {
+ // thread is definitely parked
+ if (WorkAroundNPTLTimedWaitHang) {
+ status = pthread_cond_signal (&_cond[_cur_index]);
+ assert (status == 0, "invariant");
status = pthread_mutex_unlock(_mutex);
- assert (status == 0, "invariant") ;
- } else {
+ assert (status == 0, "invariant");
+ } else {
status = pthread_mutex_unlock(_mutex);
- assert (status == 0, "invariant") ;
- status = pthread_cond_signal (_cond) ;
- assert (status == 0, "invariant") ;
- }
+ assert (status == 0, "invariant");
+ status = pthread_cond_signal (&_cond[_cur_index]);
+ assert (status == 0, "invariant");
+ }
+ } else {
+ pthread_mutex_unlock(_mutex);
+ assert (status == 0, "invariant") ;
+ }
} else {
pthread_mutex_unlock(_mutex);
assert (status == 0, "invariant") ;
diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp
index c824e8ad3fe..5eed54f8c1e 100644
--- a/hotspot/src/os/linux/vm/os_linux.hpp
+++ b/hotspot/src/os/linux/vm/os_linux.hpp
@@ -221,6 +221,13 @@ class Linux {
static jlong fast_thread_cpu_time(clockid_t clockid);
+ // pthread_cond clock suppport
+ private:
+ static pthread_condattr_t _condattr[1];
+
+ public:
+ static pthread_condattr_t* condAttr() { return _condattr; }
+
// Stack repair handling
// none present
@@ -295,7 +302,7 @@ class PlatformEvent : public CHeapObj {
public:
PlatformEvent() {
int status;
- status = pthread_cond_init (_cond, NULL);
+ status = pthread_cond_init (_cond, os::Linux::condAttr());
assert_status(status == 0, status, "cond_init");
status = pthread_mutex_init (_mutex, NULL);
assert_status(status == 0, status, "mutex_init");
@@ -310,14 +317,19 @@ class PlatformEvent : public CHeapObj {
void park () ;
void unpark () ;
int TryPark () ;
- int park (jlong millis) ;
+ int park (jlong millis) ; // relative timed-wait only
void SetAssociation (Thread * a) { _Assoc = a ; }
} ;
class PlatformParker : public CHeapObj {
protected:
+ enum {
+ REL_INDEX = 0,
+ ABS_INDEX = 1
+ };
+ int _cur_index; // which cond is in use: -1, 0, 1
pthread_mutex_t _mutex [1] ;
- pthread_cond_t _cond [1] ;
+ pthread_cond_t _cond [2] ; // one for relative times and one for abs.
public: // TODO-FIXME: make dtor private
~PlatformParker() { guarantee (0, "invariant") ; }
@@ -325,10 +337,13 @@ class PlatformParker : public CHeapObj {
public:
PlatformParker() {
int status;
- status = pthread_cond_init (_cond, NULL);
- assert_status(status == 0, status, "cond_init");
+ status = pthread_cond_init (&_cond[REL_INDEX], os::Linux::condAttr());
+ assert_status(status == 0, status, "cond_init rel");
+ status = pthread_cond_init (&_cond[ABS_INDEX], NULL);
+ assert_status(status == 0, status, "cond_init abs");
status = pthread_mutex_init (_mutex, NULL);
assert_status(status == 0, status, "mutex_init");
+ _cur_index = -1; // mark as unused
}
};
diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp
index c3e6e879077..8e5984ffa3d 100644
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp
@@ -5178,9 +5178,7 @@ jint os::init_2(void) {
if(Verbose && PrintMiscellaneous)
tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
#endif
-}
-
- os::large_page_init();
+ }
// Check minimum allowable stack size for thread creation and to initialize
// the java system classes, including StackOverflowError - depends on page
diff --git a/hotspot/src/os/windows/vm/decoder_windows.cpp b/hotspot/src/os/windows/vm/decoder_windows.cpp
index 326d3288020..b99adaa9f4f 100644
--- a/hotspot/src/os/windows/vm/decoder_windows.cpp
+++ b/hotspot/src/os/windows/vm/decoder_windows.cpp
@@ -32,7 +32,11 @@ WindowsDecoder::WindowsDecoder() {
_can_decode_in_vm = false;
_pfnSymGetSymFromAddr64 = NULL;
_pfnUndecorateSymbolName = NULL;
-
+#ifdef AMD64
+ _pfnStackWalk64 = NULL;
+ _pfnSymFunctionTableAccess64 = NULL;
+ _pfnSymGetModuleBase64 = NULL;
+#endif
_decoder_status = no_error;
initialize();
}
@@ -53,14 +57,24 @@ void WindowsDecoder::initialize() {
_pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)::GetProcAddress(handle, "UnDecorateSymbolName");
if (_pfnSymSetOptions == NULL || _pfnSymInitialize == NULL || _pfnSymGetSymFromAddr64 == NULL) {
- _pfnSymGetSymFromAddr64 = NULL;
- _pfnUndecorateSymbolName = NULL;
- ::FreeLibrary(handle);
- _dbghelp_handle = NULL;
+ uninitialize();
_decoder_status = helper_func_error;
return;
}
+#ifdef AMD64
+ _pfnStackWalk64 = (pfn_StackWalk64)::GetProcAddress(handle, "StackWalk64");
+ _pfnSymFunctionTableAccess64 = (pfn_SymFunctionTableAccess64)::GetProcAddress(handle, "SymFunctionTableAccess64");
+ _pfnSymGetModuleBase64 = (pfn_SymGetModuleBase64)::GetProcAddress(handle, "SymGetModuleBase64");
+ if (_pfnStackWalk64 == NULL || _pfnSymFunctionTableAccess64 == NULL || _pfnSymGetModuleBase64 == NULL) {
+ // We can't call StackWalk64 to walk the stack, but we are still
+ // able to decode the symbols. Let's limp on.
+ _pfnStackWalk64 = NULL;
+ _pfnSymFunctionTableAccess64 = NULL;
+ _pfnSymGetModuleBase64 = NULL;
+ }
+#endif
+
HANDLE hProcess = ::GetCurrentProcess();
_pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_EXACT_SYMBOLS);
if (!_pfnSymInitialize(hProcess, NULL, TRUE)) {
@@ -156,6 +170,11 @@ void WindowsDecoder::initialize() {
void WindowsDecoder::uninitialize() {
_pfnSymGetSymFromAddr64 = NULL;
_pfnUndecorateSymbolName = NULL;
+#ifdef AMD64
+ _pfnStackWalk64 = NULL;
+ _pfnSymFunctionTableAccess64 = NULL;
+ _pfnSymGetModuleBase64 = NULL;
+#endif
if (_dbghelp_handle != NULL) {
::FreeLibrary(_dbghelp_handle);
}
@@ -195,3 +214,65 @@ bool WindowsDecoder::demangle(const char* symbol, char *buf, int buflen) {
_pfnUndecorateSymbolName(symbol, buf, buflen, UNDNAME_COMPLETE);
}
+#ifdef AMD64
+BOOL WindowsDbgHelp::StackWalk64(DWORD MachineType,
+ HANDLE hProcess,
+ HANDLE hThread,
+ LPSTACKFRAME64 StackFrame,
+ PVOID ContextRecord,
+ PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
+ PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
+ PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
+ PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress) {
+ DecoderLocker locker;
+ WindowsDecoder* wd = (WindowsDecoder*)locker.decoder();
+
+ if (!wd->has_error() && wd->_pfnStackWalk64) {
+ return wd->_pfnStackWalk64(MachineType,
+ hProcess,
+ hThread,
+ StackFrame,
+ ContextRecord,
+ ReadMemoryRoutine,
+ FunctionTableAccessRoutine,
+ GetModuleBaseRoutine,
+ TranslateAddress);
+ } else {
+ return false;
+ }
+}
+
+PVOID WindowsDbgHelp::SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase) {
+ DecoderLocker locker;
+ WindowsDecoder* wd = (WindowsDecoder*)locker.decoder();
+
+ if (!wd->has_error() && wd->_pfnSymFunctionTableAccess64) {
+ return wd->_pfnSymFunctionTableAccess64(hProcess, AddrBase);
+ } else {
+ return NULL;
+ }
+}
+
+pfn_SymFunctionTableAccess64 WindowsDbgHelp::pfnSymFunctionTableAccess64() {
+ DecoderLocker locker;
+ WindowsDecoder* wd = (WindowsDecoder*)locker.decoder();
+
+ if (!wd->has_error()) {
+ return wd->_pfnSymFunctionTableAccess64;
+ } else {
+ return NULL;
+ }
+}
+
+pfn_SymGetModuleBase64 WindowsDbgHelp::pfnSymGetModuleBase64() {
+ DecoderLocker locker;
+ WindowsDecoder* wd = (WindowsDecoder*)locker.decoder();
+
+ if (!wd->has_error()) {
+ return wd->_pfnSymGetModuleBase64;
+ } else {
+ return NULL;
+ }
+}
+
+#endif // AMD64
diff --git a/hotspot/src/os/windows/vm/decoder_windows.hpp b/hotspot/src/os/windows/vm/decoder_windows.hpp
index 3008ee79136..2555e8c9b79 100644
--- a/hotspot/src/os/windows/vm/decoder_windows.hpp
+++ b/hotspot/src/os/windows/vm/decoder_windows.hpp
@@ -38,6 +38,20 @@ typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWOR
typedef BOOL (WINAPI *pfn_SymSetSearchPath)(HANDLE, PCTSTR);
typedef BOOL (WINAPI *pfn_SymGetSearchPath)(HANDLE, PTSTR, int);
+#ifdef AMD64
+typedef BOOL (WINAPI *pfn_StackWalk64)(DWORD MachineType,
+ HANDLE hProcess,
+ HANDLE hThread,
+ LPSTACKFRAME64 StackFrame,
+ PVOID ContextRecord,
+ PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
+ PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
+ PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
+ PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
+typedef PVOID (WINAPI *pfn_SymFunctionTableAccess64)(HANDLE hProcess, DWORD64 AddrBase);
+typedef DWORD64 (WINAPI *pfn_SymGetModuleBase64)(HANDLE hProcess, DWORD64 dwAddr);
+#endif
+
class WindowsDecoder : public AbstractDecoder {
public:
@@ -61,7 +75,34 @@ private:
bool _can_decode_in_vm;
pfn_SymGetSymFromAddr64 _pfnSymGetSymFromAddr64;
pfn_UndecorateSymbolName _pfnUndecorateSymbolName;
+#ifdef AMD64
+ pfn_StackWalk64 _pfnStackWalk64;
+ pfn_SymFunctionTableAccess64 _pfnSymFunctionTableAccess64;
+ pfn_SymGetModuleBase64 _pfnSymGetModuleBase64;
+
+ friend class WindowsDbgHelp;
+#endif
};
+#ifdef AMD64
+// TODO: refactor and move the handling of dbghelp.dll outside of Decoder
+class WindowsDbgHelp : public Decoder {
+public:
+ static BOOL StackWalk64(DWORD MachineType,
+ HANDLE hProcess,
+ HANDLE hThread,
+ LPSTACKFRAME64 StackFrame,
+ PVOID ContextRecord,
+ PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
+ PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
+ PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
+ PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
+ static PVOID SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase);
+
+ static pfn_SymFunctionTableAccess64 pfnSymFunctionTableAccess64();
+ static pfn_SymGetModuleBase64 pfnSymGetModuleBase64();
+};
+#endif
+
#endif // OS_WINDOWS_VM_DECODER_WINDOWS_HPP
diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp
index 015f94d6662..7daee35632e 100644
--- a/hotspot/src/os/windows/vm/os_windows.cpp
+++ b/hotspot/src/os/windows/vm/os_windows.cpp
@@ -3189,9 +3189,12 @@ char* os::reserve_memory_special(size_t bytes, size_t alignment, char* addr, boo
return p_buf;
} else {
+ if (TracePageSizes && Verbose) {
+ tty->print_cr("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(NULL, bytes, flag, prot);
+ char * res = (char *)VirtualAlloc(addr, bytes, flag, prot);
if (res != NULL) {
address pc = CALLER_PC;
MemTracker::record_virtual_memory_reserve_and_commit((address)res, bytes, mtNone, pc);
@@ -3917,8 +3920,6 @@ jint os::init_2(void) {
#endif
}
- os::large_page_init();
-
// Setup Windows Exceptions
// for debugging float code generation bugs
@@ -5429,7 +5430,7 @@ char* os::build_agent_function_name(const char *sym_name, const char *lib_name,
if ((start = strrchr(lib_name, *os::file_separator())) != NULL) {
lib_name = ++start;
} else {
- // Need to check for C:
+ // Need to check for drive prefix
if ((start = strchr(lib_name, ':')) != NULL) {
lib_name = ++start;
}
@@ -5714,7 +5715,66 @@ BOOL os::Advapi32Dll::AdvapiAvailable() {
#endif
#ifndef PRODUCT
+
+// test the code path in reserve_memory_special() that tries to allocate memory in a single
+// contiguous memory block at a particular address.
+// The test first tries to find a good approximate address to allocate at by using the same
+// method to allocate some memory at any address. The test then tries to allocate memory in
+// the vicinity (not directly after it to avoid possible by-chance use of that location)
+// This is of course only some dodgy assumption, there is no guarantee that the vicinity of
+// the previously allocated memory is available for allocation. The only actual failure
+// that is reported is when the test tries to allocate at a particular location but gets a
+// different valid one. A NULL return value at this point is not considered an error but may
+// be legitimate.
+// If -XX:+VerboseInternalVMTests is enabled, print some explanatory messages.
void TestReserveMemorySpecial_test() {
- // No tests available for this platform
+ if (!UseLargePages) {
+ if (VerboseInternalVMTests) {
+ gclog_or_tty->print("Skipping test because large pages are disabled");
+ }
+ return;
+ }
+ // save current value of globals
+ bool old_use_large_pages_individual_allocation = UseLargePagesIndividualAllocation;
+ bool old_use_numa_interleaving = UseNUMAInterleaving;
+
+ // set globals to make sure we hit the correct code path
+ UseLargePagesIndividualAllocation = UseNUMAInterleaving = false;
+
+ // do an allocation at an address selected by the OS to get a good one.
+ const size_t large_allocation_size = os::large_page_size() * 4;
+ char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), NULL, false);
+ if (result == NULL) {
+ if (VerboseInternalVMTests) {
+ gclog_or_tty->print("Failed to allocate control block with size "SIZE_FORMAT". Skipping remainder of test.",
+ large_allocation_size);
+ }
+ } else {
+ os::release_memory_special(result, large_allocation_size);
+
+ // allocate another page within the recently allocated memory area which seems to be a good location. At least
+ // we managed to get it once.
+ const size_t expected_allocation_size = os::large_page_size();
+ char* expected_location = result + os::large_page_size();
+ char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), expected_location, false);
+ if (actual_location == NULL) {
+ if (VerboseInternalVMTests) {
+ gclog_or_tty->print("Failed to allocate any memory at "PTR_FORMAT" size "SIZE_FORMAT". Skipping remainder of test.",
+ expected_location, large_allocation_size);
+ }
+ } else {
+ // release memory
+ os::release_memory_special(actual_location, expected_allocation_size);
+ // only now check, after releasing any memory to avoid any leaks.
+ assert(actual_location == expected_location,
+ err_msg("Failed to allocate memory at requested location "PTR_FORMAT" of size "SIZE_FORMAT", is "PTR_FORMAT" instead",
+ expected_location, expected_allocation_size, actual_location));
+ }
+ }
+
+ // restore globals
+ UseLargePagesIndividualAllocation = old_use_large_pages_individual_allocation;
+ UseNUMAInterleaving = old_use_numa_interleaving;
}
-#endif
+#endif // PRODUCT
+
diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp b/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp
index 595cd781447..e0ed6961e3a 100644
--- a/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp
@@ -35,7 +35,9 @@ define_pd_global(intx, CompilerThreadStackSize, 0);
// Used on 64 bit platforms for UseCompressedOops base address
#ifdef _LP64
-define_pd_global(uintx, HeapBaseMinAddress, CONST64(4)*G);
+// use 6G as default base address because by default the OS maps the application
+// to 4G on Solaris-Sparc. This leaves at least 2G for the native heap.
+define_pd_global(uintx, HeapBaseMinAddress, CONST64(6)*G);
#else
define_pd_global(uintx, HeapBaseMinAddress, 2*G);
#endif
diff --git a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
index a0f2a7680be..09735dae0c6 100644
--- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
+++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
@@ -29,6 +29,7 @@
#include "classfile/vmSymbols.hpp"
#include "code/icBuffer.hpp"
#include "code/vtableStubs.hpp"
+#include "decoder_windows.hpp"
#include "interpreter/interpreter.hpp"
#include "jvm_windows.h"
#include "memory/allocation.inline.hpp"
@@ -327,6 +328,94 @@ add_ptr_func_t* os::atomic_add_ptr_func = os::atomic_add_ptr_bootstrap
cmpxchg_long_func_t* os::atomic_cmpxchg_long_func = os::atomic_cmpxchg_long_bootstrap;
+#ifdef AMD64
+/*
+ * Windows/x64 does not use stack frames the way expected by Java:
+ * [1] in most cases, there is no frame pointer. All locals are addressed via RSP
+ * [2] in rare cases, when alloca() is used, a frame pointer is used, but this may
+ * not be RBP.
+ * See http://msdn.microsoft.com/en-us/library/ew5tede7.aspx
+ *
+ * So it's not possible to print the native stack using the
+ * while (...) {... fr = os::get_sender_for_C_frame(&fr); }
+ * loop in vmError.cpp. We need to roll our own loop.
+ */
+bool os::platform_print_native_stack(outputStream* st, void* context,
+ char *buf, int buf_size)
+{
+ CONTEXT ctx;
+ if (context != NULL) {
+ memcpy(&ctx, context, sizeof(ctx));
+ } else {
+ RtlCaptureContext(&ctx);
+ }
+
+ st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)");
+
+ STACKFRAME stk;
+ memset(&stk, 0, sizeof(stk));
+ stk.AddrStack.Offset = ctx.Rsp;
+ stk.AddrStack.Mode = AddrModeFlat;
+ stk.AddrFrame.Offset = ctx.Rbp;
+ stk.AddrFrame.Mode = AddrModeFlat;
+ stk.AddrPC.Offset = ctx.Rip;
+ stk.AddrPC.Mode = AddrModeFlat;
+
+ int count = 0;
+ address lastpc = 0;
+ while (count++ < StackPrintLimit) {
+ intptr_t* sp = (intptr_t*)stk.AddrStack.Offset;
+ intptr_t* fp = (intptr_t*)stk.AddrFrame.Offset; // NOT necessarily the same as ctx.Rbp!
+ address pc = (address)stk.AddrPC.Offset;
+
+ if (pc != NULL && sp != NULL && fp != NULL) {
+ if (count == 2 && lastpc == pc) {
+ // Skip it -- StackWalk64() may return the same PC
+ // (but different SP) on the first try.
+ } else {
+ // Don't try to create a frame(sp, fp, pc) -- on WinX64, stk.AddrFrame
+ // may not contain what Java expects, and may cause the frame() constructor
+ // to crash. Let's just print out the symbolic address.
+ frame::print_C_frame(st, buf, buf_size, pc);
+ st->cr();
+ }
+ lastpc = pc;
+ } else {
+ break;
+ }
+
+ PVOID p = WindowsDbgHelp::SymFunctionTableAccess64(GetCurrentProcess(), stk.AddrPC.Offset);
+ if (!p) {
+ // StackWalk64() can't handle this PC. Calling StackWalk64 again may cause crash.
+ break;
+ }
+
+ BOOL result = WindowsDbgHelp::StackWalk64(
+ IMAGE_FILE_MACHINE_AMD64, // __in DWORD MachineType,
+ GetCurrentProcess(), // __in HANDLE hProcess,
+ GetCurrentThread(), // __in HANDLE hThread,
+ &stk, // __inout LP STACKFRAME64 StackFrame,
+ &ctx, // __inout PVOID ContextRecord,
+ NULL, // __in_opt PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
+ WindowsDbgHelp::pfnSymFunctionTableAccess64(),
+ // __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
+ WindowsDbgHelp::pfnSymGetModuleBase64(),
+ // __in_opt PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
+ NULL); // __in_opt PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress
+
+ if (!result) {
+ break;
+ }
+ }
+ if (count > StackPrintLimit) {
+ st->print_cr("......");
+ }
+ st->cr();
+
+ return true;
+}
+#endif // AMD64
+
ExtendedPC os::fetch_frame_from_context(void* ucVoid,
intptr_t** ret_sp, intptr_t** ret_fp) {
@@ -401,6 +490,9 @@ frame os::current_frame() {
StubRoutines::x86::get_previous_fp_entry());
if (func == NULL) return frame();
intptr_t* fp = (*func)();
+ if (fp == NULL) {
+ return frame();
+ }
#else
intptr_t* fp = _get_previous_fp();
#endif // AMD64
diff --git a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.hpp b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.hpp
index 41814b6c61b..22ffeb5dc34 100644
--- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.hpp
+++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.hpp
@@ -62,4 +62,10 @@
static bool register_code_area(char *low, char *high);
+#ifdef AMD64
+#define PLATFORM_PRINT_NATIVE_STACK 1
+static bool platform_print_native_stack(outputStream* st, void* context,
+ char *buf, int buf_size);
+#endif
+
#endif // OS_CPU_WINDOWS_X86_VM_OS_WINDOWS_X86_HPP
diff --git a/hotspot/src/share/tools/LogCompilation/README b/hotspot/src/share/tools/LogCompilation/README
index 90dc3b893bb..aa18fe891f6 100644
--- a/hotspot/src/share/tools/LogCompilation/README
+++ b/hotspot/src/share/tools/LogCompilation/README
@@ -4,14 +4,14 @@ It's main purpose is to recreate output similar to
requires a 1.5 JDK to build and simply typing make should build it.
It produces a jar file, logc.jar, that can be run on the
-hotspot.log from LogCompilation output like this:
+HotSpot log (by default, hotspot_pid{pid}.log) from LogCompilation output like this:
- java -jar logc.jar hotspot.log
+ java -jar logc.jar hotspot_pid1234.log
This will produce something like the normal PrintCompilation output.
Adding the -i option with also report inlining like PrintInlining.
-More information about the LogCompilation output can be found at
+More information about the LogCompilation output can be found at
https://wikis.oracle.com/display/HotSpotInternals/LogCompilation+overview
https://wikis.oracle.com/display/HotSpotInternals/PrintCompilation
diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp
index 037bc31f658..080eaf67088 100644
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp
@@ -709,10 +709,10 @@ static Klass* resolve_field_return_klass(methodHandle caller, int bci, TRAPS) {
Bytecodes::Code code = field_access.code();
// We must load class, initialize class and resolvethe field
- FieldAccessInfo result; // initialize class if needed
+ fieldDescriptor result; // initialize class if needed
constantPoolHandle constants(THREAD, caller->constants());
- LinkResolver::resolve_field(result, constants, field_access.index(), Bytecodes::java_code(code), false, CHECK_NULL);
- return result.klass()();
+ LinkResolver::resolve_field_access(result, constants, field_access.index(), Bytecodes::java_code(code), CHECK_NULL);
+ return result.field_holder();
}
@@ -826,11 +826,11 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i
if (stub_id == Runtime1::access_field_patching_id) {
Bytecode_field field_access(caller_method, bci);
- FieldAccessInfo result; // initialize class if needed
+ fieldDescriptor result; // initialize class if needed
Bytecodes::Code code = field_access.code();
constantPoolHandle constants(THREAD, caller_method->constants());
- LinkResolver::resolve_field(result, constants, field_access.index(), Bytecodes::java_code(code), false, CHECK);
- patch_field_offset = result.field_offset();
+ LinkResolver::resolve_field_access(result, constants, field_access.index(), Bytecodes::java_code(code), CHECK);
+ patch_field_offset = result.offset();
// If we're patching a field which is volatile then at compile it
// must not have been know to be volatile, so the generated code
diff --git a/hotspot/src/share/vm/ci/ciArray.cpp b/hotspot/src/share/vm/ci/ciArray.cpp
index 584b1aeb50f..fdcc63a0dec 100644
--- a/hotspot/src/share/vm/ci/ciArray.cpp
+++ b/hotspot/src/share/vm/ci/ciArray.cpp
@@ -24,13 +24,92 @@
#include "precompiled.hpp"
#include "ci/ciArray.hpp"
+#include "ci/ciArrayKlass.hpp"
+#include "ci/ciConstant.hpp"
#include "ci/ciKlass.hpp"
#include "ci/ciUtilities.hpp"
+#include "oops/objArrayOop.hpp"
+#include "oops/typeArrayOop.hpp"
// ciArray
//
// This class represents an arrayOop in the HotSpot virtual
// machine.
+static BasicType fixup_element_type(BasicType bt) {
+ if (bt == T_ARRAY) return T_OBJECT;
+ if (bt == T_BOOLEAN) return T_BYTE;
+ return bt;
+}
+
+ciConstant ciArray::element_value_impl(BasicType elembt,
+ arrayOop ary,
+ int index) {
+ if (ary == NULL)
+ return ciConstant();
+ assert(ary->is_array(), "");
+ if (index < 0 || index >= ary->length())
+ return ciConstant();
+ ArrayKlass* ak = (ArrayKlass*) ary->klass();
+ BasicType abt = ak->element_type();
+ if (fixup_element_type(elembt) !=
+ fixup_element_type(abt))
+ return ciConstant();
+ switch (elembt) {
+ case T_ARRAY:
+ case T_OBJECT:
+ {
+ assert(ary->is_objArray(), "");
+ objArrayOop objary = (objArrayOop) ary;
+ oop elem = objary->obj_at(index);
+ ciEnv* env = CURRENT_ENV;
+ ciObject* box = env->get_object(elem);
+ return ciConstant(T_OBJECT, box);
+ }
+ }
+ assert(ary->is_typeArray(), "");
+ typeArrayOop tary = (typeArrayOop) ary;
+ jint value = 0;
+ switch (elembt) {
+ case T_LONG: return ciConstant(tary->long_at(index));
+ case T_FLOAT: return ciConstant(tary->float_at(index));
+ case T_DOUBLE: return ciConstant(tary->double_at(index));
+ default: return ciConstant();
+ case T_BYTE: value = tary->byte_at(index); break;
+ case T_BOOLEAN: value = tary->byte_at(index) & 1; break;
+ case T_SHORT: value = tary->short_at(index); break;
+ case T_CHAR: value = tary->char_at(index); break;
+ case T_INT: value = tary->int_at(index); break;
+ }
+ return ciConstant(elembt, value);
+}
+
+// ------------------------------------------------------------------
+// ciArray::element_value
+//
+// Current value of an element.
+// Returns T_ILLEGAL if there is no element at the given index.
+ciConstant ciArray::element_value(int index) {
+ BasicType elembt = element_basic_type();
+ GUARDED_VM_ENTRY(
+ return element_value_impl(elembt, get_arrayOop(), index);
+ )
+}
+
+// ------------------------------------------------------------------
+// ciArray::element_value_by_offset
+//
+// Current value of an element at the specified offset.
+// Returns T_ILLEGAL if there is no element at the given offset.
+ciConstant ciArray::element_value_by_offset(intptr_t element_offset) {
+ BasicType elembt = element_basic_type();
+ intptr_t shift = exact_log2(type2aelembytes(elembt));
+ intptr_t header = arrayOopDesc::base_offset_in_bytes(elembt);
+ intptr_t index = (element_offset - header) >> shift;
+ intptr_t offset = header + ((intptr_t)index << shift);
+ if (offset != element_offset || index != (jint)index)
+ return ciConstant();
+ return element_value((jint) index);
+}
// ------------------------------------------------------------------
// ciArray::print_impl
diff --git a/hotspot/src/share/vm/ci/ciArray.hpp b/hotspot/src/share/vm/ci/ciArray.hpp
index 440e407a510..c5c86265d61 100644
--- a/hotspot/src/share/vm/ci/ciArray.hpp
+++ b/hotspot/src/share/vm/ci/ciArray.hpp
@@ -25,6 +25,8 @@
#ifndef SHARE_VM_CI_CIARRAY_HPP
#define SHARE_VM_CI_CIARRAY_HPP
+#include "ci/ciArrayKlass.hpp"
+#include "ci/ciConstant.hpp"
#include "ci/ciObject.hpp"
#include "oops/arrayOop.hpp"
#include "oops/objArrayOop.hpp"
@@ -45,15 +47,30 @@ protected:
ciArray(ciKlass* klass, int len) : ciObject(klass), _length(len) {}
- arrayOop get_arrayOop() { return (arrayOop)get_oop(); }
+ arrayOop get_arrayOop() const { return (arrayOop)get_oop(); }
const char* type_string() { return "ciArray"; }
void print_impl(outputStream* st);
+ ciConstant element_value_impl(BasicType elembt, arrayOop ary, int index);
+
public:
int length() { return _length; }
+ // Convenience routines.
+ ciArrayKlass* array_type() { return klass()->as_array_klass(); }
+ ciType* element_type() { return array_type()->element_type(); }
+ BasicType element_basic_type() { return element_type()->basic_type(); }
+
+ // Current value of an element.
+ // Returns T_ILLEGAL if there is no element at the given index.
+ ciConstant element_value(int index);
+
+ // Current value of an element at the specified offset.
+ // Returns T_ILLEGAL if there is no element at the given offset.
+ ciConstant element_value_by_offset(intptr_t element_offset);
+
// What kind of ciObject is this?
bool is_array() { return true; }
bool is_java_object() { return true; }
diff --git a/hotspot/src/share/vm/ci/ciConstant.hpp b/hotspot/src/share/vm/ci/ciConstant.hpp
index 8cdc893fd2b..7a72a7de1e5 100644
--- a/hotspot/src/share/vm/ci/ciConstant.hpp
+++ b/hotspot/src/share/vm/ci/ciConstant.hpp
@@ -41,7 +41,6 @@ private:
union {
jint _int;
jlong _long;
- jint _long_half[2];
jfloat _float;
jdouble _double;
ciObject* _object;
@@ -111,6 +110,20 @@ public:
return _value._object;
}
+ bool is_null_or_zero() const {
+ if (!is_java_primitive(basic_type())) {
+ return as_object()->is_null_object();
+ } else if (type2size[basic_type()] == 1) {
+ // treat float bits as int, to avoid comparison with -0 and NaN
+ return (_value._int == 0);
+ } else if (type2size[basic_type()] == 2) {
+ // treat double bits as long, to avoid comparison with -0 and NaN
+ return (_value._long == 0);
+ } else {
+ return false;
+ }
+ }
+
// Debugging output
void print();
};
diff --git a/hotspot/src/share/vm/ci/ciField.cpp b/hotspot/src/share/vm/ci/ciField.cpp
index fe967554c3a..b08ec3616fa 100644
--- a/hotspot/src/share/vm/ci/ciField.cpp
+++ b/hotspot/src/share/vm/ci/ciField.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -75,7 +75,6 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with_put(NUL
assert(klass->get_instanceKlass()->is_linked(), "must be linked before using its constan-pool");
- _cp_index = index;
constantPoolHandle cpool(thread, klass->get_instanceKlass()->constants());
// Get the field's name, signature, and type.
@@ -116,7 +115,7 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with_put(NUL
// The declared holder of this field may not have been loaded.
// Bail out with partial field information.
if (!holder_is_accessible) {
- // _cp_index and _type have already been set.
+ // _type has already been set.
// The default values for _flags and _constant_value will suffice.
// We need values for _holder, _offset, and _is_constant,
_holder = declared_holder;
@@ -146,8 +145,6 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with_put(NUL
ciField::ciField(fieldDescriptor *fd): _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) {
ASSERT_IN_VM;
- _cp_index = -1;
-
// Get the field's name, signature, and type.
ciEnv* env = CURRENT_ENV;
_name = env->get_symbol(fd->name());
@@ -189,12 +186,14 @@ void ciField::initialize_from(fieldDescriptor* fd) {
_holder = CURRENT_ENV->get_instance_klass(fd->field_holder());
// Check to see if the field is constant.
- if (_holder->is_initialized() && this->is_final()) {
+ bool is_final = this->is_final();
+ bool is_stable = FoldStableValues && this->is_stable();
+ if (_holder->is_initialized() && (is_final || is_stable)) {
if (!this->is_static()) {
// A field can be constant if it's a final static field or if
// it's a final non-static field of a trusted class (classes in
// java.lang.invoke and sun.invoke packages and subpackages).
- if (trust_final_non_static_fields(_holder)) {
+ if (is_stable || trust_final_non_static_fields(_holder)) {
_is_constant = true;
return;
}
@@ -227,7 +226,6 @@ void ciField::initialize_from(fieldDescriptor* fd) {
Handle mirror = k->java_mirror();
- _is_constant = true;
switch(type()->basic_type()) {
case T_BYTE:
_constant_value = ciConstant(type()->basic_type(), mirror->byte_field(_offset));
@@ -273,6 +271,12 @@ void ciField::initialize_from(fieldDescriptor* fd) {
}
}
}
+ if (is_stable && _constant_value.is_null_or_zero()) {
+ // It is not a constant after all; treat it as uninitialized.
+ _is_constant = false;
+ } else {
+ _is_constant = true;
+ }
} else {
_is_constant = false;
}
@@ -344,12 +348,11 @@ bool ciField::will_link(ciInstanceKlass* accessing_klass,
}
}
- FieldAccessInfo result;
- constantPoolHandle c_pool(THREAD,
- accessing_klass->get_instanceKlass()->constants());
- LinkResolver::resolve_field(result, c_pool, _cp_index,
- Bytecodes::java_code(bc),
- true, false, KILL_COMPILE_ON_FATAL_(false));
+ fieldDescriptor result;
+ LinkResolver::resolve_field(result, _holder->get_instanceKlass(),
+ _name->get_symbol(), _signature->get_symbol(),
+ accessing_klass->get_Klass(), bc, true, false,
+ KILL_COMPILE_ON_FATAL_(false));
// update the hit-cache, unless there is a problem with memory scoping:
if (accessing_klass->is_shared() || !is_shared()) {
@@ -373,8 +376,11 @@ void ciField::print() {
tty->print(" signature=");
_signature->print_symbol();
tty->print(" offset=%d type=", _offset);
- if (_type != NULL) _type->print_name();
- else tty->print("(reference)");
+ if (_type != NULL)
+ _type->print_name();
+ else
+ tty->print("(reference)");
+ tty->print(" flags=%04x", flags().as_int());
tty->print(" is_constant=%s", bool_to_str(_is_constant));
if (_is_constant && is_static()) {
tty->print(" constant_value=");
diff --git a/hotspot/src/share/vm/ci/ciField.hpp b/hotspot/src/share/vm/ci/ciField.hpp
index ff96c99313c..75263e3f217 100644
--- a/hotspot/src/share/vm/ci/ciField.hpp
+++ b/hotspot/src/share/vm/ci/ciField.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -53,9 +53,6 @@ private:
ciInstanceKlass* _known_to_link_with_get;
ciConstant _constant_value;
- // Used for will_link
- int _cp_index;
-
ciType* compute_type();
ciType* compute_type_impl();
@@ -139,7 +136,10 @@ public:
// non-constant fields. These are java.lang.System.in
// and java.lang.System.out. Abomination.
//
- // Note: the check for case 4 is not yet implemented.
+ // A field is also considered constant if it is marked @Stable
+ // and is non-null (or non-zero, if a primitive).
+ // For non-static fields, the null/zero check must be
+ // arranged by the user, as constant_value().is_null_or_zero().
bool is_constant() { return _is_constant; }
// Get the constant value of this field.
@@ -173,6 +173,7 @@ public:
bool is_protected () { return flags().is_protected(); }
bool is_static () { return flags().is_static(); }
bool is_final () { return flags().is_final(); }
+ bool is_stable () { return flags().is_stable(); }
bool is_volatile () { return flags().is_volatile(); }
bool is_transient () { return flags().is_transient(); }
diff --git a/hotspot/src/share/vm/ci/ciFlags.hpp b/hotspot/src/share/vm/ci/ciFlags.hpp
index 6dc50d25a60..87e19466f27 100644
--- a/hotspot/src/share/vm/ci/ciFlags.hpp
+++ b/hotspot/src/share/vm/ci/ciFlags.hpp
@@ -59,6 +59,7 @@ public:
bool is_interface () const { return (_flags & JVM_ACC_INTERFACE ) != 0; }
bool is_abstract () const { return (_flags & JVM_ACC_ABSTRACT ) != 0; }
bool is_strict () const { return (_flags & JVM_ACC_STRICT ) != 0; }
+ bool is_stable () const { return (_flags & JVM_ACC_FIELD_STABLE) != 0; }
// Conversion
jint as_int() { return _flags; }
diff --git a/hotspot/src/share/vm/ci/ciInstance.cpp b/hotspot/src/share/vm/ci/ciInstance.cpp
index a74eb04f4a7..8b48b1b3706 100644
--- a/hotspot/src/share/vm/ci/ciInstance.cpp
+++ b/hotspot/src/share/vm/ci/ciInstance.cpp
@@ -127,6 +127,8 @@ ciConstant ciInstance::field_value(ciField* field) {
ciConstant ciInstance::field_value_by_offset(int field_offset) {
ciInstanceKlass* ik = klass()->as_instance_klass();
ciField* field = ik->get_field_by_offset(field_offset, false);
+ if (field == NULL)
+ return ciConstant(); // T_ILLEGAL
return field_value(field);
}
diff --git a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp
index d74e484c66e..c689efa46d6 100644
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -522,8 +522,7 @@ ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray*
for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
if (fs.access_flags().is_static()) continue;
- fieldDescriptor fd;
- fd.initialize(k, fs.index());
+ fieldDescriptor& fd = fs.field_descriptor();
ciField* field = new (arena) ciField(&fd);
fields->append(field);
}
diff --git a/hotspot/src/share/vm/ci/ciMethod.cpp b/hotspot/src/share/vm/ci/ciMethod.cpp
index d0363250ee6..486d8c499b6 100644
--- a/hotspot/src/share/vm/ci/ciMethod.cpp
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp
@@ -286,7 +286,10 @@ int ciMethod::itable_index() {
check_is_loaded();
assert(holder()->is_linked(), "must be linked");
VM_ENTRY_MARK;
- return klassItable::compute_itable_index(get_Method());
+ Method* m = get_Method();
+ if (!m->has_itable_index())
+ return Method::nonvirtual_vtable_index;
+ return m->itable_index();
}
#endif // SHARK
@@ -1137,6 +1140,10 @@ bool ciMethod::is_klass_loaded(int refinfo_index, bool must_be_resolved) const {
// ------------------------------------------------------------------
// ciMethod::check_call
bool ciMethod::check_call(int refinfo_index, bool is_static) const {
+ // This method is used only in C2 from InlineTree::ok_to_inline,
+ // and is only used under -Xcomp or -XX:CompileTheWorld.
+ // It appears to fail when applied to an invokeinterface call site.
+ // FIXME: Remove this method and resolve_method_statically; refactor to use the other LinkResolver entry points.
VM_ENTRY_MARK;
{
EXCEPTION_MARK;
diff --git a/hotspot/src/share/vm/ci/ciSymbol.hpp b/hotspot/src/share/vm/ci/ciSymbol.hpp
index d54b54009be..3c974cf272e 100644
--- a/hotspot/src/share/vm/ci/ciSymbol.hpp
+++ b/hotspot/src/share/vm/ci/ciSymbol.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -44,6 +44,7 @@ class ciSymbol : public ciBaseObject {
friend class ciInstanceKlass;
friend class ciSignature;
friend class ciMethod;
+ friend class ciField;
friend class ciObjArrayKlass;
private:
diff --git a/hotspot/src/share/vm/ci/ciTypeArray.cpp b/hotspot/src/share/vm/ci/ciTypeArray.cpp
index d4a6eff6f41..2d013e21c0e 100644
--- a/hotspot/src/share/vm/ci/ciTypeArray.cpp
+++ b/hotspot/src/share/vm/ci/ciTypeArray.cpp
@@ -39,5 +39,10 @@
jchar ciTypeArray::char_at(int index) {
VM_ENTRY_MARK;
assert(index >= 0 && index < length(), "out of range");
- return get_typeArrayOop()->char_at(index);
+ jchar c = get_typeArrayOop()->char_at(index);
+#ifdef ASSERT
+ jchar d = element_value(index).as_char();
+ assert(c == d, "");
+#endif //ASSERT
+ return c;
}
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
index 0705c5f14d6..70662d3e8b8 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
@@ -888,6 +888,7 @@ void ClassFileParser::parse_field_attributes(u2 attributes_count,
int runtime_visible_type_annotations_length = 0;
u1* runtime_invisible_type_annotations = NULL;
int runtime_invisible_type_annotations_length = 0;
+ bool runtime_invisible_type_annotations_exists = false;
while (attributes_count--) {
cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length
u2 attribute_name_index = cfs->get_u2_fast();
@@ -946,15 +947,27 @@ void ClassFileParser::parse_field_attributes(u2 attributes_count,
assert(runtime_invisible_annotations != NULL, "null invisible annotations");
cfs->skip_u1(runtime_invisible_annotations_length, CHECK);
} else if (attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) {
+ if (runtime_visible_type_annotations != NULL) {
+ classfile_parse_error(
+ "Multiple RuntimeVisibleTypeAnnotations attributes for field in class file %s", CHECK);
+ }
runtime_visible_type_annotations_length = attribute_length;
runtime_visible_type_annotations = cfs->get_u1_buffer();
assert(runtime_visible_type_annotations != NULL, "null visible type annotations");
cfs->skip_u1(runtime_visible_type_annotations_length, CHECK);
- } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) {
- runtime_invisible_type_annotations_length = attribute_length;
- runtime_invisible_type_annotations = cfs->get_u1_buffer();
- assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations");
- cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK);
+ } else if (attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) {
+ if (runtime_invisible_type_annotations_exists) {
+ classfile_parse_error(
+ "Multiple RuntimeInvisibleTypeAnnotations attributes for field in class file %s", CHECK);
+ } else {
+ runtime_invisible_type_annotations_exists = true;
+ }
+ if (PreserveAllAnnotations) {
+ runtime_invisible_type_annotations_length = attribute_length;
+ runtime_invisible_type_annotations = cfs->get_u1_buffer();
+ assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations");
+ }
+ cfs->skip_u1(attribute_length, CHECK);
} else {
cfs->skip_u1(attribute_length, CHECK); // Skip unknown attributes
}
@@ -1774,6 +1787,10 @@ ClassFileParser::AnnotationCollector::annotation_index(ClassLoaderData* loader_d
if (_location != _in_method) break; // only allow for methods
if (!privileged) break; // only allow in privileged code
return _method_LambdaForm_Hidden;
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_invoke_Stable_signature):
+ if (_location != _in_field) break; // only allow for fields
+ if (!privileged) break; // only allow in privileged code
+ return _field_Stable;
case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_misc_Contended_signature):
if (_location != _in_field && _location != _in_class) break; // only allow for fields and classes
if (!EnableContended || (RestrictContended && !privileged)) break; // honor privileges
@@ -1786,6 +1803,8 @@ ClassFileParser::AnnotationCollector::annotation_index(ClassLoaderData* loader_d
void ClassFileParser::FieldAnnotationCollector::apply_to(FieldInfo* f) {
if (is_contended())
f->set_contended_group(contended_group());
+ if (is_stable())
+ f->set_stable(true);
}
ClassFileParser::FieldAnnotationCollector::~FieldAnnotationCollector() {
@@ -2060,6 +2079,7 @@ methodHandle ClassFileParser::parse_method(bool is_interface,
int runtime_visible_type_annotations_length = 0;
u1* runtime_invisible_type_annotations = NULL;
int runtime_invisible_type_annotations_length = 0;
+ bool runtime_invisible_type_annotations_exists = false;
u1* annotation_default = NULL;
int annotation_default_length = 0;
@@ -2316,16 +2336,30 @@ methodHandle ClassFileParser::parse_method(bool is_interface,
assert(annotation_default != NULL, "null annotation default");
cfs->skip_u1(annotation_default_length, CHECK_(nullHandle));
} else if (method_attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) {
+ if (runtime_visible_type_annotations != NULL) {
+ classfile_parse_error(
+ "Multiple RuntimeVisibleTypeAnnotations attributes for method in class file %s",
+ CHECK_(nullHandle));
+ }
runtime_visible_type_annotations_length = method_attribute_length;
runtime_visible_type_annotations = cfs->get_u1_buffer();
assert(runtime_visible_type_annotations != NULL, "null visible type annotations");
// No need for the VM to parse Type annotations
cfs->skip_u1(runtime_visible_type_annotations_length, CHECK_(nullHandle));
- } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) {
- runtime_invisible_type_annotations_length = method_attribute_length;
- runtime_invisible_type_annotations = cfs->get_u1_buffer();
- assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations");
- cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK_(nullHandle));
+ } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) {
+ if (runtime_invisible_type_annotations_exists) {
+ classfile_parse_error(
+ "Multiple RuntimeInvisibleTypeAnnotations attributes for method in class file %s",
+ CHECK_(nullHandle));
+ } else {
+ runtime_invisible_type_annotations_exists = true;
+ }
+ if (PreserveAllAnnotations) {
+ runtime_invisible_type_annotations_length = method_attribute_length;
+ runtime_invisible_type_annotations = cfs->get_u1_buffer();
+ assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations");
+ }
+ cfs->skip_u1(method_attribute_length, CHECK_(nullHandle));
} else {
// Skip unknown attributes
cfs->skip_u1(method_attribute_length, CHECK_(nullHandle));
@@ -2818,6 +2852,7 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio
int runtime_visible_type_annotations_length = 0;
u1* runtime_invisible_type_annotations = NULL;
int runtime_invisible_type_annotations_length = 0;
+ bool runtime_invisible_type_annotations_exists = false;
u1* inner_classes_attribute_start = NULL;
u4 inner_classes_attribute_length = 0;
u2 enclosing_method_class_index = 0;
@@ -2921,16 +2956,28 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio
parsed_bootstrap_methods_attribute = true;
parse_classfile_bootstrap_methods_attribute(attribute_length, CHECK);
} else if (tag == vmSymbols::tag_runtime_visible_type_annotations()) {
+ if (runtime_visible_type_annotations != NULL) {
+ classfile_parse_error(
+ "Multiple RuntimeVisibleTypeAnnotations attributes in class file %s", CHECK);
+ }
runtime_visible_type_annotations_length = attribute_length;
runtime_visible_type_annotations = cfs->get_u1_buffer();
assert(runtime_visible_type_annotations != NULL, "null visible type annotations");
// No need for the VM to parse Type annotations
cfs->skip_u1(runtime_visible_type_annotations_length, CHECK);
- } else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_type_annotations()) {
- runtime_invisible_type_annotations_length = attribute_length;
- runtime_invisible_type_annotations = cfs->get_u1_buffer();
- assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations");
- cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK);
+ } else if (tag == vmSymbols::tag_runtime_invisible_type_annotations()) {
+ if (runtime_invisible_type_annotations_exists) {
+ classfile_parse_error(
+ "Multiple RuntimeInvisibleTypeAnnotations attributes in class file %s", CHECK);
+ } else {
+ runtime_invisible_type_annotations_exists = true;
+ }
+ if (PreserveAllAnnotations) {
+ runtime_invisible_type_annotations_length = attribute_length;
+ runtime_invisible_type_annotations = cfs->get_u1_buffer();
+ assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations");
+ }
+ cfs->skip_u1(attribute_length, CHECK);
} else {
// Unknown attribute
cfs->skip_u1(attribute_length, CHECK);
@@ -3948,9 +3995,8 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
this_klass->set_has_final_method();
}
this_klass->copy_method_ordering(method_ordering, CHECK_NULL);
- // The InstanceKlass::_methods_jmethod_ids cache and the
- // InstanceKlass::_methods_cached_itable_indices cache are
- // both managed on the assumption that the initial cache
+ // The InstanceKlass::_methods_jmethod_ids cache
+ // is managed on the assumption that the initial cache
// size is equal to the number of methods in the class. If
// that changes, then InstanceKlass::idnum_can_increment()
// has to be changed accordingly.
diff --git a/hotspot/src/share/vm/classfile/classFileParser.hpp b/hotspot/src/share/vm/classfile/classFileParser.hpp
index 1b5ed30c5a6..02a4ce20dd3 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp
@@ -125,6 +125,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
_method_LambdaForm_Compiled,
_method_LambdaForm_Hidden,
_sun_misc_Contended,
+ _field_Stable,
_annotation_LIMIT
};
const Location _location;
@@ -143,14 +144,23 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob");
_annotations_present |= nth_bit((int)id);
}
+
+ void remove_annotation(ID id) {
+ assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob");
+ _annotations_present &= ~nth_bit((int)id);
+ }
+
// Report if the annotation is present.
- bool has_any_annotations() { return _annotations_present != 0; }
- bool has_annotation(ID id) { return (nth_bit((int)id) & _annotations_present) != 0; }
+ bool has_any_annotations() const { return _annotations_present != 0; }
+ bool has_annotation(ID id) const { return (nth_bit((int)id) & _annotations_present) != 0; }
void set_contended_group(u2 group) { _contended_group = group; }
- u2 contended_group() { return _contended_group; }
+ u2 contended_group() const { return _contended_group; }
- bool is_contended() { return has_annotation(_sun_misc_Contended); }
+ bool is_contended() const { return has_annotation(_sun_misc_Contended); }
+
+ void set_stable(bool stable) { set_annotation(_field_Stable); }
+ bool is_stable() const { return has_annotation(_field_Stable); }
};
// This class also doubles as a holder for metadata cleanup.
diff --git a/hotspot/src/share/vm/classfile/classLoader.cpp b/hotspot/src/share/vm/classfile/classLoader.cpp
index 35055b4cb41..0ab350d90f8 100644
--- a/hotspot/src/share/vm/classfile/classLoader.cpp
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp
@@ -1319,6 +1319,25 @@ static void clear_pending_exception_if_not_oom(TRAPS) {
// The CHECK at the caller will propagate the exception out
}
+/**
+ * Returns if the given method should be compiled when doing compile-the-world.
+ *
+ * TODO: This should be a private method in a CompileTheWorld class.
+ */
+static bool can_be_compiled(methodHandle m, int comp_level) {
+ assert(CompileTheWorld, "must be");
+
+ // It's not valid to compile a native wrapper for MethodHandle methods
+ // that take a MemberName appendix since the bytecode signature is not
+ // correct.
+ vmIntrinsics::ID iid = m->intrinsic_id();
+ if (MethodHandles::is_signature_polymorphic(iid) && MethodHandles::has_member_arg(iid)) {
+ return false;
+ }
+
+ return CompilationPolicy::can_be_compiled(m, comp_level);
+}
+
void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
int len = (int)strlen(name);
if (len > 6 && strcmp(".class", name + len - 6) == 0) {
@@ -1362,8 +1381,7 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
int comp_level = CompilationPolicy::policy()->initial_compile_level();
for (int n = 0; n < k->methods()->length(); n++) {
methodHandle m (THREAD, k->methods()->at(n));
- if (CompilationPolicy::can_be_compiled(m, comp_level)) {
-
+ if (can_be_compiled(m, comp_level)) {
if (++_codecache_sweep_counter == CompileTheWorldSafepointInterval) {
// Give sweeper a chance to keep up with CTW
VM_ForceSafepoint op;
@@ -1375,7 +1393,7 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
methodHandle(), 0, "CTW", THREAD);
if (HAS_PENDING_EXCEPTION) {
clear_pending_exception_if_not_oom(CHECK);
- tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name()->as_C_string());
+ tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string());
} else {
_compile_the_world_method_counter++;
}
@@ -1391,11 +1409,13 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
methodHandle(), 0, "CTW", THREAD);
if (HAS_PENDING_EXCEPTION) {
clear_pending_exception_if_not_oom(CHECK);
- tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name()->as_C_string());
+ tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string());
} else {
_compile_the_world_method_counter++;
}
}
+ } else {
+ tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string());
}
nmethod* nm = m->code();
diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp
index b59fe66e062..99a45b55b6d 100644
--- a/hotspot/src/share/vm/classfile/defaultMethods.cpp
+++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp
@@ -450,6 +450,10 @@ class MethodFamily : public ResourceObj {
streamIndentor si(str, indent * 2);
str->indent().print("Selected method: ");
print_method(str, _selected_target);
+ Klass* method_holder = _selected_target->method_holder();
+ if (!method_holder->is_interface()) {
+ tty->print(" : in superclass");
+ }
str->print_cr("");
}
@@ -1141,19 +1145,23 @@ static void create_overpasses(
#endif // ndef PRODUCT
if (method->has_target()) {
Method* selected = method->get_selected_target();
- max_stack = assemble_redirect(
+ if (selected->method_holder()->is_interface()) {
+ max_stack = assemble_redirect(
&bpool, &buffer, slot->signature(), selected, CHECK);
+ }
} else if (method->throws_exception()) {
max_stack = assemble_abstract_method_error(
&bpool, &buffer, method->get_exception_message(), CHECK);
}
- AccessFlags flags = accessFlags_from(
+ if (max_stack != 0) {
+ AccessFlags flags = accessFlags_from(
JVM_ACC_PUBLIC | JVM_ACC_SYNTHETIC | JVM_ACC_BRIDGE);
- Method* m = new_method(&bpool, &buffer, slot->name(), slot->signature(),
+ Method* m = new_method(&bpool, &buffer, slot->name(), slot->signature(),
flags, max_stack, slot->size_of_parameters(),
ConstMethod::OVERPASS, CHECK);
- if (m != NULL) {
- overpasses.push(m);
+ if (m != NULL) {
+ overpasses.push(m);
+ }
}
}
}
diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp
index 067cf503305..f1758f86654 100644
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp
@@ -270,6 +270,7 @@
template(java_lang_invoke_LambdaForm, "java/lang/invoke/LambdaForm") \
template(java_lang_invoke_ForceInline_signature, "Ljava/lang/invoke/ForceInline;") \
template(java_lang_invoke_DontInline_signature, "Ljava/lang/invoke/DontInline;") \
+ template(sun_invoke_Stable_signature, "Lsun/invoke/Stable;") \
template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \
template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;") \
template(java_lang_invoke_MagicLambdaImpl, "java/lang/invoke/MagicLambdaImpl") \
diff --git a/hotspot/src/share/vm/code/compiledIC.cpp b/hotspot/src/share/vm/code/compiledIC.cpp
index e9a63b86623..b9db323e5b2 100644
--- a/hotspot/src/share/vm/code/compiledIC.cpp
+++ b/hotspot/src/share/vm/code/compiledIC.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -161,31 +161,36 @@ address CompiledIC::stub_address() const {
void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) {
- methodHandle method = call_info->selected_method();
- bool is_invoke_interface = (bytecode == Bytecodes::_invokeinterface && !call_info->has_vtable_index());
assert(CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "");
assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic");
assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?");
address entry;
- if (is_invoke_interface) {
- int index = klassItable::compute_itable_index(call_info->resolved_method()());
- entry = VtableStubs::create_stub(false, index, method());
+ if (call_info->call_kind() == CallInfo::itable_call) {
+ assert(bytecode == Bytecodes::_invokeinterface, "");
+ int itable_index = call_info->itable_index();
+ entry = VtableStubs::find_itable_stub(itable_index);
+#ifdef ASSERT
assert(entry != NULL, "entry not computed");
+ int index = call_info->resolved_method()->itable_index();
+ assert(index == itable_index, "CallInfo pre-computes this");
+#endif //ASSERT
InstanceKlass* k = call_info->resolved_method()->method_holder();
- assert(k->is_interface(), "sanity check");
+ assert(k->verify_itable_index(itable_index), "sanity check");
InlineCacheBuffer::create_transition_stub(this, k, entry);
} else {
- // Can be different than method->vtable_index(), due to package-private etc.
+ assert(call_info->call_kind() == CallInfo::vtable_call, "either itable or vtable");
+ // Can be different than selected_method->vtable_index(), due to package-private etc.
int vtable_index = call_info->vtable_index();
- entry = VtableStubs::create_stub(true, vtable_index, method());
- InlineCacheBuffer::create_transition_stub(this, method(), entry);
+ assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check");
+ entry = VtableStubs::find_vtable_stub(vtable_index);
+ InlineCacheBuffer::create_transition_stub(this, NULL, entry);
}
if (TraceICs) {
ResourceMark rm;
tty->print_cr ("IC@" INTPTR_FORMAT ": to megamorphic %s entry: " INTPTR_FORMAT,
- instruction_address(), method->print_value_string(), entry);
+ instruction_address(), call_info->selected_method()->print_value_string(), entry);
}
// We can't check this anymore. With lazy deopt we could have already
diff --git a/hotspot/src/share/vm/code/vtableStubs.cpp b/hotspot/src/share/vm/code/vtableStubs.cpp
index 0d7b39a0241..7d9d7efaf67 100644
--- a/hotspot/src/share/vm/code/vtableStubs.cpp
+++ b/hotspot/src/share/vm/code/vtableStubs.cpp
@@ -111,7 +111,7 @@ void VtableStubs::initialize() {
}
-address VtableStubs::create_stub(bool is_vtable_stub, int vtable_index, Method* method) {
+address VtableStubs::find_stub(bool is_vtable_stub, int vtable_index) {
assert(vtable_index >= 0, "must be positive");
VtableStub* s = ShareVtableStubs ? lookup(is_vtable_stub, vtable_index) : NULL;
diff --git a/hotspot/src/share/vm/code/vtableStubs.hpp b/hotspot/src/share/vm/code/vtableStubs.hpp
index aa95fee763c..06f2a67a857 100644
--- a/hotspot/src/share/vm/code/vtableStubs.hpp
+++ b/hotspot/src/share/vm/code/vtableStubs.hpp
@@ -121,9 +121,11 @@ class VtableStubs : AllStatic {
static VtableStub* lookup (bool is_vtable_stub, int vtable_index);
static void enter (bool is_vtable_stub, int vtable_index, VtableStub* s);
static inline uint hash (bool is_vtable_stub, int vtable_index);
+ static address find_stub (bool is_vtable_stub, int vtable_index);
public:
- static address create_stub(bool is_vtable_stub, int vtable_index, Method* method); // return the entry point of a stub for this call
+ static address find_vtable_stub(int vtable_index) { return find_stub(true, vtable_index); }
+ static address find_itable_stub(int itable_index) { return find_stub(false, itable_index); }
static bool is_entry_point(address pc); // is pc a vtable stub entry point?
static bool contains(address pc); // is pc within any stub?
static VtableStub* stub_containing(address pc); // stub containing pc or NULL
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
index 04b550c718b..2fc6edd34df 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
@@ -230,7 +230,7 @@ ConcurrentMarkSweepGeneration::ConcurrentMarkSweepGeneration(
// depends on this property.
debug_only(
FreeChunk* junk = NULL;
- assert(UseCompressedKlassPointers ||
+ assert(UseCompressedClassPointers ||
junk->prev_addr() == (void*)(oop(junk)->klass_addr()),
"Offset of FreeChunk::_prev within FreeChunk must match"
" that of OopDesc::_klass within OopDesc");
@@ -1407,7 +1407,7 @@ ConcurrentMarkSweepGeneration::par_promote(int thread_num,
assert(!((FreeChunk*)obj_ptr)->is_free(), "Error, block will look free but show wrong size");
OrderAccess::storestore();
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
// Copy gap missed by (aligned) header size calculation below
obj->set_klass_gap(old->klass_gap());
}
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
index 04f8ccd0fc7..77f08f0d3a3 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
@@ -481,9 +481,8 @@ uint ConcurrentMark::scale_parallel_threads(uint n_par_threads) {
ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs) :
_g1h(g1h),
- _markBitMap1(MinObjAlignment - 1),
- _markBitMap2(MinObjAlignment - 1),
-
+ _markBitMap1(log2_intptr(MinObjAlignment)),
+ _markBitMap2(log2_intptr(MinObjAlignment)),
_parallel_marking_threads(0),
_max_parallel_marking_threads(0),
_sleep_factor(0.0),
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp
index f75e518facc..31972bf3c4e 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp
@@ -33,8 +33,8 @@
void G1CardCounts::clear_range(size_t from_card_num, size_t to_card_num) {
if (has_count_table()) {
- check_card_num(from_card_num,
- err_msg("from card num out of range: "SIZE_FORMAT, from_card_num));
+ assert(from_card_num >= 0 && from_card_num < _committed_max_card_num,
+ err_msg("from card num out of range: "SIZE_FORMAT, from_card_num));
assert(from_card_num < to_card_num,
err_msg("Wrong order? from: " SIZE_FORMAT ", to: "SIZE_FORMAT,
from_card_num, to_card_num));
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp
index fd516c0b90e..129b3b0d232 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp
@@ -72,25 +72,21 @@ class G1CardCounts: public CHeapObj {
return has_reserved_count_table() && _committed_max_card_num > 0;
}
- void check_card_num(size_t card_num, const char* msg) {
- assert(card_num >= 0 && card_num < _committed_max_card_num, msg);
- }
-
size_t ptr_2_card_num(const jbyte* card_ptr) {
assert(card_ptr >= _ct_bot,
- err_msg("Inavalied card pointer: "
+ err_msg("Invalid card pointer: "
"card_ptr: " PTR_FORMAT ", "
"_ct_bot: " PTR_FORMAT,
card_ptr, _ct_bot));
size_t card_num = pointer_delta(card_ptr, _ct_bot, sizeof(jbyte));
- check_card_num(card_num,
- err_msg("card pointer out of range: " PTR_FORMAT, card_ptr));
+ assert(card_num >= 0 && card_num < _committed_max_card_num,
+ err_msg("card pointer out of range: " PTR_FORMAT, card_ptr));
return card_num;
}
jbyte* card_num_2_ptr(size_t card_num) {
- check_card_num(card_num,
- err_msg("card num out of range: "SIZE_FORMAT, card_num));
+ assert(card_num >= 0 && card_num < _committed_max_card_num,
+ err_msg("card num out of range: "SIZE_FORMAT, card_num));
return (jbyte*) (_ct_bot + card_num);
}
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
index bd01ec3b602..1d8ff8a26dc 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
@@ -2191,6 +2191,10 @@ jint G1CollectedHeap::initialize() {
return JNI_OK;
}
+size_t G1CollectedHeap::conservative_max_heap_alignment() {
+ return HeapRegion::max_region_size();
+}
+
void G1CollectedHeap::ref_processing_init() {
// Reference processing in G1 currently works as follows:
//
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
index aecaa5e97ac..747b2326236 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
@@ -1092,6 +1092,9 @@ public:
// specified by the policy object.
jint initialize();
+ // Return the (conservative) maximum heap alignment for any G1 heap
+ static size_t conservative_max_heap_alignment();
+
// Initialize weak reference processing.
virtual void ref_processing_init();
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp
index e66268885e3..726acbfcdc0 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -149,6 +149,10 @@ void HeapRegionDCTOC::walk_mem_region_with_cl(MemRegion mr,
// many regions in the heap (based on the min heap size).
#define TARGET_REGION_NUMBER 2048
+size_t HeapRegion::max_region_size() {
+ return (size_t)MAX_REGION_SIZE;
+}
+
void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size) {
uintx region_size = G1HeapRegionSize;
if (FLAG_IS_DEFAULT(G1HeapRegionSize)) {
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp
index 097c0b54380..ad2b0649795 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -355,6 +355,8 @@ class HeapRegion: public G1OffsetTableContigSpace {
~((1 << (size_t) LogOfHRGrainBytes) - 1);
}
+ static size_t max_region_size();
+
// It sets up the heap region size (GrainBytes / GrainWords), as
// well as other related fields that are based on the heap region
// size (LogOfHRGrainBytes / LogOfHRGrainWords /
diff --git a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp
index 1f6d9b21388..958317166ea 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp
@@ -38,6 +38,7 @@
class PtrQueueSet;
class PtrQueue VALUE_OBJ_CLASS_SPEC {
+ friend class VMStructs;
protected:
// The ptr queue set to which this queue belongs.
diff --git a/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp b/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp
index 5507dee5f80..736c2d75096 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp
@@ -31,7 +31,8 @@
#define VM_STRUCTS_G1(nonstatic_field, static_field) \
\
- static_field(HeapRegion, GrainBytes, size_t) \
+ static_field(HeapRegion, GrainBytes, size_t) \
+ static_field(HeapRegion, LogOfHRGrainBytes, int) \
\
nonstatic_field(HeapRegionSeq, _regions, HeapRegion**) \
nonstatic_field(HeapRegionSeq, _length, uint) \
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp
index b4b8c1ae9bb..e5637687e84 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -68,9 +68,6 @@ class GenerationSizer : public TwoGenerationCollectorPolicy {
size_t min_old_gen_size() { return _min_gen1_size; }
size_t old_gen_size() { return _initial_gen1_size; }
size_t max_old_gen_size() { return _max_gen1_size; }
-
- size_t metaspace_size() { return MetaspaceSize; }
- size_t max_metaspace_size() { return MaxMetaspaceSize; }
};
#endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_GENERATIONSIZER_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp
index 11ef5325120..4e458efa903 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp
@@ -86,6 +86,11 @@ class ParallelScavengeHeap : public CollectedHeap {
set_alignment(_old_gen_alignment, intra_heap_alignment());
}
+ // Return the (conservative) maximum heap alignment
+ static size_t conservative_max_heap_alignment() {
+ return intra_heap_alignment();
+ }
+
// For use by VM operations
enum CollectionType {
Scavenge,
@@ -122,7 +127,7 @@ class ParallelScavengeHeap : public CollectedHeap {
// The alignment used for eden and survivors within the young gen
// and for boundary between young gen and old gen.
- size_t intra_heap_alignment() const { return 64 * K * HeapWordSize; }
+ static size_t intra_heap_alignment() { return 64 * K * HeapWordSize; }
size_t capacity() const;
size_t used() const;
diff --git a/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp
index cf7cd3ae0f2..0fb6d7fa23e 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -26,11 +26,9 @@
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_ALLOCATIONSTATS_HPP
#include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc_implementation/shared/gcUtil.hpp"
#include "memory/allocation.hpp"
#include "utilities/globalDefinitions.hpp"
-#endif // INCLUDE_ALL_GCS
+#include "gc_implementation/shared/gcUtil.hpp"
class AllocationStats VALUE_OBJ_CLASS_SPEC {
// A duration threshold (in ms) used to filter
diff --git a/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp b/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp
index 034d319b078..0b855e7f674 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -26,11 +26,9 @@
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_HSPACECOUNTERS_HPP
#include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
#include "gc_implementation/shared/generationCounters.hpp"
#include "memory/generation.hpp"
#include "runtime/perfData.hpp"
-#endif // INCLUDE_ALL_GCS
// A HSpaceCounter is a holder class for performance counters
// that track a collections (logical spaces) in a heap;
diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp
index 3af380049bb..3f5364b79c0 100644
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp
@@ -87,15 +87,15 @@ MetaspaceSummary CollectedHeap::create_metaspace_summary() {
const MetaspaceSizes meta_space(
MetaspaceAux::allocated_capacity_bytes(),
MetaspaceAux::allocated_used_bytes(),
- MetaspaceAux::reserved_in_bytes());
+ MetaspaceAux::reserved_bytes());
const MetaspaceSizes data_space(
MetaspaceAux::allocated_capacity_bytes(Metaspace::NonClassType),
MetaspaceAux::allocated_used_bytes(Metaspace::NonClassType),
- MetaspaceAux::reserved_in_bytes(Metaspace::NonClassType));
+ MetaspaceAux::reserved_bytes(Metaspace::NonClassType));
const MetaspaceSizes class_space(
MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType),
MetaspaceAux::allocated_used_bytes(Metaspace::ClassType),
- MetaspaceAux::reserved_in_bytes(Metaspace::ClassType));
+ MetaspaceAux::reserved_bytes(Metaspace::ClassType));
return MetaspaceSummary(meta_space, data_space, class_space);
}
diff --git a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
index 4a3019f867f..4c082597b22 100644
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
@@ -496,15 +496,15 @@ IRT_END
IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode))
// resolve field
- FieldAccessInfo info;
+ fieldDescriptor info;
constantPoolHandle pool(thread, method(thread)->constants());
bool is_put = (bytecode == Bytecodes::_putfield || bytecode == Bytecodes::_putstatic);
bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic);
{
JvmtiHideSingleStepping jhss(thread);
- LinkResolver::resolve_field(info, pool, get_index_u2_cpcache(thread, bytecode),
- bytecode, false, CHECK);
+ LinkResolver::resolve_field_access(info, pool, get_index_u2_cpcache(thread, bytecode),
+ bytecode, CHECK);
} // end JvmtiHideSingleStepping
// check if link resolution caused cpCache to be updated
@@ -524,7 +524,7 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecode
// class is intitialized. This is required so that access to the static
// field will call the initialization function every time until the class
// is completely initialized ala. in 2.17.5 in JVM Specification.
- InstanceKlass *klass = InstanceKlass::cast(info.klass()());
+ InstanceKlass* klass = InstanceKlass::cast(info.field_holder());
bool uninitialized_static = ((bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic) &&
!klass->is_initialized());
Bytecodes::Code get_code = (Bytecodes::Code)0;
@@ -539,9 +539,9 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecode
cache_entry(thread)->set_field(
get_code,
put_code,
- info.klass(),
- info.field_index(),
- info.field_offset(),
+ info.field_holder(),
+ info.index(),
+ info.offset(),
state,
info.access_flags().is_final(),
info.access_flags().is_volatile(),
@@ -686,29 +686,55 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes
if (already_resolved(thread)) return;
if (bytecode == Bytecodes::_invokeinterface) {
-
if (TraceItables && Verbose) {
ResourceMark rm(thread);
tty->print_cr("Resolving: klass: %s to method: %s", info.resolved_klass()->name()->as_C_string(), info.resolved_method()->name()->as_C_string());
}
+ }
+#ifdef ASSERT
+ if (bytecode == Bytecodes::_invokeinterface) {
if (info.resolved_method()->method_holder() ==
SystemDictionary::Object_klass()) {
// NOTE: THIS IS A FIX FOR A CORNER CASE in the JVM spec
- // (see also cpCacheOop.cpp for details)
+ // (see also CallInfo::set_interface for details)
+ assert(info.call_kind() == CallInfo::vtable_call ||
+ info.call_kind() == CallInfo::direct_call, "");
methodHandle rm = info.resolved_method();
assert(rm->is_final() || info.has_vtable_index(),
"should have been set already");
- cache_entry(thread)->set_method(bytecode, rm, info.vtable_index());
+ } else if (!info.resolved_method()->has_itable_index()) {
+ // Resolved something like CharSequence.toString. Use vtable not itable.
+ assert(info.call_kind() != CallInfo::itable_call, "");
} else {
// Setup itable entry
- int index = klassItable::compute_itable_index(info.resolved_method()());
- cache_entry(thread)->set_interface_call(info.resolved_method(), index);
+ assert(info.call_kind() == CallInfo::itable_call, "");
+ int index = info.resolved_method()->itable_index();
+ assert(info.itable_index() == index, "");
}
} else {
- cache_entry(thread)->set_method(
+ assert(info.call_kind() == CallInfo::direct_call ||
+ info.call_kind() == CallInfo::vtable_call, "");
+ }
+#endif
+ switch (info.call_kind()) {
+ case CallInfo::direct_call:
+ cache_entry(thread)->set_direct_call(
+ bytecode,
+ info.resolved_method());
+ break;
+ case CallInfo::vtable_call:
+ cache_entry(thread)->set_vtable_call(
bytecode,
info.resolved_method(),
info.vtable_index());
+ break;
+ case CallInfo::itable_call:
+ cache_entry(thread)->set_itable_call(
+ bytecode,
+ info.resolved_method(),
+ info.itable_index());
+ break;
+ default: ShouldNotReachHere();
}
}
IRT_END
diff --git a/hotspot/src/share/vm/interpreter/linkResolver.cpp b/hotspot/src/share/vm/interpreter/linkResolver.cpp
index b0bd678b597..44ac9e0862d 100644
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp
@@ -46,19 +46,6 @@
#include "runtime/thread.inline.hpp"
#include "runtime/vmThread.hpp"
-//------------------------------------------------------------------------------------------------------------------------
-// Implementation of FieldAccessInfo
-
-void FieldAccessInfo::set(KlassHandle klass, Symbol* name, int field_index, int field_offset,
-BasicType field_type, AccessFlags access_flags) {
- _klass = klass;
- _name = name;
- _field_index = field_index;
- _field_offset = field_offset;
- _field_type = field_type;
- _access_flags = access_flags;
-}
-
//------------------------------------------------------------------------------------------------------------------------
// Implementation of CallInfo
@@ -66,26 +53,25 @@ BasicType field_type, AccessFlags access_flags) {
void CallInfo::set_static(KlassHandle resolved_klass, methodHandle resolved_method, TRAPS) {
int vtable_index = Method::nonvirtual_vtable_index;
- set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK);
+ set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, CallInfo::direct_call, vtable_index, CHECK);
}
-void CallInfo::set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, TRAPS) {
+void CallInfo::set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int itable_index, TRAPS) {
// This is only called for interface methods. If the resolved_method
// comes from java/lang/Object, it can be the subject of a virtual call, so
// we should pick the vtable index from the resolved method.
- // Other than that case, there is no valid vtable index to specify.
- int vtable_index = Method::invalid_vtable_index;
- if (resolved_method->method_holder() == SystemDictionary::Object_klass()) {
- assert(resolved_method->vtable_index() == selected_method->vtable_index(), "sanity check");
- vtable_index = resolved_method->vtable_index();
- }
- set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK);
+ // In that case, the caller must call set_virtual instead of set_interface.
+ assert(resolved_method->method_holder()->is_interface(), "");
+ assert(itable_index == resolved_method()->itable_index(), "");
+ set_common(resolved_klass, selected_klass, resolved_method, selected_method, CallInfo::itable_call, itable_index, CHECK);
}
void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index, "valid index");
- set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK);
+ assert(vtable_index < 0 || !resolved_method->has_vtable_index() || vtable_index == resolved_method->vtable_index(), "");
+ CallKind kind = (vtable_index >= 0 && !resolved_method->can_be_statically_bound() ? CallInfo::vtable_call : CallInfo::direct_call);
+ set_common(resolved_klass, selected_klass, resolved_method, selected_method, kind, vtable_index, CHECK);
assert(!resolved_method->is_compiled_lambda_form(), "these must be handled via an invokehandle call");
}
@@ -98,20 +84,29 @@ void CallInfo::set_handle(methodHandle resolved_method, Handle resolved_appendix
resolved_method->is_compiled_lambda_form(),
"linkMethod must return one of these");
int vtable_index = Method::nonvirtual_vtable_index;
- assert(resolved_method->vtable_index() == vtable_index, "");
- set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK);
+ assert(!resolved_method->has_vtable_index(), "");
+ set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, CallInfo::direct_call, vtable_index, CHECK);
_resolved_appendix = resolved_appendix;
_resolved_method_type = resolved_method_type;
}
-void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
+void CallInfo::set_common(KlassHandle resolved_klass,
+ KlassHandle selected_klass,
+ methodHandle resolved_method,
+ methodHandle selected_method,
+ CallKind kind,
+ int index,
+ TRAPS) {
assert(resolved_method->signature() == selected_method->signature(), "signatures must correspond");
_resolved_klass = resolved_klass;
_selected_klass = selected_klass;
_resolved_method = resolved_method;
_selected_method = selected_method;
- _vtable_index = vtable_index;
+ _call_kind = kind;
+ _call_index = index;
_resolved_appendix = Handle();
+ DEBUG_ONLY(verify()); // verify before making side effects
+
if (CompilationPolicy::must_be_compiled(selected_method)) {
// This path is unusual, mostly used by the '-Xcomp' stress test mode.
@@ -138,6 +133,65 @@ void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass
}
}
+// utility query for unreflecting a method
+CallInfo::CallInfo(Method* resolved_method, Klass* resolved_klass) {
+ Klass* resolved_method_holder = resolved_method->method_holder();
+ if (resolved_klass == NULL) { // 2nd argument defaults to holder of 1st
+ resolved_klass = resolved_method_holder;
+ }
+ _resolved_klass = resolved_klass;
+ _selected_klass = resolved_klass;
+ _resolved_method = resolved_method;
+ _selected_method = resolved_method;
+ // classify:
+ CallKind kind = CallInfo::unknown_kind;
+ int index = resolved_method->vtable_index();
+ if (resolved_method->can_be_statically_bound()) {
+ kind = CallInfo::direct_call;
+ } else if (!resolved_method_holder->is_interface()) {
+ // Could be an Object method inherited into an interface, but still a vtable call.
+ kind = CallInfo::vtable_call;
+ } else if (!resolved_klass->is_interface()) {
+ // A miranda method. Compute the vtable index.
+ ResourceMark rm;
+ klassVtable* vt = InstanceKlass::cast(resolved_klass)->vtable();
+ index = vt->index_of_miranda(resolved_method->name(),
+ resolved_method->signature());
+ kind = CallInfo::vtable_call;
+ } else {
+ // A regular interface call.
+ kind = CallInfo::itable_call;
+ index = resolved_method->itable_index();
+ }
+ assert(index == Method::nonvirtual_vtable_index || index >= 0, err_msg("bad index %d", index));
+ _call_kind = kind;
+ _call_index = index;
+ _resolved_appendix = Handle();
+ DEBUG_ONLY(verify());
+}
+
+#ifdef ASSERT
+void CallInfo::verify() {
+ switch (call_kind()) { // the meaning and allowed value of index depends on kind
+ case CallInfo::direct_call:
+ if (_call_index == Method::nonvirtual_vtable_index) break;
+ // else fall through to check vtable index:
+ case CallInfo::vtable_call:
+ assert(resolved_klass()->verify_vtable_index(_call_index), "");
+ break;
+ case CallInfo::itable_call:
+ assert(resolved_method()->method_holder()->verify_itable_index(_call_index), "");
+ break;
+ case CallInfo::unknown_kind:
+ assert(call_kind() != CallInfo::unknown_kind, "CallInfo must be set");
+ break;
+ default:
+ fatal(err_msg_res("Unexpected call kind %d", call_kind()));
+ }
+}
+#endif //ASSERT
+
+
//------------------------------------------------------------------------------------------------------------------------
// Klass resolution
@@ -163,13 +217,6 @@ void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, i
result = KlassHandle(THREAD, result_oop);
}
-void LinkResolver::resolve_klass_no_update(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) {
- Klass* result_oop =
- ConstantPool::klass_ref_at_if_loaded_check(pool, index, CHECK);
- result = KlassHandle(THREAD, result_oop);
-}
-
-
//------------------------------------------------------------------------------------------------------------------------
// Method resolution
//
@@ -360,7 +407,12 @@ void LinkResolver::check_method_accessability(KlassHandle ref_klass,
void LinkResolver::resolve_method_statically(methodHandle& resolved_method, KlassHandle& resolved_klass,
Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS) {
-
+ // This method is used only
+ // (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call),
+ // and
+ // (2) in Bytecode_invoke::static_target
+ // It appears to fail when applied to an invokeinterface call site.
+ // FIXME: Remove this method and ciMethod::check_call; refactor to use the other LinkResolver entry points.
// resolve klass
if (code == Bytecodes::_invokedynamic) {
resolved_klass = SystemDictionary::MethodHandle_klass();
@@ -580,45 +632,49 @@ void LinkResolver::check_field_accessability(KlassHandle ref_klass,
}
}
-void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, TRAPS) {
- resolve_field(result, pool, index, byte, check_only, true, CHECK);
+void LinkResolver::resolve_field_access(fieldDescriptor& result, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) {
+ // Load these early in case the resolve of the containing klass fails
+ Symbol* field = pool->name_ref_at(index);
+ Symbol* sig = pool->signature_ref_at(index);
+
+ // resolve specified klass
+ KlassHandle resolved_klass;
+ resolve_klass(resolved_klass, pool, index, CHECK);
+
+ KlassHandle current_klass(THREAD, pool->pool_holder());
+ resolve_field(result, resolved_klass, field, sig, current_klass, byte, true, true, CHECK);
}
-void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, bool update_pool, TRAPS) {
+void LinkResolver::resolve_field(fieldDescriptor& fd, KlassHandle resolved_klass, Symbol* field, Symbol* sig,
+ KlassHandle current_klass, Bytecodes::Code byte, bool check_access, bool initialize_class,
+ TRAPS) {
assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
- byte == Bytecodes::_getfield || byte == Bytecodes::_putfield, "bad bytecode");
+ byte == Bytecodes::_getfield || byte == Bytecodes::_putfield ||
+ (byte == Bytecodes::_nop && !check_access), "bad field access bytecode");
bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
bool is_put = (byte == Bytecodes::_putfield || byte == Bytecodes::_putstatic);
- // resolve specified klass
- KlassHandle resolved_klass;
- if (update_pool) {
- resolve_klass(resolved_klass, pool, index, CHECK);
- } else {
- resolve_klass_no_update(resolved_klass, pool, index, CHECK);
- }
- // Load these early in case the resolve of the containing klass fails
- Symbol* field = pool->name_ref_at(index);
- Symbol* sig = pool->signature_ref_at(index);
// Check if there's a resolved klass containing the field
- if( resolved_klass.is_null() ) {
+ if (resolved_klass.is_null()) {
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
}
// Resolve instance field
- fieldDescriptor fd; // find_field initializes fd if found
KlassHandle sel_klass(THREAD, InstanceKlass::cast(resolved_klass())->find_field(field, sig, &fd));
// check if field exists; i.e., if a klass containing the field def has been selected
- if (sel_klass.is_null()){
+ if (sel_klass.is_null()) {
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
}
+ if (!check_access)
+ // Access checking may be turned off when calling from within the VM.
+ return;
+
// check access
- KlassHandle ref_klass(THREAD, pool->pool_holder());
- check_field_accessability(ref_klass, resolved_klass, sel_klass, fd, CHECK);
+ check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK);
// check for errors
if (is_static != fd.is_static()) {
@@ -629,7 +685,7 @@ void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle poo
}
// Final fields can only be accessed from its own class.
- if (is_put && fd.access_flags().is_final() && sel_klass() != pool->pool_holder()) {
+ if (is_put && fd.access_flags().is_final() && sel_klass() != current_klass()) {
THROW(vmSymbols::java_lang_IllegalAccessError());
}
@@ -639,19 +695,18 @@ void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle poo
//
// note 2: we don't want to force initialization if we are just checking
// if the field access is legal; e.g., during compilation
- if (is_static && !check_only) {
+ if (is_static && initialize_class) {
sel_klass->initialize(CHECK);
}
- {
+ if (sel_klass() != current_klass()) {
HandleMark hm(THREAD);
- Handle ref_loader (THREAD, InstanceKlass::cast(ref_klass())->class_loader());
+ Handle ref_loader (THREAD, InstanceKlass::cast(current_klass())->class_loader());
Handle sel_loader (THREAD, InstanceKlass::cast(sel_klass())->class_loader());
- Symbol* signature_ref = pool->signature_ref_at(index);
{
ResourceMark rm(THREAD);
Symbol* failed_type_symbol =
- SystemDictionary::check_signature_loaders(signature_ref,
+ SystemDictionary::check_signature_loaders(sig,
ref_loader, sel_loader,
false,
CHECK);
@@ -677,9 +732,6 @@ void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle poo
// return information. note that the klass is set to the actual klass containing the
// field, otherwise access of static fields in superclasses will not work.
- KlassHandle holder (THREAD, fd.field_holder());
- Symbol* name = fd.name();
- result.set(holder, name, fd.index(), fd.offset(), fd.field_type(), fd.access_flags());
}
@@ -906,10 +958,6 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
THROW(vmSymbols::java_lang_NullPointerException());
}
- // Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s
- // has not been rewritten, and the vtable initialized.
- assert(resolved_method->method_holder()->is_linked(), "must be linked");
-
// Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s
// has not been rewritten, and the vtable initialized. Make sure to do this after the nullcheck, since
// a missing receiver might result in a bogus lookup.
@@ -920,6 +968,7 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
vtable_index = vtable_index_of_miranda_method(resolved_klass,
resolved_method->name(),
resolved_method->signature(), CHECK);
+
assert(vtable_index >= 0 , "we should have valid vtable index at this point");
InstanceKlass* inst = InstanceKlass::cast(recv_klass());
@@ -927,6 +976,7 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
} else {
// at this point we are sure that resolved_method is virtual and not
// a miranda method; therefore, it must have a valid vtable index.
+ assert(!resolved_method->has_itable_index(), "");
vtable_index = resolved_method->vtable_index();
// We could get a negative vtable_index for final methods,
// because as an optimization they are they are never put in the vtable,
@@ -1006,6 +1056,12 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand
lookup_instance_method_in_klasses(sel_method, recv_klass,
resolved_method->name(),
resolved_method->signature(), CHECK);
+ if (sel_method.is_null() && !check_null_and_abstract) {
+ // In theory this is a harmless placeholder value, but
+ // in practice leaving in null affects the nsk default method tests.
+ // This needs further study.
+ sel_method = resolved_method;
+ }
// check if method exists
if (sel_method.is_null()) {
ResourceMark rm(THREAD);
@@ -1046,7 +1102,14 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand
sel_method->signature()));
}
// setup result
- result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, CHECK);
+ if (!resolved_method->has_itable_index()) {
+ int vtable_index = resolved_method->vtable_index();
+ assert(vtable_index == sel_method->vtable_index(), "sanity check");
+ result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK);
+ return;
+ }
+ int itable_index = resolved_method()->itable_index();
+ result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK);
}
@@ -1293,7 +1356,8 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle po
}
if (TraceMethodHandles) {
- tty->print_cr("resolve_invokedynamic #%d %s %s",
+ ResourceMark rm(THREAD);
+ tty->print_cr("resolve_invokedynamic #%d %s %s",
ConstantPool::decode_invokedynamic_index(index),
method_name->as_C_string(), method_signature->as_C_string());
tty->print(" BSM info: "); bootstrap_specifier->print();
@@ -1342,9 +1406,16 @@ void LinkResolver::resolve_dynamic_call(CallInfo& result,
//------------------------------------------------------------------------------------------------------------------------
#ifndef PRODUCT
-void FieldAccessInfo::print() {
+void CallInfo::print() {
ResourceMark rm;
- tty->print_cr("Field %s@%d", name()->as_C_string(), field_offset());
+ const char* kindstr = "unknown";
+ switch (_call_kind) {
+ case direct_call: kindstr = "direct"; break;
+ case vtable_call: kindstr = "vtable"; break;
+ case itable_call: kindstr = "itable"; break;
+ }
+ tty->print_cr("Call %s@%d %s", kindstr, _call_index,
+ _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
}
#endif
diff --git a/hotspot/src/share/vm/interpreter/linkResolver.hpp b/hotspot/src/share/vm/interpreter/linkResolver.hpp
index 4054eeb35ef..0fb551a23a8 100644
--- a/hotspot/src/share/vm/interpreter/linkResolver.hpp
+++ b/hotspot/src/share/vm/interpreter/linkResolver.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -30,63 +30,54 @@
// All the necessary definitions for run-time link resolution.
-// LinkInfo & its subclasses provide all the information gathered
-// for a particular link after resolving it. A link is any reference
+// CallInfo provides all the information gathered for a particular
+// linked call site after resolving it. A link is any reference
// made from within the bytecodes of a method to an object outside of
// that method. If the info is invalid, the link has not been resolved
// successfully.
-class LinkInfo VALUE_OBJ_CLASS_SPEC {
-};
-
-
-// Link information for getfield/putfield & getstatic/putstatic bytecodes.
-
-class FieldAccessInfo: public LinkInfo {
- protected:
- KlassHandle _klass;
- Symbol* _name;
- AccessFlags _access_flags;
- int _field_index; // original index in the klass
- int _field_offset;
- BasicType _field_type;
-
+class CallInfo VALUE_OBJ_CLASS_SPEC {
public:
- void set(KlassHandle klass, Symbol* name, int field_index, int field_offset,
- BasicType field_type, AccessFlags access_flags);
- KlassHandle klass() const { return _klass; }
- Symbol* name() const { return _name; }
- int field_index() const { return _field_index; }
- int field_offset() const { return _field_offset; }
- BasicType field_type() const { return _field_type; }
- AccessFlags access_flags() const { return _access_flags; }
-
- // debugging
- void print() PRODUCT_RETURN;
-};
-
-
-// Link information for all calls.
-
-class CallInfo: public LinkInfo {
+ // Ways that a method call might be selected (or not) based on receiver type.
+ // Note that an invokevirtual instruction might be linked with no_dispatch,
+ // and an invokeinterface instruction might be linked with any of the three options
+ enum CallKind {
+ direct_call, // jump into resolved_method (must be concrete)
+ vtable_call, // select recv.klass.method_at_vtable(index)
+ itable_call, // select recv.klass.method_at_itable(resolved_method.holder, index)
+ unknown_kind = -1
+ };
private:
- KlassHandle _resolved_klass; // static receiver klass
+ KlassHandle _resolved_klass; // static receiver klass, resolved from a symbolic reference
KlassHandle _selected_klass; // dynamic receiver class (same as static, or subklass)
methodHandle _resolved_method; // static target method
methodHandle _selected_method; // dynamic (actual) target method
- int _vtable_index; // vtable index of selected method
+ CallKind _call_kind; // kind of call (static(=bytecode static/special +
+ // others inferred), vtable, itable)
+ int _call_index; // vtable or itable index of selected class method (if any)
Handle _resolved_appendix; // extra argument in constant pool (if CPCE::has_appendix)
Handle _resolved_method_type; // MethodType (for invokedynamic and invokehandle call sites)
void set_static( KlassHandle resolved_klass, methodHandle resolved_method , TRAPS);
- void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method , TRAPS);
+ void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int itable_index , TRAPS);
void set_virtual( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index , TRAPS);
void set_handle( methodHandle resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS);
- void set_common( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index , TRAPS);
+ void set_common( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, CallKind kind, int index, TRAPS);
friend class LinkResolver;
public:
+ CallInfo() {
+#ifndef PRODUCT
+ _call_kind = CallInfo::unknown_kind;
+ _call_index = Method::garbage_vtable_index;
+#endif //PRODUCT
+ }
+
+ // utility to extract an effective CallInfo from a method and an optional receiver limit
+ // does not queue the method for compilation
+ CallInfo(Method* resolved_method, Klass* resolved_klass = NULL);
+
KlassHandle resolved_klass() const { return _resolved_klass; }
KlassHandle selected_klass() const { return _selected_klass; }
methodHandle resolved_method() const { return _resolved_method; }
@@ -95,21 +86,43 @@ class CallInfo: public LinkInfo {
Handle resolved_method_type() const { return _resolved_method_type; }
BasicType result_type() const { return selected_method()->result_type(); }
- bool has_vtable_index() const { return _vtable_index >= 0; }
- bool is_statically_bound() const { return _vtable_index == Method::nonvirtual_vtable_index; }
+ CallKind call_kind() const { return _call_kind; }
+ int call_index() const { return _call_index; }
int vtable_index() const {
// Even for interface calls the vtable index could be non-negative.
// See CallInfo::set_interface.
assert(has_vtable_index() || is_statically_bound(), "");
- return _vtable_index;
+ assert(call_kind() == vtable_call || call_kind() == direct_call, "");
+ // The returned value is < 0 if the call is statically bound.
+ // But, the returned value may be >= 0 even if the kind is direct_call.
+ // It is up to the caller to decide which way to go.
+ return _call_index;
}
+ int itable_index() const {
+ assert(call_kind() == itable_call, "");
+ // The returned value is always >= 0, a valid itable index.
+ return _call_index;
+ }
+
+ // debugging
+#ifdef ASSERT
+ bool has_vtable_index() const { return _call_index >= 0 && _call_kind != CallInfo::itable_call; }
+ bool is_statically_bound() const { return _call_index == Method::nonvirtual_vtable_index; }
+#endif //ASSERT
+ void verify() PRODUCT_RETURN;
+ void print() PRODUCT_RETURN;
};
+// Link information for getfield/putfield & getstatic/putstatic bytecodes
+// is represented using a fieldDescriptor.
// The LinkResolver is used to resolve constant-pool references at run-time.
// It does all necessary link-time checks & throws exceptions if necessary.
class LinkResolver: AllStatic {
+ friend class klassVtable;
+ friend class klassItable;
+
private:
static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
@@ -120,7 +133,6 @@ class LinkResolver: AllStatic {
static int vtable_index_of_miranda_method(KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
static void resolve_klass (KlassHandle& result, constantPoolHandle pool, int index, TRAPS);
- static void resolve_klass_no_update (KlassHandle& result, constantPoolHandle pool, int index, TRAPS); // no update of constantPool entry
static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS);
@@ -148,9 +160,16 @@ class LinkResolver: AllStatic {
Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS);
// runtime/static resolving for fields
- static void resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, TRAPS);
- // takes an extra bool argument "update_pool" to decide whether to update the constantPool during klass resolution.
- static void resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, bool update_pool, TRAPS);
+ static void resolve_field_access(fieldDescriptor& result, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS);
+ static void resolve_field(fieldDescriptor& result, KlassHandle resolved_klass, Symbol* field_name, Symbol* field_signature,
+ KlassHandle current_klass, Bytecodes::Code access_kind, bool check_access, bool initialize_class, TRAPS);
+
+ // source of access_kind codes:
+ static Bytecodes::Code field_access_kind(bool is_static, bool is_put) {
+ return (is_static
+ ? (is_put ? Bytecodes::_putstatic : Bytecodes::_getstatic)
+ : (is_put ? Bytecodes::_putfield : Bytecodes::_getfield ));
+ }
// runtime resolving:
// resolved_klass = specified class (i.e., static receiver class)
diff --git a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp
index 8ed2b61a921..bfe1d1b4ca8 100644
--- a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp
+++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -33,10 +33,10 @@
#include "runtime/globals.hpp"
#include "utilities/ostream.hpp"
#include "utilities/macros.hpp"
+#include "gc_implementation/shared/spaceDecorator.hpp"
#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp"
#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
-#include "gc_implementation/shared/spaceDecorator.hpp"
#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
#endif // INCLUDE_ALL_GCS
diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp
index 6a1967daeda..0728997b769 100644
--- a/hotspot/src/share/vm/memory/collectorPolicy.cpp
+++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp
@@ -47,6 +47,11 @@
// CollectorPolicy methods.
+// Align down. If the aligning result in 0, return 'alignment'.
+static size_t restricted_align_down(size_t size, size_t alignment) {
+ return MAX2(alignment, align_size_down_(size, alignment));
+}
+
void CollectorPolicy::initialize_flags() {
assert(max_alignment() >= min_alignment(),
err_msg("max_alignment: " SIZE_FORMAT " less than min_alignment: " SIZE_FORMAT,
@@ -59,18 +64,24 @@ void CollectorPolicy::initialize_flags() {
vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified");
}
- if (MetaspaceSize > MaxMetaspaceSize) {
- MaxMetaspaceSize = MetaspaceSize;
- }
- MetaspaceSize = MAX2(min_alignment(), align_size_down_(MetaspaceSize, min_alignment()));
- // Don't increase Metaspace size limit above specified.
- MaxMetaspaceSize = align_size_down(MaxMetaspaceSize, max_alignment());
- if (MetaspaceSize > MaxMetaspaceSize) {
- MetaspaceSize = MaxMetaspaceSize;
+ if (!is_size_aligned(MaxMetaspaceSize, max_alignment())) {
+ FLAG_SET_ERGO(uintx, MaxMetaspaceSize,
+ restricted_align_down(MaxMetaspaceSize, max_alignment()));
}
- MinMetaspaceExpansion = MAX2(min_alignment(), align_size_down_(MinMetaspaceExpansion, min_alignment()));
- MaxMetaspaceExpansion = MAX2(min_alignment(), align_size_down_(MaxMetaspaceExpansion, min_alignment()));
+ if (MetaspaceSize > MaxMetaspaceSize) {
+ FLAG_SET_ERGO(uintx, MetaspaceSize, MaxMetaspaceSize);
+ }
+
+ if (!is_size_aligned(MetaspaceSize, min_alignment())) {
+ FLAG_SET_ERGO(uintx, MetaspaceSize,
+ restricted_align_down(MetaspaceSize, min_alignment()));
+ }
+
+ assert(MetaspaceSize <= MaxMetaspaceSize, "Must be");
+
+ MinMetaspaceExpansion = restricted_align_down(MinMetaspaceExpansion, min_alignment());
+ MaxMetaspaceExpansion = restricted_align_down(MaxMetaspaceExpansion, min_alignment());
MinHeapDeltaBytes = align_size_up(MinHeapDeltaBytes, min_alignment());
@@ -145,6 +156,30 @@ void CollectorPolicy::cleared_all_soft_refs() {
_all_soft_refs_clear = true;
}
+size_t CollectorPolicy::compute_max_alignment() {
+ // The card marking array and the offset arrays for old generations are
+ // committed in os pages as well. Make sure they are entirely full (to
+ // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
+ // byte entry and the os page size is 4096, the maximum heap size should
+ // be 512*4096 = 2MB aligned.
+
+ // There is only the GenRemSet in Hotspot and only the GenRemSet::CardTable
+ // is supported.
+ // Requirements of any new remembered set implementations must be added here.
+ size_t alignment = GenRemSet::max_alignment_constraint(GenRemSet::CardTable);
+
+ // Parallel GC does its own alignment of the generations to avoid requiring a
+ // large page (256M on some platforms) for the permanent generation. The
+ // other collectors should also be updated to do their own alignment and then
+ // this use of lcm() should be removed.
+ if (UseLargePages && !UseParallelGC) {
+ // in presence of large pages we have to make sure that our
+ // alignment is large page aware
+ alignment = lcm(os::large_page_size(), alignment);
+ }
+
+ return alignment;
+}
// GenCollectorPolicy methods.
@@ -175,29 +210,6 @@ void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size,
GCTimeRatio);
}
-size_t GenCollectorPolicy::compute_max_alignment() {
- // The card marking array and the offset arrays for old generations are
- // committed in os pages as well. Make sure they are entirely full (to
- // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
- // byte entry and the os page size is 4096, the maximum heap size should
- // be 512*4096 = 2MB aligned.
- size_t alignment = GenRemSet::max_alignment_constraint(rem_set_name());
-
- // Parallel GC does its own alignment of the generations to avoid requiring a
- // large page (256M on some platforms) for the permanent generation. The
- // other collectors should also be updated to do their own alignment and then
- // this use of lcm() should be removed.
- if (UseLargePages && !UseParallelGC) {
- // in presence of large pages we have to make sure that our
- // alignment is large page aware
- alignment = lcm(os::large_page_size(), alignment);
- }
-
- assert(alignment >= min_alignment(), "Must be");
-
- return alignment;
-}
-
void GenCollectorPolicy::initialize_flags() {
// All sizes must be multiples of the generation granularity.
set_min_alignment((uintx) Generation::GenGrain);
diff --git a/hotspot/src/share/vm/memory/collectorPolicy.hpp b/hotspot/src/share/vm/memory/collectorPolicy.hpp
index 4acf7ba780c..73fd177d7ba 100644
--- a/hotspot/src/share/vm/memory/collectorPolicy.hpp
+++ b/hotspot/src/share/vm/memory/collectorPolicy.hpp
@@ -98,6 +98,9 @@ class CollectorPolicy : public CHeapObj {
{}
public:
+ // Return maximum heap alignment that may be imposed by the policy
+ static size_t compute_max_alignment();
+
void set_min_alignment(size_t align) { _min_alignment = align; }
size_t min_alignment() { return _min_alignment; }
void set_max_alignment(size_t align) { _max_alignment = align; }
@@ -234,9 +237,6 @@ class GenCollectorPolicy : public CollectorPolicy {
// Try to allocate space by expanding the heap.
virtual HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab);
- // compute max heap alignment
- size_t compute_max_alignment();
-
// Scale the base_size by NewRation according to
// result = base_size / (NewRatio + 1)
// and align by min_alignment()
diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.hpp b/hotspot/src/share/vm/memory/genCollectedHeap.hpp
index 9ab9d1991df..8f814132a78 100644
--- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -148,6 +148,11 @@ public:
return gen_policy()->size_policy();
}
+ // Return the (conservative) maximum heap alignment
+ static size_t conservative_max_heap_alignment() {
+ return Generation::GenGrain;
+ }
+
size_t capacity() const;
size_t used() const;
diff --git a/hotspot/src/share/vm/memory/metablock.cpp b/hotspot/src/share/vm/memory/metablock.cpp
index 450d2c3193d..b6c6947e1ac 100644
--- a/hotspot/src/share/vm/memory/metablock.cpp
+++ b/hotspot/src/share/vm/memory/metablock.cpp
@@ -50,13 +50,6 @@
// Chunks, change Chunks so that they can be allocated out of a VirtualSpace.
size_t Metablock::_min_block_byte_size = sizeof(Metablock);
-#ifdef ASSERT
-size_t Metablock::_overhead =
- Chunk::aligned_overhead_size(sizeof(Metablock)) / BytesPerWord;
-#else
-size_t Metablock::_overhead = 0;
-#endif
-
// New blocks returned by the Metaspace are zero initialized.
// We should fix the constructors to not assume this instead.
Metablock* Metablock::initialize(MetaWord* p, size_t word_size) {
diff --git a/hotspot/src/share/vm/memory/metablock.hpp b/hotspot/src/share/vm/memory/metablock.hpp
index 220d3614818..fa4c6c0b445 100644
--- a/hotspot/src/share/vm/memory/metablock.hpp
+++ b/hotspot/src/share/vm/memory/metablock.hpp
@@ -48,7 +48,6 @@ class Metablock VALUE_OBJ_CLASS_SPEC {
} _header;
} _block;
static size_t _min_block_byte_size;
- static size_t _overhead;
typedef union block_t Block;
typedef struct header_t Header;
@@ -73,7 +72,6 @@ class Metablock VALUE_OBJ_CLASS_SPEC {
void set_prev(Metablock* v) { _block._header._prev = v; }
static size_t min_block_byte_size() { return _min_block_byte_size; }
- static size_t overhead() { return _overhead; }
bool is_free() { return header()->_word_size != 0; }
void clear_next() { set_next(NULL); }
diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp
index cd46888c9c2..c12c0b8637b 100644
--- a/hotspot/src/share/vm/memory/metaspace.cpp
+++ b/hotspot/src/share/vm/memory/metaspace.cpp
@@ -51,7 +51,7 @@ const bool metaspace_slow_verify = false;
// Parameters for stress mode testing
const uint metadata_deallocate_a_lot_block = 10;
const uint metadata_deallocate_a_lock_chunk = 3;
-size_t const allocation_from_dictionary_limit = 64 * K;
+size_t const allocation_from_dictionary_limit = 4 * K;
MetaWord* last_allocated = 0;
@@ -177,8 +177,8 @@ class ChunkManager VALUE_OBJ_CLASS_SPEC {
void return_chunks(ChunkIndex index, Metachunk* chunks);
// Total of the space in the free chunks list
- size_t free_chunks_total();
- size_t free_chunks_total_in_bytes();
+ size_t free_chunks_total_words();
+ size_t free_chunks_total_bytes();
// Number of chunks in the free chunks list
size_t free_chunks_count();
@@ -228,6 +228,10 @@ class BlockFreelist VALUE_OBJ_CLASS_SPEC {
BlockTreeDictionary* _dictionary;
static Metablock* initialize_free_chunk(MetaWord* p, size_t word_size);
+ // Only allocate and split from freelist if the size of the allocation
+ // is at least 1/4th the size of the available block.
+ const static int WasteMultiplier = 4;
+
// Accessors
BlockTreeDictionary* dictionary() const { return _dictionary; }
@@ -287,6 +291,10 @@ class VirtualSpaceNode : public CHeapObj {
MetaWord* bottom() const { return (MetaWord*) _virtual_space.low(); }
MetaWord* end() const { return (MetaWord*) _virtual_space.high(); }
+ size_t reserved_words() const { return _virtual_space.reserved_size() / BytesPerWord; }
+ size_t expanded_words() const { return _virtual_space.committed_size() / BytesPerWord; }
+ size_t committed_words() const { return _virtual_space.actual_committed_size() / BytesPerWord; }
+
// address of next available space in _virtual_space;
// Accessors
VirtualSpaceNode* next() { return _next; }
@@ -323,12 +331,10 @@ class VirtualSpaceNode : public CHeapObj {
// Allocate a chunk from the virtual space and return it.
Metachunk* get_chunk_vs(size_t chunk_word_size);
- Metachunk* get_chunk_vs_with_expand(size_t chunk_word_size);
// Expands/shrinks the committed space in a virtual space. Delegates
// to Virtualspace
bool expand_by(size_t words, bool pre_touch = false);
- bool shrink_by(size_t words);
// In preparation for deleting this node, remove all the chunks
// in the node from any freelist.
@@ -336,8 +342,6 @@ class VirtualSpaceNode : public CHeapObj {
#ifdef ASSERT
// Debug support
- static void verify_virtual_space_total();
- static void verify_virtual_space_count();
void mangle();
#endif
@@ -423,10 +427,13 @@ class VirtualSpaceList : public CHeapObj {
// Can this virtual list allocate >1 spaces? Also, used to determine
// whether to allocate unlimited small chunks in this virtual space
bool _is_class;
- bool can_grow() const { return !is_class() || !UseCompressedKlassPointers; }
+ bool can_grow() const { return !is_class() || !UseCompressedClassPointers; }
- // Sum of space in all virtual spaces and number of virtual spaces
- size_t _virtual_space_total;
+ // Sum of reserved and committed memory in the virtual spaces
+ size_t _reserved_words;
+ size_t _committed_words;
+
+ // Number of virtual spaces
size_t _virtual_space_count;
~VirtualSpaceList();
@@ -440,7 +447,7 @@ class VirtualSpaceList : public CHeapObj {
_current_virtual_space = v;
}
- void link_vs(VirtualSpaceNode* new_entry, size_t vs_word_size);
+ void link_vs(VirtualSpaceNode* new_entry);
// Get another virtual space and add it to the list. This
// is typically prompted by a failed attempt to allocate a chunk
@@ -457,6 +464,8 @@ class VirtualSpaceList : public CHeapObj {
size_t grow_chunks_by_words,
size_t medium_chunk_bunch);
+ bool expand_by(VirtualSpaceNode* node, size_t word_size, bool pre_touch = false);
+
// Get the first chunk for a Metaspace. Used for
// special cases such as the boot class loader, reflection
// class loader and anonymous class loader.
@@ -472,10 +481,15 @@ class VirtualSpaceList : public CHeapObj {
// Allocate the first virtualspace.
void initialize(size_t word_size);
- size_t virtual_space_total() { return _virtual_space_total; }
+ size_t reserved_words() { return _reserved_words; }
+ size_t reserved_bytes() { return reserved_words() * BytesPerWord; }
+ size_t committed_words() { return _committed_words; }
+ size_t committed_bytes() { return committed_words() * BytesPerWord; }
- void inc_virtual_space_total(size_t v);
- void dec_virtual_space_total(size_t v);
+ void inc_reserved_words(size_t v);
+ void dec_reserved_words(size_t v);
+ void inc_committed_words(size_t v);
+ void dec_committed_words(size_t v);
void inc_virtual_space_count();
void dec_virtual_space_count();
@@ -623,6 +637,7 @@ class SpaceManager : public CHeapObj {
// Add chunk to the list of chunks in use
void add_chunk(Metachunk* v, bool make_current);
+ void retire_current_chunk();
Mutex* lock() const { return _lock; }
@@ -722,9 +737,7 @@ class SpaceManager : public CHeapObj {
// MinChunkSize is a placeholder for the real minimum size JJJ
size_t byte_size = word_size * BytesPerWord;
- size_t byte_size_with_overhead = byte_size + Metablock::overhead();
-
- size_t raw_bytes_size = MAX2(byte_size_with_overhead,
+ size_t raw_bytes_size = MAX2(byte_size,
Metablock::min_block_byte_size());
raw_bytes_size = ARENA_ALIGN(raw_bytes_size);
size_t raw_word_size = raw_bytes_size / BytesPerWord;
@@ -807,12 +820,25 @@ MetaWord* BlockFreelist::get_block(size_t word_size) {
}
Metablock* free_block =
- dictionary()->get_chunk(word_size, FreeBlockDictionary::exactly);
+ dictionary()->get_chunk(word_size, FreeBlockDictionary::atLeast);
if (free_block == NULL) {
return NULL;
}
- return (MetaWord*) free_block;
+ const size_t block_size = free_block->size();
+ if (block_size > WasteMultiplier * word_size) {
+ return_block((MetaWord*)free_block, block_size);
+ return NULL;
+ }
+
+ MetaWord* new_block = (MetaWord*)free_block;
+ assert(block_size >= word_size, "Incorrect size of block from freelist");
+ const size_t unused = block_size - word_size;
+ if (unused >= TreeChunk::min_size()) {
+ return_block(new_block + word_size, unused);
+ }
+
+ return new_block;
}
void BlockFreelist::print_on(outputStream* st) const {
@@ -855,9 +881,9 @@ Metachunk* VirtualSpaceNode::take_from_committed(size_t chunk_word_size) {
if (!is_available(chunk_word_size)) {
if (TraceMetadataChunkAllocation) {
- tty->print("VirtualSpaceNode::take_from_committed() not available %d words ", chunk_word_size);
+ gclog_or_tty->print("VirtualSpaceNode::take_from_committed() not available %d words ", chunk_word_size);
// Dump some information about the virtual space that is nearly full
- print_on(tty);
+ print_on(gclog_or_tty);
}
return NULL;
}
@@ -878,20 +904,11 @@ bool VirtualSpaceNode::expand_by(size_t words, bool pre_touch) {
if (TraceMetavirtualspaceAllocation && !result) {
gclog_or_tty->print_cr("VirtualSpaceNode::expand_by() failed "
"for byte size " SIZE_FORMAT, bytes);
- virtual_space()->print();
+ virtual_space()->print_on(gclog_or_tty);
}
return result;
}
-// Shrink the virtual space (commit more of the reserved space)
-bool VirtualSpaceNode::shrink_by(size_t words) {
- size_t bytes = words * BytesPerWord;
- virtual_space()->shrink_by(bytes);
- return true;
-}
-
-// Add another chunk to the chunk list.
-
Metachunk* VirtualSpaceNode::get_chunk_vs(size_t chunk_word_size) {
assert_lock_strong(SpaceManager::expand_lock());
Metachunk* result = take_from_committed(chunk_word_size);
@@ -901,23 +918,6 @@ Metachunk* VirtualSpaceNode::get_chunk_vs(size_t chunk_word_size) {
return result;
}
-Metachunk* VirtualSpaceNode::get_chunk_vs_with_expand(size_t chunk_word_size) {
- assert_lock_strong(SpaceManager::expand_lock());
-
- Metachunk* new_chunk = get_chunk_vs(chunk_word_size);
-
- if (new_chunk == NULL) {
- // Only a small part of the virtualspace is committed when first
- // allocated so committing more here can be expected.
- size_t page_size_words = os::vm_page_size() / BytesPerWord;
- size_t aligned_expand_vs_by_words = align_size_up(chunk_word_size,
- page_size_words);
- expand_by(aligned_expand_vs_by_words, false);
- new_chunk = get_chunk_vs(chunk_word_size);
- }
- return new_chunk;
-}
-
bool VirtualSpaceNode::initialize() {
if (!_rs.is_reserved()) {
@@ -977,13 +977,22 @@ VirtualSpaceList::~VirtualSpaceList() {
}
}
-void VirtualSpaceList::inc_virtual_space_total(size_t v) {
+void VirtualSpaceList::inc_reserved_words(size_t v) {
assert_lock_strong(SpaceManager::expand_lock());
- _virtual_space_total = _virtual_space_total + v;
+ _reserved_words = _reserved_words + v;
}
-void VirtualSpaceList::dec_virtual_space_total(size_t v) {
+void VirtualSpaceList::dec_reserved_words(size_t v) {
assert_lock_strong(SpaceManager::expand_lock());
- _virtual_space_total = _virtual_space_total - v;
+ _reserved_words = _reserved_words - v;
+}
+
+void VirtualSpaceList::inc_committed_words(size_t v) {
+ assert_lock_strong(SpaceManager::expand_lock());
+ _committed_words = _committed_words + v;
+}
+void VirtualSpaceList::dec_committed_words(size_t v) {
+ assert_lock_strong(SpaceManager::expand_lock());
+ _committed_words = _committed_words - v;
}
void VirtualSpaceList::inc_virtual_space_count() {
@@ -1034,7 +1043,8 @@ void VirtualSpaceList::purge() {
}
vsl->purge(chunk_manager());
- dec_virtual_space_total(vsl->reserved()->word_size());
+ dec_reserved_words(vsl->reserved_words());
+ dec_committed_words(vsl->committed_words());
dec_virtual_space_count();
purged_vsl = vsl;
delete vsl;
@@ -1062,12 +1072,12 @@ size_t VirtualSpaceList::used_words_sum() {
// Sum used region [bottom, top) in each virtualspace
allocated_by_vs += vsl->used_words_in_vs();
}
- assert(allocated_by_vs >= chunk_manager()->free_chunks_total(),
+ assert(allocated_by_vs >= chunk_manager()->free_chunks_total_words(),
err_msg("Total in free chunks " SIZE_FORMAT
" greater than total from virtual_spaces " SIZE_FORMAT,
- allocated_by_vs, chunk_manager()->free_chunks_total()));
+ allocated_by_vs, chunk_manager()->free_chunks_total_words()));
size_t used =
- allocated_by_vs - chunk_manager()->free_chunks_total();
+ allocated_by_vs - chunk_manager()->free_chunks_total_words();
return used;
}
@@ -1088,7 +1098,8 @@ VirtualSpaceList::VirtualSpaceList(size_t word_size ) :
_is_class(false),
_virtual_space_list(NULL),
_current_virtual_space(NULL),
- _virtual_space_total(0),
+ _reserved_words(0),
+ _committed_words(0),
_virtual_space_count(0) {
MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag);
@@ -1105,7 +1116,8 @@ VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) :
_is_class(true),
_virtual_space_list(NULL),
_current_virtual_space(NULL),
- _virtual_space_total(0),
+ _reserved_words(0),
+ _committed_words(0),
_virtual_space_count(0) {
MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag);
@@ -1115,7 +1127,7 @@ VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) :
_chunk_manager.free_chunks(SmallIndex)->set_size(ClassSmallChunk);
_chunk_manager.free_chunks(MediumIndex)->set_size(ClassMediumChunk);
assert(succeeded, " VirtualSpaceList initialization should not fail");
- link_vs(class_entry, rs.size()/BytesPerWord);
+ link_vs(class_entry);
}
size_t VirtualSpaceList::free_bytes() {
@@ -1138,31 +1150,47 @@ bool VirtualSpaceList::grow_vs(size_t vs_word_size) {
delete new_entry;
return false;
} else {
+ assert(new_entry->reserved_words() == vs_word_size, "Must be");
// ensure lock-free iteration sees fully initialized node
OrderAccess::storestore();
- link_vs(new_entry, vs_word_size);
+ link_vs(new_entry);
return true;
}
}
-void VirtualSpaceList::link_vs(VirtualSpaceNode* new_entry, size_t vs_word_size) {
+void VirtualSpaceList::link_vs(VirtualSpaceNode* new_entry) {
if (virtual_space_list() == NULL) {
set_virtual_space_list(new_entry);
} else {
current_virtual_space()->set_next(new_entry);
}
set_current_virtual_space(new_entry);
- inc_virtual_space_total(vs_word_size);
+ inc_reserved_words(new_entry->reserved_words());
+ inc_committed_words(new_entry->committed_words());
inc_virtual_space_count();
#ifdef ASSERT
new_entry->mangle();
#endif
if (TraceMetavirtualspaceAllocation && Verbose) {
VirtualSpaceNode* vsl = current_virtual_space();
- vsl->print_on(tty);
+ vsl->print_on(gclog_or_tty);
}
}
+bool VirtualSpaceList::expand_by(VirtualSpaceNode* node, size_t word_size, bool pre_touch) {
+ size_t before = node->committed_words();
+
+ bool result = node->expand_by(word_size, pre_touch);
+
+ size_t after = node->committed_words();
+
+ // after and before can be the same if the memory was pre-committed.
+ assert(after >= before, "Must be");
+ inc_committed_words(after - before);
+
+ return result;
+}
+
Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
size_t grow_chunks_by_words,
size_t medium_chunk_bunch) {
@@ -1186,7 +1214,7 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
size_t aligned_expand_vs_by_words = align_size_up(expand_vs_by_words,
page_size_words);
bool vs_expanded =
- current_virtual_space()->expand_by(aligned_expand_vs_by_words, false);
+ expand_by(current_virtual_space(), aligned_expand_vs_by_words);
if (!vs_expanded) {
// Should the capacity of the metaspaces be expanded for
// this allocation? If it's the virtual space for classes and is
@@ -1197,7 +1225,14 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
MAX2((size_t)VirtualSpaceSize, aligned_expand_vs_by_words);
if (grow_vs(grow_vs_words)) {
// Got it. It's on the list now. Get a chunk from it.
- next = current_virtual_space()->get_chunk_vs_with_expand(grow_chunks_by_words);
+ assert(current_virtual_space()->expanded_words() == 0,
+ "New virtuals space nodes should not have expanded");
+
+ size_t grow_chunks_by_words_aligned = align_size_up(grow_chunks_by_words,
+ page_size_words);
+ // We probably want to expand by aligned_expand_vs_by_words here.
+ expand_by(current_virtual_space(), grow_chunks_by_words_aligned);
+ next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words);
}
} else {
// Allocation will fail and induce a GC
@@ -1307,7 +1342,7 @@ bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) {
// reserved space, because this is a larger space prereserved for compressed
// class pointers.
if (!FLAG_IS_DEFAULT(MaxMetaspaceSize)) {
- size_t real_allocated = Metaspace::space_list()->virtual_space_total() +
+ size_t real_allocated = Metaspace::space_list()->reserved_words() +
MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType);
if (real_allocated >= MaxMetaspaceSize) {
return false;
@@ -1508,7 +1543,7 @@ void Metadebug::deallocate_chunk_a_lot(SpaceManager* sm,
sm->sum_count_in_chunks_in_use());
dummy_chunk->print_on(gclog_or_tty);
gclog_or_tty->print_cr(" Free chunks total %d count %d",
- vsl->chunk_manager()->free_chunks_total(),
+ vsl->chunk_manager()->free_chunks_total_words(),
vsl->chunk_manager()->free_chunks_count());
}
}
@@ -1565,12 +1600,12 @@ bool Metadebug::test_metadata_failure() {
// ChunkManager methods
-size_t ChunkManager::free_chunks_total() {
+size_t ChunkManager::free_chunks_total_words() {
return _free_chunks_total;
}
-size_t ChunkManager::free_chunks_total_in_bytes() {
- return free_chunks_total() * BytesPerWord;
+size_t ChunkManager::free_chunks_total_bytes() {
+ return free_chunks_total_words() * BytesPerWord;
}
size_t ChunkManager::free_chunks_count() {
@@ -1698,9 +1733,9 @@ void ChunkManager::chunk_freelist_deallocate(Metachunk* chunk) {
assert_lock_strong(SpaceManager::expand_lock());
slow_locked_verify();
if (TraceMetadataChunkAllocation) {
- tty->print_cr("ChunkManager::chunk_freelist_deallocate: chunk "
- PTR_FORMAT " size " SIZE_FORMAT,
- chunk, chunk->word_size());
+ gclog_or_tty->print_cr("ChunkManager::chunk_freelist_deallocate: chunk "
+ PTR_FORMAT " size " SIZE_FORMAT,
+ chunk, chunk->word_size());
}
free_chunks_put(chunk);
}
@@ -1729,9 +1764,9 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) {
dec_free_chunks_total(chunk->capacity_word_size());
if (TraceMetadataChunkAllocation && Verbose) {
- tty->print_cr("ChunkManager::free_chunks_get: free_list "
- PTR_FORMAT " head " PTR_FORMAT " size " SIZE_FORMAT,
- free_list, chunk, chunk->word_size());
+ gclog_or_tty->print_cr("ChunkManager::free_chunks_get: free_list "
+ PTR_FORMAT " head " PTR_FORMAT " size " SIZE_FORMAT,
+ free_list, chunk, chunk->word_size());
}
} else {
chunk = humongous_dictionary()->get_chunk(
@@ -1741,10 +1776,10 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) {
if (chunk != NULL) {
if (TraceMetadataHumongousAllocation) {
size_t waste = chunk->word_size() - word_size;
- tty->print_cr("Free list allocate humongous chunk size " SIZE_FORMAT
- " for requested size " SIZE_FORMAT
- " waste " SIZE_FORMAT,
- chunk->word_size(), word_size, waste);
+ gclog_or_tty->print_cr("Free list allocate humongous chunk size "
+ SIZE_FORMAT " for requested size " SIZE_FORMAT
+ " waste " SIZE_FORMAT,
+ chunk->word_size(), word_size, waste);
}
// Chunk is being removed from the chunks free list.
dec_free_chunks_total(chunk->capacity_word_size());
@@ -1786,10 +1821,10 @@ Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) {
} else {
list_count = humongous_dictionary()->total_count();
}
- tty->print("ChunkManager::chunk_freelist_allocate: " PTR_FORMAT " chunk "
- PTR_FORMAT " size " SIZE_FORMAT " count " SIZE_FORMAT " ",
- this, chunk, chunk->word_size(), list_count);
- locked_print_free_chunks(tty);
+ gclog_or_tty->print("ChunkManager::chunk_freelist_allocate: " PTR_FORMAT " chunk "
+ PTR_FORMAT " size " SIZE_FORMAT " count " SIZE_FORMAT " ",
+ this, chunk, chunk->word_size(), list_count);
+ locked_print_free_chunks(gclog_or_tty);
}
return chunk;
@@ -2278,6 +2313,7 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) {
ChunkIndex index = ChunkManager::list_index(new_chunk->word_size());
if (index != HumongousIndex) {
+ retire_current_chunk();
set_current_chunk(new_chunk);
new_chunk->set_next(chunks_in_use(index));
set_chunks_in_use(index, new_chunk);
@@ -2308,7 +2344,17 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) {
sum_count_in_chunks_in_use());
new_chunk->print_on(gclog_or_tty);
if (vs_list() != NULL) {
- vs_list()->chunk_manager()->locked_print_free_chunks(tty);
+ vs_list()->chunk_manager()->locked_print_free_chunks(gclog_or_tty);
+ }
+ }
+}
+
+void SpaceManager::retire_current_chunk() {
+ if (current_chunk() != NULL) {
+ size_t remaining_words = current_chunk()->free_word_size();
+ if (remaining_words >= TreeChunk::min_size()) {
+ block_freelists()->return_block(current_chunk()->allocate(remaining_words), remaining_words);
+ inc_used_metrics(remaining_words);
}
}
}
@@ -2320,10 +2366,10 @@ Metachunk* SpaceManager::get_new_chunk(size_t word_size,
grow_chunks_by_words,
medium_chunk_bunch());
- if (TraceMetadataHumongousAllocation &&
+ if (TraceMetadataHumongousAllocation && next != NULL &&
SpaceManager::is_humongous(next->word_size())) {
- gclog_or_tty->print_cr(" new humongous chunk word size " PTR_FORMAT,
- next->word_size());
+ gclog_or_tty->print_cr(" new humongous chunk word size "
+ PTR_FORMAT, next->word_size());
}
return next;
@@ -2441,9 +2487,6 @@ void SpaceManager::dump(outputStream* const out) const {
curr = curr->next()) {
out->print("%d) ", i++);
curr->print_on(out);
- if (TraceMetadataChunkAllocation && Verbose) {
- block_freelists()->print_on(out);
- }
curr_total += curr->word_size();
used += curr->used_word_size();
capacity += curr->capacity_word_size();
@@ -2451,6 +2494,10 @@ void SpaceManager::dump(outputStream* const out) const {
}
}
+ if (TraceMetadataChunkAllocation && Verbose) {
+ block_freelists()->print_on(out);
+ }
+
size_t free = current_chunk() == NULL ? 0 : current_chunk()->free_word_size();
// Free space isn't wasted.
waste -= free;
@@ -2538,13 +2585,13 @@ size_t MetaspaceAux::used_bytes_slow(Metaspace::MetadataType mdtype) {
return used * BytesPerWord;
}
-size_t MetaspaceAux::free_in_bytes(Metaspace::MetadataType mdtype) {
+size_t MetaspaceAux::free_bytes_slow(Metaspace::MetadataType mdtype) {
size_t free = 0;
ClassLoaderDataGraphMetaspaceIterator iter;
while (iter.repeat()) {
Metaspace* msp = iter.get_next();
if (msp != NULL) {
- free += msp->free_words(mdtype);
+ free += msp->free_words_slow(mdtype);
}
}
return free * BytesPerWord;
@@ -2567,34 +2614,56 @@ size_t MetaspaceAux::capacity_bytes_slow(Metaspace::MetadataType mdtype) {
return capacity * BytesPerWord;
}
-size_t MetaspaceAux::reserved_in_bytes(Metaspace::MetadataType mdtype) {
- VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
- return list == NULL ? 0 : list->virtual_space_total();
+size_t MetaspaceAux::capacity_bytes_slow() {
+#ifdef PRODUCT
+ // Use allocated_capacity_bytes() in PRODUCT instead of this function.
+ guarantee(false, "Should not call capacity_bytes_slow() in the PRODUCT");
+#endif
+ size_t class_capacity = capacity_bytes_slow(Metaspace::ClassType);
+ size_t non_class_capacity = capacity_bytes_slow(Metaspace::NonClassType);
+ assert(allocated_capacity_bytes() == class_capacity + non_class_capacity,
+ err_msg("bad accounting: allocated_capacity_bytes() " SIZE_FORMAT
+ " class_capacity + non_class_capacity " SIZE_FORMAT
+ " class_capacity " SIZE_FORMAT " non_class_capacity " SIZE_FORMAT,
+ allocated_capacity_bytes(), class_capacity + non_class_capacity,
+ class_capacity, non_class_capacity));
+
+ return class_capacity + non_class_capacity;
}
-size_t MetaspaceAux::min_chunk_size() { return Metaspace::first_chunk_word_size(); }
+size_t MetaspaceAux::reserved_bytes(Metaspace::MetadataType mdtype) {
+ VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
+ return list == NULL ? 0 : list->reserved_bytes();
+}
-size_t MetaspaceAux::free_chunks_total(Metaspace::MetadataType mdtype) {
+size_t MetaspaceAux::committed_bytes(Metaspace::MetadataType mdtype) {
+ VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
+ return list == NULL ? 0 : list->committed_bytes();
+}
+
+size_t MetaspaceAux::min_chunk_size_words() { return Metaspace::first_chunk_word_size(); }
+
+size_t MetaspaceAux::free_chunks_total_words(Metaspace::MetadataType mdtype) {
VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
if (list == NULL) {
return 0;
}
ChunkManager* chunk = list->chunk_manager();
chunk->slow_verify();
- return chunk->free_chunks_total();
+ return chunk->free_chunks_total_words();
}
-size_t MetaspaceAux::free_chunks_total_in_bytes(Metaspace::MetadataType mdtype) {
- return free_chunks_total(mdtype) * BytesPerWord;
+size_t MetaspaceAux::free_chunks_total_bytes(Metaspace::MetadataType mdtype) {
+ return free_chunks_total_words(mdtype) * BytesPerWord;
}
-size_t MetaspaceAux::free_chunks_total() {
- return free_chunks_total(Metaspace::ClassType) +
- free_chunks_total(Metaspace::NonClassType);
+size_t MetaspaceAux::free_chunks_total_words() {
+ return free_chunks_total_words(Metaspace::ClassType) +
+ free_chunks_total_words(Metaspace::NonClassType);
}
-size_t MetaspaceAux::free_chunks_total_in_bytes() {
- return free_chunks_total() * BytesPerWord;
+size_t MetaspaceAux::free_chunks_total_bytes() {
+ return free_chunks_total_words() * BytesPerWord;
}
void MetaspaceAux::print_metaspace_change(size_t prev_metadata_used) {
@@ -2605,14 +2674,14 @@ void MetaspaceAux::print_metaspace_change(size_t prev_metadata_used) {
"(" SIZE_FORMAT ")",
prev_metadata_used,
allocated_used_bytes(),
- reserved_in_bytes());
+ reserved_bytes());
} else {
gclog_or_tty->print(" " SIZE_FORMAT "K"
"->" SIZE_FORMAT "K"
"(" SIZE_FORMAT "K)",
- prev_metadata_used / K,
- allocated_used_bytes() / K,
- reserved_in_bytes()/ K);
+ prev_metadata_used/K,
+ allocated_used_bytes()/K,
+ reserved_bytes()/K);
}
gclog_or_tty->print("]");
@@ -2625,14 +2694,14 @@ void MetaspaceAux::print_on(outputStream* out) {
out->print_cr(" Metaspace total "
SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
" reserved " SIZE_FORMAT "K",
- allocated_capacity_bytes()/K, allocated_used_bytes()/K, reserved_in_bytes()/K);
+ allocated_capacity_bytes()/K, allocated_used_bytes()/K, reserved_bytes()/K);
out->print_cr(" data space "
SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
" reserved " SIZE_FORMAT "K",
allocated_capacity_bytes(nct)/K,
allocated_used_bytes(nct)/K,
- reserved_in_bytes(nct)/K);
+ reserved_bytes(nct)/K);
if (Metaspace::using_class_space()) {
Metaspace::MetadataType ct = Metaspace::ClassType;
out->print_cr(" class space "
@@ -2640,17 +2709,17 @@ void MetaspaceAux::print_on(outputStream* out) {
" reserved " SIZE_FORMAT "K",
allocated_capacity_bytes(ct)/K,
allocated_used_bytes(ct)/K,
- reserved_in_bytes(ct)/K);
+ reserved_bytes(ct)/K);
}
}
// Print information for class space and data space separately.
// This is almost the same as above.
void MetaspaceAux::print_on(outputStream* out, Metaspace::MetadataType mdtype) {
- size_t free_chunks_capacity_bytes = free_chunks_total_in_bytes(mdtype);
+ size_t free_chunks_capacity_bytes = free_chunks_total_bytes(mdtype);
size_t capacity_bytes = capacity_bytes_slow(mdtype);
size_t used_bytes = used_bytes_slow(mdtype);
- size_t free_bytes = free_in_bytes(mdtype);
+ size_t free_bytes = free_bytes_slow(mdtype);
size_t used_and_free = used_bytes + free_bytes +
free_chunks_capacity_bytes;
out->print_cr(" Chunk accounting: used in chunks " SIZE_FORMAT
@@ -2836,7 +2905,7 @@ void Metaspace::set_narrow_klass_base_and_shift(address metaspace_base, address
// to work with compressed klass pointers.
bool Metaspace::can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base) {
assert(cds_base != 0 && UseSharedSpaces, "Only use with CDS");
- assert(UseCompressedKlassPointers, "Only use with CompressedKlassPtrs");
+ assert(UseCompressedClassPointers, "Only use with CompressedKlassPtrs");
address lower_base = MIN2((address)metaspace_base, cds_base);
address higher_address = MAX2((address)(cds_base + FileMapInfo::shared_spaces_size()),
(address)(metaspace_base + class_metaspace_size()));
@@ -2846,7 +2915,7 @@ bool Metaspace::can_use_cds_with_metaspace_addr(char* metaspace_base, address cd
// Try to allocate the metaspace at the requested addr.
void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base) {
assert(using_class_space(), "called improperly");
- assert(UseCompressedKlassPointers, "Only use with CompressedKlassPtrs");
+ assert(UseCompressedClassPointers, "Only use with CompressedKlassPtrs");
assert(class_metaspace_size() < KlassEncodingMetaspaceMax,
"Metaspace size is too big");
@@ -2869,9 +2938,9 @@ void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, a
// If no successful allocation then try to allocate the space anywhere. If
// that fails then OOM doom. At this point we cannot try allocating the
- // metaspace as if UseCompressedKlassPointers is off because too much
- // initialization has happened that depends on UseCompressedKlassPointers.
- // So, UseCompressedKlassPointers cannot be turned off at this point.
+ // metaspace as if UseCompressedClassPointers is off because too much
+ // initialization has happened that depends on UseCompressedClassPointers.
+ // So, UseCompressedClassPointers cannot be turned off at this point.
if (!metaspace_rs.is_reserved()) {
metaspace_rs = ReservedSpace(class_metaspace_size(),
os::vm_allocation_granularity(), false);
@@ -2904,12 +2973,12 @@ void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, a
}
}
-// For UseCompressedKlassPointers the class space is reserved above the top of
+// For UseCompressedClassPointers the class space is reserved above the top of
// the Java heap. The argument passed in is at the base of the compressed space.
void Metaspace::initialize_class_space(ReservedSpace rs) {
// The reserved space size may be bigger because of alignment, esp with UseLargePages
- assert(rs.size() >= ClassMetaspaceSize,
- err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), ClassMetaspaceSize));
+ assert(rs.size() >= CompressedClassSpaceSize,
+ err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), CompressedClassSpaceSize));
assert(using_class_space(), "Must be using class space");
_class_space_list = new VirtualSpaceList(rs);
}
@@ -2921,7 +2990,7 @@ void Metaspace::global_initialize() {
int max_alignment = os::vm_page_size();
size_t cds_total = 0;
- set_class_metaspace_size(align_size_up(ClassMetaspaceSize,
+ set_class_metaspace_size(align_size_up(CompressedClassSpaceSize,
os::vm_allocation_granularity()));
MetaspaceShared::set_max_alignment(max_alignment);
@@ -2941,8 +3010,8 @@ void Metaspace::global_initialize() {
#ifdef _LP64
// Set the compressed klass pointer base so that decoding of these pointers works
// properly when creating the shared archive.
- assert(UseCompressedOops && UseCompressedKlassPointers,
- "UseCompressedOops and UseCompressedKlassPointers must be set");
+ assert(UseCompressedOops && UseCompressedClassPointers,
+ "UseCompressedOops and UseCompressedClassPointers must be set");
Universe::set_narrow_klass_base((address)_space_list->current_virtual_space()->bottom());
if (TraceMetavirtualspaceAllocation && Verbose) {
gclog_or_tty->print_cr("Setting_narrow_klass_base to Address: " PTR_FORMAT,
@@ -2979,7 +3048,7 @@ void Metaspace::global_initialize() {
}
#ifdef _LP64
- // If UseCompressedKlassPointers is set then allocate the metaspace area
+ // If UseCompressedClassPointers is set then allocate the metaspace area
// above the heap and above the CDS area (if it exists).
if (using_class_space()) {
if (UseSharedSpaces) {
@@ -2997,7 +3066,7 @@ void Metaspace::global_initialize() {
// on the medium chunk list. The next chunk will be small and progress
// from there. This size calculated by -version.
_first_class_chunk_word_size = MIN2((size_t)MediumChunk*6,
- (ClassMetaspaceSize/BytesPerWord)*2);
+ (CompressedClassSpaceSize/BytesPerWord)*2);
_first_class_chunk_word_size = align_word_size_up(_first_class_chunk_word_size);
// Arbitrarily set the initial virtual space to a multiple
// of the boot class loader size.
@@ -3064,7 +3133,7 @@ size_t Metaspace::align_word_size_up(size_t word_size) {
MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) {
// DumpSharedSpaces doesn't use class metadata area (yet)
- // Also, don't use class_vsm() unless UseCompressedKlassPointers is true.
+ // Also, don't use class_vsm() unless UseCompressedClassPointers is true.
if (mdtype == ClassType && using_class_space()) {
return class_vsm()->allocate(word_size);
} else {
@@ -3103,7 +3172,7 @@ size_t Metaspace::used_words_slow(MetadataType mdtype) const {
}
}
-size_t Metaspace::free_words(MetadataType mdtype) const {
+size_t Metaspace::free_words_slow(MetadataType mdtype) const {
if (mdtype == ClassType) {
return using_class_space() ? class_vsm()->sum_free_in_chunks_in_use() : 0;
} else {
@@ -3213,7 +3282,7 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
MetaspaceAux::dump(gclog_or_tty);
}
// -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
- const char* space_string = (mdtype == ClassType) ? "Class Metadata space" :
+ const char* space_string = (mdtype == ClassType) ? "Compressed class space" :
"Metadata space";
report_java_out_of_memory(space_string);
@@ -3311,3 +3380,59 @@ void Metaspace::dump(outputStream* const out) const {
class_vsm()->dump(out);
}
}
+
+/////////////// Unit tests ///////////////
+
+#ifndef PRODUCT
+
+class MetaspaceAuxTest : AllStatic {
+ public:
+ static void test_reserved() {
+ size_t reserved = MetaspaceAux::reserved_bytes();
+
+ assert(reserved > 0, "assert");
+
+ size_t committed = MetaspaceAux::committed_bytes();
+ assert(committed <= reserved, "assert");
+
+ size_t reserved_metadata = MetaspaceAux::reserved_bytes(Metaspace::NonClassType);
+ assert(reserved_metadata > 0, "assert");
+ assert(reserved_metadata <= reserved, "assert");
+
+ if (UseCompressedClassPointers) {
+ size_t reserved_class = MetaspaceAux::reserved_bytes(Metaspace::ClassType);
+ assert(reserved_class > 0, "assert");
+ assert(reserved_class < reserved, "assert");
+ }
+ }
+
+ static void test_committed() {
+ size_t committed = MetaspaceAux::committed_bytes();
+
+ assert(committed > 0, "assert");
+
+ size_t reserved = MetaspaceAux::reserved_bytes();
+ assert(committed <= reserved, "assert");
+
+ size_t committed_metadata = MetaspaceAux::committed_bytes(Metaspace::NonClassType);
+ assert(committed_metadata > 0, "assert");
+ assert(committed_metadata <= committed, "assert");
+
+ if (UseCompressedClassPointers) {
+ size_t committed_class = MetaspaceAux::committed_bytes(Metaspace::ClassType);
+ assert(committed_class > 0, "assert");
+ assert(committed_class < committed, "assert");
+ }
+ }
+
+ static void test() {
+ test_reserved();
+ test_committed();
+ }
+};
+
+void MetaspaceAux_test() {
+ MetaspaceAuxTest::test();
+}
+
+#endif
diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp
index 88f089494d3..242fa61b1cc 100644
--- a/hotspot/src/share/vm/memory/metaspace.hpp
+++ b/hotspot/src/share/vm/memory/metaspace.hpp
@@ -182,9 +182,8 @@ class Metaspace : public CHeapObj {
char* bottom() const;
size_t used_words_slow(MetadataType mdtype) const;
- size_t free_words(MetadataType mdtype) const;
+ size_t free_words_slow(MetadataType mdtype) const;
size_t capacity_words_slow(MetadataType mdtype) const;
- size_t waste_words(MetadataType mdtype) const;
size_t used_bytes_slow(MetadataType mdtype) const;
size_t capacity_bytes_slow(MetadataType mdtype) const;
@@ -213,27 +212,22 @@ class Metaspace : public CHeapObj {
void iterate(AllocRecordClosure *closure);
- // Return TRUE only if UseCompressedKlassPointers is True and DumpSharedSpaces is False.
+ // Return TRUE only if UseCompressedClassPointers is True and DumpSharedSpaces is False.
static bool using_class_space() {
- return NOT_LP64(false) LP64_ONLY(UseCompressedKlassPointers && !DumpSharedSpaces);
+ return NOT_LP64(false) LP64_ONLY(UseCompressedClassPointers && !DumpSharedSpaces);
}
};
class MetaspaceAux : AllStatic {
- static size_t free_chunks_total(Metaspace::MetadataType mdtype);
-
- public:
- // Statistics for class space and data space in metaspace.
+ static size_t free_chunks_total_words(Metaspace::MetadataType mdtype);
// These methods iterate over the classloader data graph
// for the given Metaspace type. These are slow.
static size_t used_bytes_slow(Metaspace::MetadataType mdtype);
- static size_t free_in_bytes(Metaspace::MetadataType mdtype);
+ static size_t free_bytes_slow(Metaspace::MetadataType mdtype);
static size_t capacity_bytes_slow(Metaspace::MetadataType mdtype);
-
- // Iterates over the virtual space list.
- static size_t reserved_in_bytes(Metaspace::MetadataType mdtype);
+ static size_t capacity_bytes_slow();
// Running sum of space in all Metachunks that has been
// allocated to a Metaspace. This is used instead of
@@ -263,17 +257,16 @@ class MetaspaceAux : AllStatic {
}
// Used by MetaspaceCounters
- static size_t free_chunks_total();
- static size_t free_chunks_total_in_bytes();
- static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype);
+ static size_t free_chunks_total_words();
+ static size_t free_chunks_total_bytes();
+ static size_t free_chunks_total_bytes(Metaspace::MetadataType mdtype);
static size_t allocated_capacity_words(Metaspace::MetadataType mdtype) {
return _allocated_capacity_words[mdtype];
}
static size_t allocated_capacity_words() {
- return _allocated_capacity_words[Metaspace::NonClassType] +
- (Metaspace::using_class_space() ?
- _allocated_capacity_words[Metaspace::ClassType] : 0);
+ return allocated_capacity_words(Metaspace::NonClassType) +
+ allocated_capacity_words(Metaspace::ClassType);
}
static size_t allocated_capacity_bytes(Metaspace::MetadataType mdtype) {
return allocated_capacity_words(mdtype) * BytesPerWord;
@@ -286,9 +279,8 @@ class MetaspaceAux : AllStatic {
return _allocated_used_words[mdtype];
}
static size_t allocated_used_words() {
- return _allocated_used_words[Metaspace::NonClassType] +
- (Metaspace::using_class_space() ?
- _allocated_used_words[Metaspace::ClassType] : 0);
+ return allocated_used_words(Metaspace::NonClassType) +
+ allocated_used_words(Metaspace::ClassType);
}
static size_t allocated_used_bytes(Metaspace::MetadataType mdtype) {
return allocated_used_words(mdtype) * BytesPerWord;
@@ -300,31 +292,22 @@ class MetaspaceAux : AllStatic {
static size_t free_bytes();
static size_t free_bytes(Metaspace::MetadataType mdtype);
- // Total capacity in all Metaspaces
- static size_t capacity_bytes_slow() {
-#ifdef PRODUCT
- // Use allocated_capacity_bytes() in PRODUCT instead of this function.
- guarantee(false, "Should not call capacity_bytes_slow() in the PRODUCT");
-#endif
- size_t class_capacity = capacity_bytes_slow(Metaspace::ClassType);
- size_t non_class_capacity = capacity_bytes_slow(Metaspace::NonClassType);
- assert(allocated_capacity_bytes() == class_capacity + non_class_capacity,
- err_msg("bad accounting: allocated_capacity_bytes() " SIZE_FORMAT
- " class_capacity + non_class_capacity " SIZE_FORMAT
- " class_capacity " SIZE_FORMAT " non_class_capacity " SIZE_FORMAT,
- allocated_capacity_bytes(), class_capacity + non_class_capacity,
- class_capacity, non_class_capacity));
-
- return class_capacity + non_class_capacity;
+ static size_t reserved_bytes(Metaspace::MetadataType mdtype);
+ static size_t reserved_bytes() {
+ return reserved_bytes(Metaspace::ClassType) +
+ reserved_bytes(Metaspace::NonClassType);
}
- // Total space reserved in all Metaspaces
- static size_t reserved_in_bytes() {
- return reserved_in_bytes(Metaspace::ClassType) +
- reserved_in_bytes(Metaspace::NonClassType);
+ static size_t committed_bytes(Metaspace::MetadataType mdtype);
+ static size_t committed_bytes() {
+ return committed_bytes(Metaspace::ClassType) +
+ committed_bytes(Metaspace::NonClassType);
}
- static size_t min_chunk_size();
+ static size_t min_chunk_size_words();
+ static size_t min_chunk_size_bytes() {
+ return min_chunk_size_words() * BytesPerWord;
+ }
// Print change in used metadata.
static void print_metaspace_change(size_t prev_metadata_used);
diff --git a/hotspot/src/share/vm/memory/metaspaceCounters.cpp b/hotspot/src/share/vm/memory/metaspaceCounters.cpp
index eb7bebd28b6..60e26b8c714 100644
--- a/hotspot/src/share/vm/memory/metaspaceCounters.cpp
+++ b/hotspot/src/share/vm/memory/metaspaceCounters.cpp
@@ -65,26 +65,25 @@ class MetaspacePerfCounters: public CHeapObj {
MetaspacePerfCounters* MetaspaceCounters::_perf_counters = NULL;
-size_t MetaspaceCounters::calculate_capacity() {
- // The total capacity is the sum of
- // 1) capacity of Metachunks in use by all Metaspaces
- // 2) unused space at the end of each Metachunk
- // 3) space in the freelist
- size_t total_capacity = MetaspaceAux::allocated_capacity_bytes()
- + MetaspaceAux::free_bytes() + MetaspaceAux::free_chunks_total_in_bytes();
- return total_capacity;
+size_t MetaspaceCounters::used() {
+ return MetaspaceAux::allocated_used_bytes();
+}
+
+size_t MetaspaceCounters::capacity() {
+ return MetaspaceAux::committed_bytes();
+}
+
+size_t MetaspaceCounters::max_capacity() {
+ return MetaspaceAux::reserved_bytes();
}
void MetaspaceCounters::initialize_performance_counters() {
if (UsePerfData) {
assert(_perf_counters == NULL, "Should only be initialized once");
- size_t min_capacity = MetaspaceAux::min_chunk_size();
- size_t capacity = calculate_capacity();
- size_t max_capacity = MetaspaceAux::reserved_in_bytes();
- size_t used = MetaspaceAux::allocated_used_bytes();
-
- _perf_counters = new MetaspacePerfCounters("metaspace", min_capacity, capacity, max_capacity, used);
+ size_t min_capacity = 0;
+ _perf_counters = new MetaspacePerfCounters("metaspace", min_capacity,
+ capacity(), max_capacity(), used());
}
}
@@ -92,31 +91,29 @@ void MetaspaceCounters::update_performance_counters() {
if (UsePerfData) {
assert(_perf_counters != NULL, "Should be initialized");
- size_t capacity = calculate_capacity();
- size_t max_capacity = MetaspaceAux::reserved_in_bytes();
- size_t used = MetaspaceAux::allocated_used_bytes();
-
- _perf_counters->update(capacity, max_capacity, used);
+ _perf_counters->update(capacity(), max_capacity(), used());
}
}
MetaspacePerfCounters* CompressedClassSpaceCounters::_perf_counters = NULL;
-size_t CompressedClassSpaceCounters::calculate_capacity() {
- return MetaspaceAux::allocated_capacity_bytes(_class_type) +
- MetaspaceAux::free_bytes(_class_type) +
- MetaspaceAux::free_chunks_total_in_bytes(_class_type);
+size_t CompressedClassSpaceCounters::used() {
+ return MetaspaceAux::allocated_used_bytes(Metaspace::ClassType);
+}
+
+size_t CompressedClassSpaceCounters::capacity() {
+ return MetaspaceAux::committed_bytes(Metaspace::ClassType);
+}
+
+size_t CompressedClassSpaceCounters::max_capacity() {
+ return MetaspaceAux::reserved_bytes(Metaspace::ClassType);
}
void CompressedClassSpaceCounters::update_performance_counters() {
- if (UsePerfData && UseCompressedKlassPointers) {
+ if (UsePerfData && UseCompressedClassPointers) {
assert(_perf_counters != NULL, "Should be initialized");
- size_t capacity = calculate_capacity();
- size_t max_capacity = MetaspaceAux::reserved_in_bytes(_class_type);
- size_t used = MetaspaceAux::allocated_used_bytes(_class_type);
-
- _perf_counters->update(capacity, max_capacity, used);
+ _perf_counters->update(capacity(), max_capacity(), used());
}
}
@@ -125,13 +122,10 @@ void CompressedClassSpaceCounters::initialize_performance_counters() {
assert(_perf_counters == NULL, "Should only be initialized once");
const char* ns = "compressedclassspace";
- if (UseCompressedKlassPointers) {
- size_t min_capacity = MetaspaceAux::min_chunk_size();
- size_t capacity = calculate_capacity();
- size_t max_capacity = MetaspaceAux::reserved_in_bytes(_class_type);
- size_t used = MetaspaceAux::allocated_used_bytes(_class_type);
-
- _perf_counters = new MetaspacePerfCounters(ns, min_capacity, capacity, max_capacity, used);
+ if (UseCompressedClassPointers) {
+ size_t min_capacity = 0;
+ _perf_counters = new MetaspacePerfCounters(ns, min_capacity, capacity(),
+ max_capacity(), used());
} else {
_perf_counters = new MetaspacePerfCounters(ns, 0, 0, 0, 0);
}
diff --git a/hotspot/src/share/vm/memory/metaspaceCounters.hpp b/hotspot/src/share/vm/memory/metaspaceCounters.hpp
index 5b481d59b4d..0fa991291a1 100644
--- a/hotspot/src/share/vm/memory/metaspaceCounters.hpp
+++ b/hotspot/src/share/vm/memory/metaspaceCounters.hpp
@@ -25,13 +25,15 @@
#ifndef SHARE_VM_MEMORY_METASPACECOUNTERS_HPP
#define SHARE_VM_MEMORY_METASPACECOUNTERS_HPP
-#include "memory/metaspace.hpp"
+#include "memory/allocation.hpp"
class MetaspacePerfCounters;
class MetaspaceCounters: public AllStatic {
static MetaspacePerfCounters* _perf_counters;
- static size_t calculate_capacity();
+ static size_t used();
+ static size_t capacity();
+ static size_t max_capacity();
public:
static void initialize_performance_counters();
@@ -40,8 +42,9 @@ class MetaspaceCounters: public AllStatic {
class CompressedClassSpaceCounters: public AllStatic {
static MetaspacePerfCounters* _perf_counters;
- static size_t calculate_capacity();
- static const Metaspace::MetadataType _class_type = Metaspace::ClassType;
+ static size_t used();
+ static size_t capacity();
+ static size_t max_capacity();
public:
static void initialize_performance_counters();
diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp
index 143c0c00c45..1f632ae478f 100644
--- a/hotspot/src/share/vm/memory/universe.cpp
+++ b/hotspot/src/share/vm/memory/universe.cpp
@@ -602,7 +602,7 @@ oop Universe::gen_out_of_memory_error(oop default_err) {
}
}
-static intptr_t non_oop_bits = 0;
+intptr_t Universe::_non_oop_bits = 0;
void* Universe::non_oop_word() {
// Neither the high bits nor the low bits of this value is allowed
@@ -616,11 +616,11 @@ void* Universe::non_oop_word() {
// Using the OS-supplied non-memory-address word (usually 0 or -1)
// will take care of the high bits, however many there are.
- if (non_oop_bits == 0) {
- non_oop_bits = (intptr_t)os::non_memory_address_word() | 1;
+ if (_non_oop_bits == 0) {
+ _non_oop_bits = (intptr_t)os::non_memory_address_word() | 1;
}
- return (void*)non_oop_bits;
+ return (void*)_non_oop_bits;
}
jint universe_init() {
@@ -872,13 +872,16 @@ jint Universe::initialize_heap() {
// Reserve the Java heap, which is now the same for all GCs.
ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
+ assert(alignment <= Arguments::conservative_max_heap_alignment(),
+ err_msg("actual alignment "SIZE_FORMAT" must be within maximum heap alignment "SIZE_FORMAT,
+ alignment, Arguments::conservative_max_heap_alignment()));
size_t total_reserved = align_size_up(heap_size, alignment);
assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())),
"heap size is too big for compressed oops");
bool use_large_pages = UseLargePages && is_size_aligned(alignment, os::large_page_size());
assert(!UseLargePages
- || UseParallelOldGC
+ || UseParallelGC
|| use_large_pages, "Wrong alignment to use large pages");
char* addr = Universe::preferred_heap_base(total_reserved, alignment, Universe::UnscaledNarrowOop);
@@ -1028,7 +1031,7 @@ bool universe_post_init() {
msg = java_lang_String::create_from_str("Metadata space", CHECK_false);
java_lang_Throwable::set_message(Universe::_out_of_memory_error_metaspace, msg());
- msg = java_lang_String::create_from_str("Class Metadata space", CHECK_false);
+ msg = java_lang_String::create_from_str("Compressed class space", CHECK_false);
java_lang_Throwable::set_message(Universe::_out_of_memory_error_class_metaspace, msg());
msg = java_lang_String::create_from_str("Requested array size exceeds VM limit", CHECK_false);
diff --git a/hotspot/src/share/vm/memory/universe.hpp b/hotspot/src/share/vm/memory/universe.hpp
index a8b541d03a1..a891d2a11ce 100644
--- a/hotspot/src/share/vm/memory/universe.hpp
+++ b/hotspot/src/share/vm/memory/universe.hpp
@@ -179,9 +179,11 @@ class Universe: AllStatic {
// The particular choice of collected heap.
static CollectedHeap* _collectedHeap;
+ static intptr_t _non_oop_bits;
+
// For UseCompressedOops.
static struct NarrowPtrStruct _narrow_oop;
- // For UseCompressedKlassPointers.
+ // For UseCompressedClassPointers.
static struct NarrowPtrStruct _narrow_klass;
static address _narrow_ptrs_base;
@@ -229,7 +231,7 @@ class Universe: AllStatic {
_narrow_oop._base = base;
}
static void set_narrow_klass_base(address base) {
- assert(UseCompressedKlassPointers, "no compressed klass ptrs?");
+ assert(UseCompressedClassPointers, "no compressed klass ptrs?");
_narrow_klass._base = base;
}
static void set_narrow_oop_use_implicit_null_checks(bool use) {
@@ -353,7 +355,7 @@ class Universe: AllStatic {
static int narrow_oop_shift() { return _narrow_oop._shift; }
static bool narrow_oop_use_implicit_null_checks() { return _narrow_oop._use_implicit_null_checks; }
- // For UseCompressedKlassPointers
+ // For UseCompressedClassPointers
static address narrow_klass_base() { return _narrow_klass._base; }
static bool is_narrow_klass_base(void* addr) { return (narrow_klass_base() == (address)addr); }
static int narrow_klass_shift() { return _narrow_klass._shift; }
diff --git a/hotspot/src/share/vm/oops/arrayOop.hpp b/hotspot/src/share/vm/oops/arrayOop.hpp
index 806b7b7289a..0e5ceffe35a 100644
--- a/hotspot/src/share/vm/oops/arrayOop.hpp
+++ b/hotspot/src/share/vm/oops/arrayOop.hpp
@@ -65,7 +65,7 @@ class arrayOopDesc : public oopDesc {
// declared nonstatic fields in arrayOopDesc if not compressed, otherwise
// it occupies the second half of the _klass field in oopDesc.
static int length_offset_in_bytes() {
- return UseCompressedKlassPointers ? klass_gap_offset_in_bytes() :
+ return UseCompressedClassPointers ? klass_gap_offset_in_bytes() :
sizeof(arrayOopDesc);
}
diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp
index 8033d7e3850..673da4dd622 100644
--- a/hotspot/src/share/vm/oops/constantPool.cpp
+++ b/hotspot/src/share/vm/oops/constantPool.cpp
@@ -396,32 +396,6 @@ Klass* ConstantPool::klass_ref_at_if_loaded(constantPoolHandle this_oop, int whi
}
-// This is an interface for the compiler that allows accessing non-resolved entries
-// in the constant pool - but still performs the validations tests. Must be used
-// in a pre-parse of the compiler - to determine what it can do and not do.
-// Note: We cannot update the ConstantPool from the vm_thread.
-Klass* ConstantPool::klass_ref_at_if_loaded_check(constantPoolHandle this_oop, int index, TRAPS) {
- int which = this_oop->klass_ref_index_at(index);
- CPSlot entry = this_oop->slot_at(which);
- if (entry.is_resolved()) {
- assert(entry.get_klass()->is_klass(), "must be");
- return entry.get_klass();
- } else {
- assert(entry.is_unresolved(), "must be either symbol or klass");
- Symbol* name = entry.get_symbol();
- oop loader = this_oop->pool_holder()->class_loader();
- oop protection_domain = this_oop->pool_holder()->protection_domain();
- Handle h_loader(THREAD, loader);
- Handle h_prot (THREAD, protection_domain);
- KlassHandle k(THREAD, SystemDictionary::find(name, h_loader, h_prot, THREAD));
-
- // Do access check for klasses
- if( k.not_null() ) verify_constant_pool_resolve(this_oop, k, CHECK_NULL);
- return k();
- }
-}
-
-
Method* ConstantPool::method_at_if_loaded(constantPoolHandle cpool,
int which) {
if (cpool->cache() == NULL) return NULL; // nothing to load yet
diff --git a/hotspot/src/share/vm/oops/constantPool.hpp b/hotspot/src/share/vm/oops/constantPool.hpp
index eca2dcd9c56..b7d607d763a 100644
--- a/hotspot/src/share/vm/oops/constantPool.hpp
+++ b/hotspot/src/share/vm/oops/constantPool.hpp
@@ -730,8 +730,6 @@ class ConstantPool : public Metadata {
static oop method_type_at_if_loaded (constantPoolHandle this_oop, int which);
static Klass* klass_at_if_loaded (constantPoolHandle this_oop, int which);
static Klass* klass_ref_at_if_loaded (constantPoolHandle this_oop, int which);
- // Same as above - but does LinkResolving.
- static Klass* klass_ref_at_if_loaded_check(constantPoolHandle this_oop, int which, TRAPS);
// Routines currently used for annotations (only called by jvm.cpp) but which might be used in the
// future by other Java code. These take constant pool indices rather than
diff --git a/hotspot/src/share/vm/oops/cpCache.cpp b/hotspot/src/share/vm/oops/cpCache.cpp
index 9e2b83c2caf..9d358955025 100644
--- a/hotspot/src/share/vm/oops/cpCache.cpp
+++ b/hotspot/src/share/vm/oops/cpCache.cpp
@@ -140,9 +140,10 @@ void ConstantPoolCacheEntry::set_parameter_size(int value) {
err_msg("size must not change: parameter_size=%d, value=%d", parameter_size(), value));
}
-void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code,
- methodHandle method,
- int vtable_index) {
+void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code,
+ methodHandle method,
+ int vtable_index) {
+ bool is_vtable_call = (vtable_index >= 0); // FIXME: split this method on this boolean
assert(method->interpreter_entry() != NULL, "should have been set at this point");
assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache");
@@ -160,7 +161,8 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code,
// ...and fall through as if we were handling invokevirtual:
case Bytecodes::_invokevirtual:
{
- if (method->can_be_statically_bound()) {
+ if (!is_vtable_call) {
+ assert(method->can_be_statically_bound(), "");
// set_f2_as_vfinal_method checks if is_vfinal flag is true.
set_method_flags(as_TosState(method->result_type()),
( 1 << is_vfinal_shift) |
@@ -169,6 +171,7 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code,
method()->size_of_parameters());
set_f2_as_vfinal_method(method());
} else {
+ assert(!method->can_be_statically_bound(), "");
assert(vtable_index >= 0, "valid index");
assert(!method->is_final_method(), "sanity");
set_method_flags(as_TosState(method->result_type()),
@@ -182,6 +185,7 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code,
case Bytecodes::_invokespecial:
case Bytecodes::_invokestatic:
+ assert(!is_vtable_call, "");
// Note: Read and preserve the value of the is_vfinal flag on any
// invokevirtual bytecode shared with this constant pool cache entry.
// It is cheap and safe to consult is_vfinal() at all times.
@@ -232,8 +236,22 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code,
NOT_PRODUCT(verify(tty));
}
+void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, methodHandle method) {
+ int index = Method::nonvirtual_vtable_index;
+ // index < 0; FIXME: inline and customize set_direct_or_vtable_call
+ set_direct_or_vtable_call(invoke_code, method, index);
+}
-void ConstantPoolCacheEntry::set_interface_call(methodHandle method, int index) {
+void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, methodHandle method, int index) {
+ // either the method is a miranda or its holder should accept the given index
+ assert(method->method_holder()->is_interface() || method->method_holder()->verify_vtable_index(index), "");
+ // index >= 0; FIXME: inline and customize set_direct_or_vtable_call
+ set_direct_or_vtable_call(invoke_code, method, index);
+}
+
+void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, methodHandle method, int index) {
+ assert(method->method_holder()->verify_itable_index(index), "");
+ assert(invoke_code == Bytecodes::_invokeinterface, "");
InstanceKlass* interf = method->method_holder();
assert(interf->is_interface(), "must be an interface");
assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here");
diff --git a/hotspot/src/share/vm/oops/cpCache.hpp b/hotspot/src/share/vm/oops/cpCache.hpp
index c15b4a54bd6..77c0deb9d8f 100644
--- a/hotspot/src/share/vm/oops/cpCache.hpp
+++ b/hotspot/src/share/vm/oops/cpCache.hpp
@@ -219,15 +219,29 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
Klass* root_klass // needed by the GC to dirty the klass
);
- void set_method( // sets entry to resolved method entry
+ private:
+ void set_direct_or_vtable_call(
Bytecodes::Code invoke_code, // the bytecode used for invoking the method
methodHandle method, // the method/prototype if any (NULL, otherwise)
int vtable_index // the vtable index if any, else negative
);
- void set_interface_call(
- methodHandle method, // Resolved method
- int index // Method index into interface
+ public:
+ void set_direct_call( // sets entry to exact concrete method entry
+ Bytecodes::Code invoke_code, // the bytecode used for invoking the method
+ methodHandle method // the method to call
+ );
+
+ void set_vtable_call( // sets entry to vtable index
+ Bytecodes::Code invoke_code, // the bytecode used for invoking the method
+ methodHandle method, // resolved method which declares the vtable index
+ int vtable_index // the vtable index
+ );
+
+ void set_itable_call(
+ Bytecodes::Code invoke_code, // the bytecode used; must be invokeinterface
+ methodHandle method, // the resolved interface method
+ int itable_index // index into itable for the method
);
void set_method_handle(
diff --git a/hotspot/src/share/vm/oops/fieldInfo.hpp b/hotspot/src/share/vm/oops/fieldInfo.hpp
index 5da8ed9628a..6763c42d127 100644
--- a/hotspot/src/share/vm/oops/fieldInfo.hpp
+++ b/hotspot/src/share/vm/oops/fieldInfo.hpp
@@ -240,6 +240,14 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC {
return (access_flags() & JVM_ACC_FIELD_INTERNAL) != 0;
}
+ bool is_stable() const {
+ return (access_flags() & JVM_ACC_FIELD_STABLE) != 0;
+ }
+ void set_stable(bool z) {
+ if (z) _shorts[access_flags_offset] |= JVM_ACC_FIELD_STABLE;
+ else _shorts[access_flags_offset] &= ~JVM_ACC_FIELD_STABLE;
+ }
+
Symbol* lookup_symbol(int symbol_index) const {
assert(is_internal(), "only internal fields");
return vmSymbols::symbol_at((vmSymbols::SID)symbol_index);
diff --git a/hotspot/src/share/vm/oops/fieldStreams.hpp b/hotspot/src/share/vm/oops/fieldStreams.hpp
index acc590c970c..17f1b0a8585 100644
--- a/hotspot/src/share/vm/oops/fieldStreams.hpp
+++ b/hotspot/src/share/vm/oops/fieldStreams.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -27,6 +27,7 @@
#include "oops/instanceKlass.hpp"
#include "oops/fieldInfo.hpp"
+#include "runtime/fieldDescriptor.hpp"
// The is the base class for iteration over the fields array
// describing the declared fields in the class. Several subclasses
@@ -43,8 +44,10 @@ class FieldStreamBase : public StackObj {
int _index;
int _limit;
int _generic_signature_slot;
+ fieldDescriptor _fd_buf;
FieldInfo* field() const { return FieldInfo::from_field_array(_fields, _index); }
+ InstanceKlass* field_holder() const { return _constants->pool_holder(); }
int init_generic_signature_start_slot() {
int length = _fields->length();
@@ -102,6 +105,7 @@ class FieldStreamBase : public StackObj {
_index = 0;
_limit = klass->java_fields_count();
init_generic_signature_start_slot();
+ assert(klass == field_holder(), "");
}
FieldStreamBase(instanceKlassHandle klass) {
_fields = klass->fields();
@@ -109,6 +113,7 @@ class FieldStreamBase : public StackObj {
_index = 0;
_limit = klass->java_fields_count();
init_generic_signature_start_slot();
+ assert(klass == field_holder(), "");
}
// accessors
@@ -180,6 +185,12 @@ class FieldStreamBase : public StackObj {
return field()->contended_group();
}
+ // bridge to a heavier API:
+ fieldDescriptor& field_descriptor() const {
+ fieldDescriptor& field = const_cast(_fd_buf);
+ field.reinitialize(field_holder(), _index);
+ return field;
+ }
};
// Iterate over only the internal fields
diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
index 29c77a07ccb..cf77300dcf0 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
@@ -286,7 +286,6 @@ InstanceKlass::InstanceKlass(int vtable_len,
init_previous_versions();
set_generic_signature_index(0);
release_set_methods_jmethod_ids(NULL);
- release_set_methods_cached_itable_indices(NULL);
set_annotations(NULL);
set_jvmti_cached_class_field_map(NULL);
set_initial_method_idnum(0);
@@ -1149,7 +1148,7 @@ bool InstanceKlass::find_local_field(Symbol* name, Symbol* sig, fieldDescriptor*
Symbol* f_name = fs.name();
Symbol* f_sig = fs.signature();
if (f_name == name && f_sig == sig) {
- fd->initialize(const_cast(this), fs.index());
+ fd->reinitialize(const_cast(this), fs.index());
return true;
}
}
@@ -1218,7 +1217,7 @@ Klass* InstanceKlass::find_field(Symbol* name, Symbol* sig, bool is_static, fiel
bool InstanceKlass::find_local_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const {
for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
if (fs.offset() == offset) {
- fd->initialize(const_cast(this), fs.index());
+ fd->reinitialize(const_cast(this), fs.index());
if (fd->is_static() == is_static) return true;
}
}
@@ -1251,8 +1250,7 @@ void InstanceKlass::methods_do(void f(Method* method)) {
void InstanceKlass::do_local_static_fields(FieldClosure* cl) {
for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
if (fs.access_flags().is_static()) {
- fieldDescriptor fd;
- fd.initialize(this, fs.index());
+ fieldDescriptor& fd = fs.field_descriptor();
cl->do_field(&fd);
}
}
@@ -1268,8 +1266,7 @@ void InstanceKlass::do_local_static_fields(void f(fieldDescriptor*, TRAPS), TRAP
void InstanceKlass::do_local_static_fields_impl(instanceKlassHandle this_oop, void f(fieldDescriptor* fd, TRAPS), TRAPS) {
for (JavaFieldStream fs(this_oop()); !fs.done(); fs.next()) {
if (fs.access_flags().is_static()) {
- fieldDescriptor fd;
- fd.initialize(this_oop(), fs.index());
+ fieldDescriptor& fd = fs.field_descriptor();
f(&fd, CHECK);
}
}
@@ -1291,7 +1288,7 @@ void InstanceKlass::do_nonstatic_fields(FieldClosure* cl) {
int* fields_sorted = NEW_C_HEAP_ARRAY(int, 2*(length+1), mtClass);
int j = 0;
for (int i = 0; i < length; i += 1) {
- fd.initialize(this, i);
+ fd.reinitialize(this, i);
if (!fd.is_static()) {
fields_sorted[j + 0] = fd.offset();
fields_sorted[j + 1] = i;
@@ -1303,7 +1300,7 @@ void InstanceKlass::do_nonstatic_fields(FieldClosure* cl) {
// _sort_Fn is defined in growableArray.hpp.
qsort(fields_sorted, length/2, 2*sizeof(int), (_sort_Fn)compare_fields_by_offset);
for (int i = 0; i < length; i += 2) {
- fd.initialize(this, fields_sorted[i + 1]);
+ fd.reinitialize(this, fields_sorted[i + 1]);
assert(!fd.is_static() && fd.offset() == fields_sorted[i], "only nonstatic fields");
cl->do_field(&fd);
}
@@ -1686,87 +1683,6 @@ jmethodID InstanceKlass::jmethod_id_or_null(Method* method) {
}
-// Cache an itable index
-void InstanceKlass::set_cached_itable_index(size_t idnum, int index) {
- int* indices = methods_cached_itable_indices_acquire();
- int* to_dealloc_indices = NULL;
-
- // We use a double-check locking idiom here because this cache is
- // performance sensitive. In the normal system, this cache only
- // transitions from NULL to non-NULL which is safe because we use
- // release_set_methods_cached_itable_indices() to advertise the
- // new cache. A partially constructed cache should never be seen
- // by a racing thread. Cache reads and writes proceed without a
- // lock, but creation of the cache itself requires no leaks so a
- // lock is generally acquired in that case.
- //
- // If the RedefineClasses() API has been used, then this cache can
- // grow and we'll have transitions from non-NULL to bigger non-NULL.
- // Cache creation requires no leaks and we require safety between all
- // cache accesses and freeing of the old cache so a lock is generally
- // acquired when the RedefineClasses() API has been used.
-
- if (indices == NULL || idnum_can_increment()) {
- // we need a cache or the cache can grow
- MutexLocker ml(JNICachedItableIndex_lock);
- // reacquire the cache to see if another thread already did the work
- indices = methods_cached_itable_indices_acquire();
- size_t length = 0;
- // cache size is stored in element[0], other elements offset by one
- if (indices == NULL || (length = (size_t)indices[0]) <= idnum) {
- size_t size = MAX2(idnum+1, (size_t)idnum_allocated_count());
- int* new_indices = NEW_C_HEAP_ARRAY(int, size+1, mtClass);
- new_indices[0] = (int)size;
- // copy any existing entries
- size_t i;
- for (i = 0; i < length; i++) {
- new_indices[i+1] = indices[i+1];
- }
- // Set all the rest to -1
- for (i = length; i < size; i++) {
- new_indices[i+1] = -1;
- }
- if (indices != NULL) {
- // We have an old cache to delete so save it for after we
- // drop the lock.
- to_dealloc_indices = indices;
- }
- release_set_methods_cached_itable_indices(indices = new_indices);
- }
-
- if (idnum_can_increment()) {
- // this cache can grow so we have to write to it safely
- indices[idnum+1] = index;
- }
- } else {
- CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
- }
-
- if (!idnum_can_increment()) {
- // The cache cannot grow and this JNI itable index value does not
- // have to be unique like a jmethodID. If there is a race to set it,
- // it doesn't matter.
- indices[idnum+1] = index;
- }
-
- if (to_dealloc_indices != NULL) {
- // we allocated a new cache so free the old one
- FreeHeap(to_dealloc_indices);
- }
-}
-
-
-// Retrieve a cached itable index
-int InstanceKlass::cached_itable_index(size_t idnum) {
- int* indices = methods_cached_itable_indices_acquire();
- if (indices != NULL && ((size_t)indices[0]) > idnum) {
- // indices exist and are long enough, retrieve possible cached
- return indices[idnum+1];
- }
- return -1;
-}
-
-
//
// Walk the list of dependent nmethods searching for nmethods which
// are dependent on the changes that were passed in and mark them for
@@ -2326,12 +2242,6 @@ void InstanceKlass::release_C_heap_structures() {
}
}
- int* indices = methods_cached_itable_indices_acquire();
- if (indices != (int*)NULL) {
- release_set_methods_cached_itable_indices(NULL);
- FreeHeap(indices);
- }
-
// release dependencies
nmethodBucket* b = _dependencies;
_dependencies = NULL;
@@ -2782,6 +2692,18 @@ static const char* state_names[] = {
"allocated", "loaded", "linked", "being_initialized", "fully_initialized", "initialization_error"
};
+static void print_vtable(intptr_t* start, int len, outputStream* st) {
+ for (int i = 0; i < len; i++) {
+ intptr_t e = start[i];
+ st->print("%d : " INTPTR_FORMAT, i, e);
+ if (e != 0 && ((Metadata*)e)->is_metaspace_object()) {
+ st->print(" ");
+ ((Metadata*)e)->print_value_on(st);
+ }
+ st->cr();
+ }
+}
+
void InstanceKlass::print_on(outputStream* st) const {
assert(is_klass(), "must be klass");
Klass::print_on(st);
@@ -2816,7 +2738,7 @@ void InstanceKlass::print_on(outputStream* st) const {
st->print(BULLET"arrays: "); array_klasses()->print_value_on_maybe_null(st); st->cr();
st->print(BULLET"methods: "); methods()->print_value_on(st); st->cr();
- if (Verbose) {
+ if (Verbose || WizardMode) {
Array* method_array = methods();
for(int i = 0; i < method_array->length(); i++) {
st->print("%d : ", i); method_array->at(i)->print_value(); st->cr();
@@ -2874,7 +2796,9 @@ void InstanceKlass::print_on(outputStream* st) const {
st->print(BULLET"inner classes: "); inner_classes()->print_value_on(st); st->cr();
st->print(BULLET"java mirror: "); java_mirror()->print_value_on(st); st->cr();
st->print(BULLET"vtable length %d (start addr: " INTPTR_FORMAT ")", vtable_length(), start_of_vtable()); st->cr();
+ if (vtable_length() > 0 && (Verbose || WizardMode)) print_vtable(start_of_vtable(), vtable_length(), st);
st->print(BULLET"itable length %d (start addr: " INTPTR_FORMAT ")", itable_length(), start_of_itable()); st->cr();
+ if (itable_length() > 0 && (Verbose || WizardMode)) print_vtable(start_of_itable(), itable_length(), st);
st->print_cr(BULLET"---- static fields (%d words):", static_field_size());
FieldPrinter print_static_field(st);
((InstanceKlass*)this)->do_local_static_fields(&print_static_field);
@@ -2896,6 +2820,7 @@ void InstanceKlass::print_on(outputStream* st) const {
void InstanceKlass::print_value_on(outputStream* st) const {
assert(is_klass(), "must be klass");
+ if (Verbose || WizardMode) access_flags().print_on(st);
name()->print_value_on(st);
}
diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp
index 123f6b17911..3bd4e9de40c 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp
@@ -245,7 +245,6 @@ class InstanceKlass: public Klass {
MemberNameTable* _member_names; // Member names
JNIid* _jni_ids; // First JNI identifier for static fields in this class
jmethodID* _methods_jmethod_ids; // jmethodIDs corresponding to method_idnum, or NULL if none
- int* _methods_cached_itable_indices; // itable_index cache for JNI invoke corresponding to methods idnum, or NULL
nmethodBucket* _dependencies; // list of dependent nmethods
nmethod* _osr_nmethods_head; // Head of list of on-stack replacement nmethods for this class
BreakpointInfo* _breakpoints; // bpt lists, managed by Method*
@@ -690,10 +689,6 @@ class InstanceKlass: public Klass {
size_t *length_p, jmethodID* id_p);
jmethodID jmethod_id_or_null(Method* method);
- // cached itable index support
- void set_cached_itable_index(size_t idnum, int index);
- int cached_itable_index(size_t idnum);
-
// annotations support
Annotations* annotations() const { return _annotations; }
void set_annotations(Annotations* anno) { _annotations = anno; }
@@ -994,11 +989,6 @@ private:
void release_set_methods_jmethod_ids(jmethodID* jmeths)
{ OrderAccess::release_store_ptr(&_methods_jmethod_ids, jmeths); }
- int* methods_cached_itable_indices_acquire() const
- { return (int*)OrderAccess::load_ptr_acquire(&_methods_cached_itable_indices); }
- void release_set_methods_cached_itable_indices(int* indices)
- { OrderAccess::release_store_ptr(&_methods_cached_itable_indices, indices); }
-
// Lock during initialization
public:
// Lock for (1) initialization; (2) access to the ConstantPool of this class.
diff --git a/hotspot/src/share/vm/oops/instanceOop.hpp b/hotspot/src/share/vm/oops/instanceOop.hpp
index 9ebb9d4720b..bdac1992e6f 100644
--- a/hotspot/src/share/vm/oops/instanceOop.hpp
+++ b/hotspot/src/share/vm/oops/instanceOop.hpp
@@ -37,9 +37,9 @@ class instanceOopDesc : public oopDesc {
// If compressed, the offset of the fields of the instance may not be aligned.
static int base_offset_in_bytes() {
- // offset computation code breaks if UseCompressedKlassPointers
+ // offset computation code breaks if UseCompressedClassPointers
// only is true
- return (UseCompressedOops && UseCompressedKlassPointers) ?
+ return (UseCompressedOops && UseCompressedClassPointers) ?
klass_gap_offset_in_bytes() :
sizeof(instanceOopDesc);
}
diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp
index cf24783fbf8..22b570bbff3 100644
--- a/hotspot/src/share/vm/oops/klass.cpp
+++ b/hotspot/src/share/vm/oops/klass.cpp
@@ -674,13 +674,23 @@ void Klass::oop_verify_on(oop obj, outputStream* st) {
#ifndef PRODUCT
-void Klass::verify_vtable_index(int i) {
+bool Klass::verify_vtable_index(int i) {
if (oop_is_instance()) {
- assert(i>=0 && i<((InstanceKlass*)this)->vtable_length()/vtableEntry::size(), "index out of bounds");
+ int limit = ((InstanceKlass*)this)->vtable_length()/vtableEntry::size();
+ assert(i >= 0 && i < limit, err_msg("index %d out of bounds %d", i, limit));
} else {
assert(oop_is_array(), "Must be");
- assert(i>=0 && i<((ArrayKlass*)this)->vtable_length()/vtableEntry::size(), "index out of bounds");
+ int limit = ((ArrayKlass*)this)->vtable_length()/vtableEntry::size();
+ assert(i >= 0 && i < limit, err_msg("index %d out of bounds %d", i, limit));
}
+ return true;
+}
+
+bool Klass::verify_itable_index(int i) {
+ assert(oop_is_instance(), "");
+ int method_count = klassItable::method_count_for_interface(this);
+ assert(i >= 0 && i < method_count, "index out of bounds");
+ return true;
}
#endif
diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp
index 83bf44561b2..9855fdd3233 100644
--- a/hotspot/src/share/vm/oops/klass.hpp
+++ b/hotspot/src/share/vm/oops/klass.hpp
@@ -699,7 +699,8 @@ class Klass : public Metadata {
void verify(bool check_dictionary = true) { verify_on(tty, check_dictionary); }
#ifndef PRODUCT
- void verify_vtable_index(int index);
+ bool verify_vtable_index(int index);
+ bool verify_itable_index(int index);
#endif
virtual void oop_verify_on(oop obj, outputStream* st);
diff --git a/hotspot/src/share/vm/oops/klassVtable.cpp b/hotspot/src/share/vm/oops/klassVtable.cpp
index ebc6e0aea88..7105368840f 100644
--- a/hotspot/src/share/vm/oops/klassVtable.cpp
+++ b/hotspot/src/share/vm/oops/klassVtable.cpp
@@ -47,11 +47,12 @@ inline InstanceKlass* klassVtable::ik() const {
// this function computes the vtable size (including the size needed for miranda
-// methods) and the number of miranda methods in this class
+// methods) and the number of miranda methods in this class.
// Note on Miranda methods: Let's say there is a class C that implements
-// interface I. Let's say there is a method m in I that neither C nor any
-// of its super classes implement (i.e there is no method of any access, with
-// the same name and signature as m), then m is a Miranda method which is
+// interface I, and none of C's superclasses implements I.
+// Let's say there is an abstract method m in I that neither C
+// nor any of its super classes implement (i.e there is no method of any access,
+// with the same name and signature as m), then m is a Miranda method which is
// entered as a public abstract method in C's vtable. From then on it should
// treated as any other public method in C for method over-ride purposes.
void klassVtable::compute_vtable_size_and_num_mirandas(
@@ -111,10 +112,13 @@ void klassVtable::compute_vtable_size_and_num_mirandas(
}
int klassVtable::index_of(Method* m, int len) const {
- assert(m->vtable_index() >= 0, "do not ask this of non-vtable methods");
+ assert(m->has_vtable_index(), "do not ask this of non-vtable methods");
return m->vtable_index();
}
+// Copy super class's vtable to the first part (prefix) of this class's vtable,
+// and return the number of entries copied. Expects that 'super' is the Java
+// super class (arrays can have "array" super classes that must be skipped).
int klassVtable::initialize_from_super(KlassHandle super) {
if (super.is_null()) {
return 0;
@@ -139,14 +143,14 @@ int klassVtable::initialize_from_super(KlassHandle super) {
}
}
-// Revised lookup semantics introduced 1.3 (Kestral beta)
+//
+// Revised lookup semantics introduced 1.3 (Kestrel beta)
void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {
// Note: Arrays can have intermediate array supers. Use java_super to skip them.
KlassHandle super (THREAD, klass()->java_super());
int nofNewEntries = 0;
-
if (PrintVtables && !klass()->oop_is_array()) {
ResourceMark rm(THREAD);
tty->print_cr("Initializing: %s", _klass->name()->as_C_string());
@@ -174,8 +178,10 @@ void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {
int len = methods->length();
int initialized = super_vtable_len;
- // update_inherited_vtable can stop for gc - ensure using handles
+ // Check each of this class's methods against super;
+ // if override, replace in copy of super vtable, otherwise append to end
for (int i = 0; i < len; i++) {
+ // update_inherited_vtable can stop for gc - ensure using handles
HandleMark hm(THREAD);
assert(methods->at(i)->is_method(), "must be a Method*");
methodHandle mh(THREAD, methods->at(i));
@@ -189,11 +195,11 @@ void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {
}
}
- // add miranda methods; it will also update the value of initialized
- fill_in_mirandas(&initialized);
+ // add miranda methods to end of vtable.
+ initialized = fill_in_mirandas(initialized);
// In class hierarchies where the accessibility is not increasing (i.e., going from private ->
- // package_private -> publicprotected), the vtable might actually be smaller than our initial
+ // package_private -> public/protected), the vtable might actually be smaller than our initial
// calculation.
assert(initialized <= _length, "vtable initialization failed");
for(;initialized < _length; initialized++) {
@@ -248,14 +254,8 @@ InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper
return superk;
}
-// Methods that are "effectively" final don't need vtable entries.
-bool method_is_effectively_final(
- AccessFlags klass_flags, methodHandle target) {
- return target->is_final() || klass_flags.is_final() && !target->is_overpass();
-}
-
// Update child's copy of super vtable for overrides
-// OR return true if a new vtable entry is required
+// OR return true if a new vtable entry is required.
// Only called for InstanceKlass's, i.e. not for arrays
// If that changed, could not use _klass as handle for klass
bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle target_method, int super_vtable_len,
@@ -263,6 +263,7 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle tar
ResourceMark rm;
bool allocate_new = true;
assert(klass->oop_is_instance(), "must be InstanceKlass");
+ assert(klass == target_method()->method_holder(), "caller resp.");
// Initialize the method's vtable index to "nonvirtual".
// If we allocate a vtable entry, we will update it to a non-negative number.
@@ -273,11 +274,17 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle tar
return false;
}
- if (method_is_effectively_final(klass->access_flags(), target_method)) {
+ if (target_method->is_final_method(klass->access_flags())) {
// a final method never needs a new entry; final methods can be statically
// resolved and they have to be present in the vtable only if they override
// a super's method, in which case they re-use its entry
allocate_new = false;
+ } else if (klass->is_interface()) {
+ allocate_new = false; // see note below in needs_new_vtable_entry
+ // An interface never allocates new vtable slots, only inherits old ones.
+ // This method will either be assigned its own itable index later,
+ // or be assigned an inherited vtable index in the loop below.
+ target_method()->set_vtable_index(Method::pending_itable_index);
}
// we need a new entry if there is no superclass
@@ -411,8 +418,14 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method,
Symbol* classname,
AccessFlags class_flags,
TRAPS) {
+ if (class_flags.is_interface()) {
+ // Interfaces do not use vtables, so there is no point to assigning
+ // a vtable index to any of their methods. If we refrain from doing this,
+ // we can use Method::_vtable_index to hold the itable index
+ return false;
+ }
- if (method_is_effectively_final(class_flags, target_method) ||
+ if (target_method->is_final_method(class_flags) ||
// a final method never needs a new entry; final methods can be statically
// resolved and they have to be present in the vtable only if they override
// a super's method, in which case they re-use its entry
@@ -500,7 +513,8 @@ int klassVtable::index_of_miranda(Symbol* name, Symbol* signature) {
return Method::invalid_vtable_index;
}
-// check if an entry is miranda
+// check if an entry at an index is miranda
+// requires that method m at entry be declared ("held") by an interface.
bool klassVtable::is_miranda_entry_at(int i) {
Method* m = method_at(i);
Klass* method_holder = m->method_holder();
@@ -516,7 +530,9 @@ bool klassVtable::is_miranda_entry_at(int i) {
return false;
}
-// check if a method is a miranda method, given a class's methods table and it's super
+// check if a method is a miranda method, given a class's methods table and its super
+// "miranda" means not static, not defined by this class, and not defined
+// in super unless it is private and therefore inaccessible to this class.
// the caller must make sure that the method belongs to an interface implemented by the class
bool klassVtable::is_miranda(Method* m, Array* class_methods, Klass* super) {
if (m->is_static()) {
@@ -541,6 +557,14 @@ bool klassVtable::is_miranda(Method* m, Array* class_methods, Klass* su
return false;
}
+// Scans current_interface_methods for miranda methods that do not
+// already appear in new_mirandas and are also not defined-and-non-private
+// in super (superclass). These mirandas are added to all_mirandas if it is
+// not null; in addition, those that are not duplicates of miranda methods
+// inherited by super from its interfaces are added to new_mirandas.
+// Thus, new_mirandas will be the set of mirandas that this class introduces,
+// all_mirandas will be the set of all mirandas applicable to this class
+// including all defined in superclasses.
void klassVtable::add_new_mirandas_to_lists(
GrowableArray* new_mirandas, GrowableArray* all_mirandas,
Array* current_interface_methods, Array* class_methods,
@@ -599,17 +623,22 @@ void klassVtable::get_mirandas(GrowableArray* new_mirandas,
}
}
-// fill in mirandas
-void klassVtable::fill_in_mirandas(int* initialized) {
+// Discover miranda methods ("miranda" = "interface abstract, no binding"),
+// and append them into the vtable starting at index initialized,
+// return the new value of initialized.
+int klassVtable::fill_in_mirandas(int initialized) {
GrowableArray mirandas(20);
get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(),
ik()->local_interfaces());
for (int i = 0; i < mirandas.length(); i++) {
- put_method_at(mirandas.at(i), *initialized);
- ++(*initialized);
+ put_method_at(mirandas.at(i), initialized);
+ ++initialized;
}
+ return initialized;
}
+// Copy this class's vtable to the vtable beginning at start.
+// Used to copy superclass vtable to prefix of subclass's vtable.
void klassVtable::copy_vtable_to(vtableEntry* start) {
Copy::disjoint_words((HeapWord*)table(), (HeapWord*)start, _length * vtableEntry::size());
}
@@ -723,6 +752,12 @@ static int initialize_count = 0;
// Initialization
void klassItable::initialize_itable(bool checkconstraints, TRAPS) {
+ if (_klass->is_interface()) {
+ // This needs to go after vtable indexes are assigned but
+ // before implementors need to know the number of itable indexes.
+ assign_itable_indexes_for_interface(_klass());
+ }
+
// Cannot be setup doing bootstrapping, interfaces don't have
// itables, and klass with only ones entry have empty itables
if (Universe::is_bootstrapping() ||
@@ -754,45 +789,89 @@ void klassItable::initialize_itable(bool checkconstraints, TRAPS) {
}
+inline bool interface_method_needs_itable_index(Method* m) {
+ if (m->is_static()) return false; // e.g., Stream.empty
+ if (m->is_initializer()) return false; // or
+ // If an interface redeclares a method from java.lang.Object,
+ // it should already have a vtable index, don't touch it.
+ // e.g., CharSequence.toString (from initialize_vtable)
+ // if (m->has_vtable_index()) return false; // NO!
+ return true;
+}
+
+int klassItable::assign_itable_indexes_for_interface(Klass* klass) {
+ // an interface does not have an itable, but its methods need to be numbered
+ if (TraceItables) tty->print_cr("%3d: Initializing itable for interface %s", ++initialize_count,
+ klass->name()->as_C_string());
+ Array* methods = InstanceKlass::cast(klass)->methods();
+ int nof_methods = methods->length();
+ int ime_num = 0;
+ for (int i = 0; i < nof_methods; i++) {
+ Method* m = methods->at(i);
+ if (interface_method_needs_itable_index(m)) {
+ assert(!m->is_final_method(), "no final interface methods");
+ // If m is already assigned a vtable index, do not disturb it.
+ if (!m->has_vtable_index()) {
+ assert(m->vtable_index() == Method::pending_itable_index, "set by initialize_vtable");
+ m->set_itable_index(ime_num);
+ // Progress to next itable entry
+ ime_num++;
+ }
+ }
+ }
+ assert(ime_num == method_count_for_interface(klass), "proper sizing");
+ return ime_num;
+}
+
+int klassItable::method_count_for_interface(Klass* interf) {
+ assert(interf->oop_is_instance(), "must be");
+ assert(interf->is_interface(), "must be");
+ Array* methods = InstanceKlass::cast(interf)->methods();
+ int nof_methods = methods->length();
+ while (nof_methods > 0) {
+ Method* m = methods->at(nof_methods-1);
+ if (m->has_itable_index()) {
+ int length = m->itable_index() + 1;
+#ifdef ASSERT
+ while (nof_methods = 0) {
+ m = methods->at(--nof_methods);
+ assert(!m->has_itable_index() || m->itable_index() < length, "");
+ }
+#endif //ASSERT
+ return length; // return the rightmost itable index, plus one
+ }
+ nof_methods -= 1;
+ }
+ // no methods have itable indexes
+ return 0;
+}
+
+
void klassItable::initialize_itable_for_interface(int method_table_offset, KlassHandle interf_h, bool checkconstraints, TRAPS) {
Array* methods = InstanceKlass::cast(interf_h())->methods();
int nof_methods = methods->length();
HandleMark hm;
- KlassHandle klass = _klass;
assert(nof_methods > 0, "at least one method must exist for interface to be in vtable");
Handle interface_loader (THREAD, InstanceKlass::cast(interf_h())->class_loader());
- int ime_num = 0;
- // Skip first Method* if it is a class initializer
- int i = methods->at(0)->is_static_initializer() ? 1 : 0;
-
- // m, method_name, method_signature, klass reset each loop so they
- // don't need preserving across check_signature_loaders call
- // methods needs a handle in case of gc from check_signature_loaders
- for(; i < nof_methods; i++) {
+ int ime_count = method_count_for_interface(interf_h());
+ for (int i = 0; i < nof_methods; i++) {
Method* m = methods->at(i);
- Symbol* method_name = m->name();
- Symbol* method_signature = m->signature();
-
- // This is same code as in Linkresolver::lookup_instance_method_in_klasses
- Method* target = klass->uncached_lookup_method(method_name, method_signature);
- while (target != NULL && target->is_static()) {
- // continue with recursive lookup through the superclass
- Klass* super = target->method_holder()->super();
- target = (super == NULL) ? (Method*)NULL : super->uncached_lookup_method(method_name, method_signature);
+ methodHandle target;
+ if (m->has_itable_index()) {
+ LinkResolver::lookup_instance_method_in_klasses(target, _klass, m->name(), m->signature(), CHECK);
}
if (target == NULL || !target->is_public() || target->is_abstract()) {
// Entry do not resolve. Leave it empty
} else {
// Entry did resolve, check loader constraints before initializing
// if checkconstraints requested
- methodHandle target_h (THREAD, target); // preserve across gc
if (checkconstraints) {
Handle method_holder_loader (THREAD, target->method_holder()->class_loader());
if (method_holder_loader() != interface_loader()) {
ResourceMark rm(THREAD);
Symbol* failed_type_symbol =
- SystemDictionary::check_signature_loaders(method_signature,
+ SystemDictionary::check_signature_loaders(m->signature(),
method_holder_loader,
interface_loader,
true, CHECK);
@@ -803,9 +882,9 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass
"and the class loader (instance of %s) for interface "
"%s have different Class objects for the type %s "
"used in the signature";
- char* sig = target_h()->name_and_sig_as_C_string();
+ char* sig = target()->name_and_sig_as_C_string();
const char* loader1 = SystemDictionary::loader_name(method_holder_loader());
- char* current = klass->name()->as_C_string();
+ char* current = _klass->name()->as_C_string();
const char* loader2 = SystemDictionary::loader_name(interface_loader());
char* iface = InstanceKlass::cast(interf_h())->name()->as_C_string();
char* failed_type_name = failed_type_symbol->as_C_string();
@@ -821,10 +900,10 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass
}
// ime may have moved during GC so recalculate address
- itableOffsetEntry::method_entry(_klass(), method_table_offset)[ime_num].initialize(target_h());
+ int ime_num = m->itable_index();
+ assert(ime_num < ime_count, "oob");
+ itableOffsetEntry::method_entry(_klass(), method_table_offset)[ime_num].initialize(target());
}
- // Progress to next entry
- ime_num++;
}
}
@@ -913,20 +992,22 @@ class InterfaceVisiterClosure : public StackObj {
virtual void doit(Klass* intf, int method_count) = 0;
};
-// Visit all interfaces with at-least one method (excluding )
+// Visit all interfaces with at least one itable method
void visit_all_interfaces(Array* transitive_intf, InterfaceVisiterClosure *blk) {
// Handle array argument
for(int i = 0; i < transitive_intf->length(); i++) {
Klass* intf = transitive_intf->at(i);
assert(intf->is_interface(), "sanity check");
- // Find no. of methods excluding a
- int method_count = InstanceKlass::cast(intf)->methods()->length();
- if (method_count > 0) {
- Method* m = InstanceKlass::cast(intf)->methods()->at(0);
- assert(m != NULL && m->is_method(), "sanity check");
- if (m->name() == vmSymbols::object_initializer_name()) {
- method_count--;
+ // Find no. of itable methods
+ int method_count = 0;
+ // method_count = klassItable::method_count_for_interface(intf);
+ Array* methods = InstanceKlass::cast(intf)->methods();
+ if (methods->length() > 0) {
+ for (int i = methods->length(); --i >= 0; ) {
+ if (interface_method_needs_itable_index(methods->at(i))) {
+ method_count++;
+ }
}
}
@@ -1024,40 +1105,26 @@ void klassItable::setup_itable_offset_table(instanceKlassHandle klass) {
}
-// m must be a method in an interface
-int klassItable::compute_itable_index(Method* m) {
- InstanceKlass* intf = m->method_holder();
- assert(intf->is_interface(), "sanity check");
- Array* methods = intf->methods();
- int index = 0;
- while(methods->at(index) != m) {
- index++;
- assert(index < methods->length(), "should find index for resolve_invoke");
- }
- // Adjust for , which is left out of table if first method
- if (methods->length() > 0 && methods->at(0)->is_static_initializer()) {
- index--;
- }
- return index;
-}
-
-
-// inverse to compute_itable_index
+// inverse to itable_index
Method* klassItable::method_for_itable_index(Klass* intf, int itable_index) {
assert(InstanceKlass::cast(intf)->is_interface(), "sanity check");
+ assert(intf->verify_itable_index(itable_index), "");
Array* methods = InstanceKlass::cast(intf)->methods();
- int index = itable_index;
- // Adjust for , which is left out of table if first method
- if (methods->length() > 0 && methods->at(0)->is_static_initializer()) {
- index++;
- }
-
- if (itable_index < 0 || index >= methods->length())
+ if (itable_index < 0 || itable_index >= method_count_for_interface(intf))
return NULL; // help caller defend against bad indexes
+ int index = itable_index;
Method* m = methods->at(index);
- assert(compute_itable_index(m) == itable_index, "correct inverse");
+ int index2 = -1;
+ while (!m->has_itable_index() ||
+ (index2 = m->itable_index()) != itable_index) {
+ assert(index2 < itable_index, "monotonic");
+ if (++index == methods->length())
+ return NULL;
+ m = methods->at(index);
+ }
+ assert(m->itable_index() == itable_index, "correct inverse");
return m;
}
diff --git a/hotspot/src/share/vm/oops/klassVtable.hpp b/hotspot/src/share/vm/oops/klassVtable.hpp
index 01495e35d90..06d55af2566 100644
--- a/hotspot/src/share/vm/oops/klassVtable.hpp
+++ b/hotspot/src/share/vm/oops/klassVtable.hpp
@@ -124,7 +124,7 @@ class klassVtable : public ResourceObj {
// support for miranda methods
bool is_miranda_entry_at(int i);
- void fill_in_mirandas(int* initialized);
+ int fill_in_mirandas(int initialized);
static bool is_miranda(Method* m, Array* class_methods, Klass* super);
static void add_new_mirandas_to_lists(
GrowableArray* new_mirandas,
@@ -150,6 +150,8 @@ class klassVtable : public ResourceObj {
// from_compiled_code_entry_point -> nmethod entry point
// from_interpreter_entry_point -> i2cadapter
class vtableEntry VALUE_OBJ_CLASS_SPEC {
+ friend class VMStructs;
+
public:
// size in words
static int size() {
@@ -288,12 +290,12 @@ class klassItable : public ResourceObj {
#endif // INCLUDE_JVMTI
// Setup of itable
+ static int assign_itable_indexes_for_interface(Klass* klass);
+ static int method_count_for_interface(Klass* klass);
static int compute_itable_size(Array* transitive_interfaces);
static void setup_itable_offset_table(instanceKlassHandle klass);
// Resolving of method to index
- static int compute_itable_index(Method* m);
- // ...and back again:
static Method* method_for_itable_index(Klass* klass, int itable_index);
// Debugging/Statistics
diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp
index b8e60a774f3..30631fa3b61 100644
--- a/hotspot/src/share/vm/oops/method.cpp
+++ b/hotspot/src/share/vm/oops/method.cpp
@@ -509,24 +509,31 @@ bool Method::compute_has_loops_flag() {
return _access_flags.has_loops();
}
+bool Method::is_final_method(AccessFlags class_access_flags) const {
+ // or "does_not_require_vtable_entry"
+ // overpass can occur, is not final (reuses vtable entry)
+ // private methods get vtable entries for backward class compatibility.
+ if (is_overpass()) return false;
+ return is_final() || class_access_flags.is_final();
+}
bool Method::is_final_method() const {
- // %%% Should return true for private methods also,
- // since there is no way to override them.
- return is_final() || method_holder()->is_final();
+ return is_final_method(method_holder()->access_flags());
}
-
-bool Method::is_strict_method() const {
- return is_strict();
-}
-
-
-bool Method::can_be_statically_bound() const {
- if (is_final_method()) return true;
+bool Method::can_be_statically_bound(AccessFlags class_access_flags) const {
+ if (is_final_method(class_access_flags)) return true;
+#ifdef ASSERT
+ bool is_nonv = (vtable_index() == nonvirtual_vtable_index);
+ if (class_access_flags.is_interface()) assert(is_nonv == is_static(), err_msg("is_nonv=%s", is_nonv));
+#endif
+ assert(valid_vtable_index() || valid_itable_index(), "method must be linked before we ask this question");
return vtable_index() == nonvirtual_vtable_index;
}
+bool Method::can_be_statically_bound() const {
+ return can_be_statically_bound(method_holder()->access_flags());
+}
bool Method::is_accessor() const {
if (code_size() != 5) return false;
@@ -967,7 +974,7 @@ bool Method::is_overridden_in(Klass* k) const {
assert(ik->is_subclass_of(method_holder()), "should be subklass");
assert(ik->vtable() != NULL, "vtable should exist");
- if (vtable_index() == nonvirtual_vtable_index) {
+ if (!has_vtable_index()) {
return false;
} else {
Method* vt_m = ik->method_at_vtable(vtable_index());
@@ -1959,7 +1966,7 @@ void Method::print_on(outputStream* st) const {
void Method::print_value_on(outputStream* st) const {
assert(is_method(), "must be method");
- st->print_cr(internal_name());
+ st->print(internal_name());
print_address_on(st);
st->print(" ");
name()->print_value_on(st);
@@ -1967,6 +1974,7 @@ void Method::print_value_on(outputStream* st) const {
signature()->print_value_on(st);
st->print(" in ");
method_holder()->print_value_on(st);
+ if (WizardMode) st->print("#%d", _vtable_index);
if (WizardMode) st->print("[%d,%d]", size_of_parameters(), max_locals());
if (WizardMode && code() != NULL) st->print(" ((nmethod*)%p)", code());
}
diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp
index faaf5105994..02d2253b80a 100644
--- a/hotspot/src/share/vm/oops/method.hpp
+++ b/hotspot/src/share/vm/oops/method.hpp
@@ -448,16 +448,22 @@ class Method : public Metadata {
enum VtableIndexFlag {
// Valid vtable indexes are non-negative (>= 0).
// These few negative values are used as sentinels.
- highest_unused_vtable_index_value = -5,
+ itable_index_max = -10, // first itable index, growing downward
+ pending_itable_index = -9, // itable index will be assigned
invalid_vtable_index = -4, // distinct from any valid vtable index
garbage_vtable_index = -3, // not yet linked; no vtable layout yet
nonvirtual_vtable_index = -2 // there is no need for vtable dispatch
// 6330203 Note: Do not use -1, which was overloaded with many meanings.
};
DEBUG_ONLY(bool valid_vtable_index() const { return _vtable_index >= nonvirtual_vtable_index; })
- int vtable_index() const { assert(valid_vtable_index(), "");
- return _vtable_index; }
+ bool has_vtable_index() const { return _vtable_index >= 0; }
+ int vtable_index() const { return _vtable_index; }
void set_vtable_index(int index) { _vtable_index = index; }
+ DEBUG_ONLY(bool valid_itable_index() const { return _vtable_index <= pending_itable_index; })
+ bool has_itable_index() const { return _vtable_index <= itable_index_max; }
+ int itable_index() const { assert(valid_itable_index(), "");
+ return itable_index_max - _vtable_index; }
+ void set_itable_index(int index) { _vtable_index = itable_index_max - index; assert(valid_itable_index(), ""); }
// interpreter entry
address interpreter_entry() const { return _i2i_entry; }
@@ -560,10 +566,11 @@ class Method : public Metadata {
// checks method and its method holder
bool is_final_method() const;
- bool is_strict_method() const;
+ bool is_final_method(AccessFlags class_access_flags) const;
// true if method needs no dynamic dispatch (final and/or no vtable entry)
bool can_be_statically_bound() const;
+ bool can_be_statically_bound(AccessFlags class_access_flags) const;
// returns true if the method has any backward branches.
bool has_loops() {
@@ -740,10 +747,6 @@ class Method : public Metadata {
// so handles are not used to avoid deadlock.
jmethodID find_jmethod_id_or_null() { return method_holder()->jmethod_id_or_null(this); }
- // JNI static invoke cached itable index accessors
- int cached_itable_index() { return method_holder()->cached_itable_index(method_idnum()); }
- void set_cached_itable_index(int index) { method_holder()->set_cached_itable_index(method_idnum(), index); }
-
// Support for inlining of intrinsic methods
vmIntrinsics::ID intrinsic_id() const { return (vmIntrinsics::ID) _intrinsic_id; }
void set_intrinsic_id(vmIntrinsics::ID id) { _intrinsic_id = (u1) id; }
diff --git a/hotspot/src/share/vm/oops/methodData.hpp b/hotspot/src/share/vm/oops/methodData.hpp
index 765b91c142c..7ff9b2bbb6d 100644
--- a/hotspot/src/share/vm/oops/methodData.hpp
+++ b/hotspot/src/share/vm/oops/methodData.hpp
@@ -72,6 +72,8 @@ class ProfileData;
//
// Overlay for generic profiling data.
class DataLayout VALUE_OBJ_CLASS_SPEC {
+ friend class VMStructs;
+
private:
// Every data layout begins with a header. This header
// contains a tag, which is used to indicate the size/layout
diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp
index 9a6c1e1787b..f1823f2e2b1 100644
--- a/hotspot/src/share/vm/oops/oop.inline.hpp
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp
@@ -69,7 +69,7 @@ inline markOop oopDesc::cas_set_mark(markOop new_mark, markOop old_mark) {
}
inline Klass* oopDesc::klass() const {
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
return Klass::decode_klass_not_null(_metadata._compressed_klass);
} else {
return _metadata._klass;
@@ -78,7 +78,7 @@ inline Klass* oopDesc::klass() const {
inline Klass* oopDesc::klass_or_null() const volatile {
// can be NULL in CMS
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
return Klass::decode_klass(_metadata._compressed_klass);
} else {
return _metadata._klass;
@@ -86,19 +86,19 @@ inline Klass* oopDesc::klass_or_null() const volatile {
}
inline int oopDesc::klass_gap_offset_in_bytes() {
- assert(UseCompressedKlassPointers, "only applicable to compressed klass pointers");
+ assert(UseCompressedClassPointers, "only applicable to compressed klass pointers");
return oopDesc::klass_offset_in_bytes() + sizeof(narrowKlass);
}
inline Klass** oopDesc::klass_addr() {
// Only used internally and with CMS and will not work with
// UseCompressedOops
- assert(!UseCompressedKlassPointers, "only supported with uncompressed klass pointers");
+ assert(!UseCompressedClassPointers, "only supported with uncompressed klass pointers");
return (Klass**) &_metadata._klass;
}
inline narrowKlass* oopDesc::compressed_klass_addr() {
- assert(UseCompressedKlassPointers, "only called by compressed klass pointers");
+ assert(UseCompressedClassPointers, "only called by compressed klass pointers");
return &_metadata._compressed_klass;
}
@@ -106,7 +106,7 @@ inline void oopDesc::set_klass(Klass* k) {
// since klasses are promoted no store check is needed
assert(Universe::is_bootstrapping() || k != NULL, "must be a real Klass*");
assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass*");
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
*compressed_klass_addr() = Klass::encode_klass_not_null(k);
} else {
*klass_addr() = k;
@@ -118,7 +118,7 @@ inline int oopDesc::klass_gap() const {
}
inline void oopDesc::set_klass_gap(int v) {
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
*(int*)(((intptr_t)this) + klass_gap_offset_in_bytes()) = v;
}
}
@@ -126,7 +126,7 @@ inline void oopDesc::set_klass_gap(int v) {
inline void oopDesc::set_klass_to_list_ptr(oop k) {
// This is only to be used during GC, for from-space objects, so no
// barrier is needed.
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
_metadata._compressed_klass = (narrowKlass)encode_heap_oop(k); // may be null (parnew overflow handling)
} else {
_metadata._klass = (Klass*)(address)k;
@@ -135,7 +135,7 @@ inline void oopDesc::set_klass_to_list_ptr(oop k) {
inline oop oopDesc::list_ptr_from_klass() {
// This is only to be used during GC, for from-space objects.
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
return decode_heap_oop((narrowOop)_metadata._compressed_klass);
} else {
// Special case for GC
diff --git a/hotspot/src/share/vm/oops/symbol.hpp b/hotspot/src/share/vm/oops/symbol.hpp
index f9db8d39974..e747c464607 100644
--- a/hotspot/src/share/vm/oops/symbol.hpp
+++ b/hotspot/src/share/vm/oops/symbol.hpp
@@ -45,7 +45,7 @@
// in the SymbolTable bucket (the _literal field in HashtableEntry)
// that points to the Symbol. All other stores of a Symbol*
// to a field of a persistent variable (e.g., the _name filed in
-// FieldAccessInfo or _ptr in a CPSlot) is reference counted.
+// fieldDescriptor or _ptr in a CPSlot) is reference counted.
//
// 1) The lookup of a "name" in the SymbolTable either creates a Symbol F for
// "name" and returns a pointer to F or finds a pre-existing Symbol F for
diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp
index 15d8befbbac..cf9a82092fd 100644
--- a/hotspot/src/share/vm/opto/c2_globals.hpp
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp
@@ -421,7 +421,7 @@
product(bool, UseDivMod, true, \
"Use combined DivMod instruction if available") \
\
- product(intx, MinJumpTableSize, 18, \
+ product_pd(intx, MinJumpTableSize, \
"Minimum number of targets in a generated jump table") \
\
product(intx, MaxJumpTableSize, 65000, \
@@ -448,6 +448,9 @@
product(bool, EliminateAutoBox, true, \
"Control optimizations for autobox elimination") \
\
+ experimental(bool, UseImplicitStableValues, false, \
+ "Mark well-known stable fields as such (e.g. String.value)") \
+ \
product(intx, AutoBoxCacheMax, 128, \
"Sets max value cached by the java.lang.Integer autobox cache") \
\
diff --git a/hotspot/src/share/vm/opto/cfgnode.cpp b/hotspot/src/share/vm/opto/cfgnode.cpp
index 4185ada5d1c..36347fb9202 100644
--- a/hotspot/src/share/vm/opto/cfgnode.cpp
+++ b/hotspot/src/share/vm/opto/cfgnode.cpp
@@ -1932,7 +1932,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
#ifdef _LP64
// Push DecodeN/DecodeNKlass down through phi.
// The rest of phi graph will transform by split EncodeP node though phis up.
- if ((UseCompressedOops || UseCompressedKlassPointers) && can_reshape && progress == NULL) {
+ if ((UseCompressedOops || UseCompressedClassPointers) && can_reshape && progress == NULL) {
bool may_push = true;
bool has_decodeN = false;
bool is_decodeN = false;
diff --git a/hotspot/src/share/vm/opto/chaitin.cpp b/hotspot/src/share/vm/opto/chaitin.cpp
index a1a0e1c1fb7..492bf384f2f 100644
--- a/hotspot/src/share/vm/opto/chaitin.cpp
+++ b/hotspot/src/share/vm/opto/chaitin.cpp
@@ -122,40 +122,23 @@ double LRG::score() const {
return score;
}
-LRG_List::LRG_List( uint max ) : _cnt(max), _max(max), _lidxs(NEW_RESOURCE_ARRAY(uint,max)) {
- memset( _lidxs, 0, sizeof(uint)*max );
-}
-
-void LRG_List::extend( uint nidx, uint lidx ) {
- _nesting.check();
- if( nidx >= _max ) {
- uint size = 16;
- while( size <= nidx ) size <<=1;
- _lidxs = REALLOC_RESOURCE_ARRAY( uint, _lidxs, _max, size );
- _max = size;
- }
- while( _cnt <= nidx )
- _lidxs[_cnt++] = 0;
- _lidxs[nidx] = lidx;
-}
-
#define NUMBUCKS 3
// Straight out of Tarjan's union-find algorithm
uint LiveRangeMap::find_compress(uint lrg) {
uint cur = lrg;
- uint next = _uf_map[cur];
+ uint next = _uf_map.at(cur);
while (next != cur) { // Scan chain of equivalences
assert( next < cur, "always union smaller");
cur = next; // until find a fixed-point
- next = _uf_map[cur];
+ next = _uf_map.at(cur);
}
// Core of union-find algorithm: update chain of
// equivalences to be equal to the root.
while (lrg != next) {
- uint tmp = _uf_map[lrg];
- _uf_map.map(lrg, next);
+ uint tmp = _uf_map.at(lrg);
+ _uf_map.at_put(lrg, next);
lrg = tmp;
}
return lrg;
@@ -165,10 +148,10 @@ uint LiveRangeMap::find_compress(uint lrg) {
void LiveRangeMap::reset_uf_map(uint max_lrg_id) {
_max_lrg_id= max_lrg_id;
// Force the Union-Find mapping to be at least this large
- _uf_map.extend(_max_lrg_id, 0);
+ _uf_map.at_put_grow(_max_lrg_id, 0);
// Initialize it to be the ID mapping.
for (uint i = 0; i < _max_lrg_id; ++i) {
- _uf_map.map(i, i);
+ _uf_map.at_put(i, i);
}
}
@@ -176,12 +159,12 @@ void LiveRangeMap::reset_uf_map(uint max_lrg_id) {
// the Union-Find mapping after this call.
void LiveRangeMap::compress_uf_map_for_nodes() {
// For all Nodes, compress mapping
- uint unique = _names.Size();
+ uint unique = _names.length();
for (uint i = 0; i < unique; ++i) {
- uint lrg = _names[i];
+ uint lrg = _names.at(i);
uint compressed_lrg = find(lrg);
if (lrg != compressed_lrg) {
- _names.map(i, compressed_lrg);
+ _names.at_put(i, compressed_lrg);
}
}
}
@@ -198,11 +181,11 @@ uint LiveRangeMap::find_const(uint lrg) const {
return lrg;
}
- uint next = _uf_map[lrg];
+ uint next = _uf_map.at(lrg);
while (next != lrg) { // Scan chain of equivalences
assert(next < lrg, "always union smaller");
lrg = next; // until find a fixed-point
- next = _uf_map[lrg];
+ next = _uf_map.at(lrg);
}
return next;
}
@@ -215,7 +198,7 @@ PhaseChaitin::PhaseChaitin(uint unique, PhaseCFG &cfg, Matcher &matcher)
NULL
#endif
)
- , _lrg_map(unique)
+ , _lrg_map(Thread::current()->resource_area(), unique)
, _live(0)
, _spilled_once(Thread::current()->resource_area())
, _spilled_twice(Thread::current()->resource_area())
@@ -692,6 +675,7 @@ void PhaseChaitin::de_ssa() {
_lrg_map.map(n->_idx, rm.is_NotEmpty() ? lr_counter++ : 0);
}
}
+
// Reset the Union-Find mapping to be identity
_lrg_map.reset_uf_map(lr_counter);
}
diff --git a/hotspot/src/share/vm/opto/chaitin.hpp b/hotspot/src/share/vm/opto/chaitin.hpp
index c951024ee75..41276efa5ca 100644
--- a/hotspot/src/share/vm/opto/chaitin.hpp
+++ b/hotspot/src/share/vm/opto/chaitin.hpp
@@ -283,8 +283,8 @@ private:
// Straight out of Tarjan's union-find algorithm
uint find_compress(const Node *node) {
- uint lrg_id = find_compress(_names[node->_idx]);
- _names.map(node->_idx, lrg_id);
+ uint lrg_id = find_compress(_names.at(node->_idx));
+ _names.at_put(node->_idx, lrg_id);
return lrg_id;
}
@@ -305,40 +305,40 @@ public:
}
uint size() const {
- return _names.Size();
+ return _names.length();
}
uint live_range_id(uint idx) const {
- return _names[idx];
+ return _names.at(idx);
}
uint live_range_id(const Node *node) const {
- return _names[node->_idx];
+ return _names.at(node->_idx);
}
uint uf_live_range_id(uint lrg_id) const {
- return _uf_map[lrg_id];
+ return _uf_map.at(lrg_id);
}
void map(uint idx, uint lrg_id) {
- _names.map(idx, lrg_id);
+ _names.at_put(idx, lrg_id);
}
void uf_map(uint dst_lrg_id, uint src_lrg_id) {
- _uf_map.map(dst_lrg_id, src_lrg_id);
+ _uf_map.at_put(dst_lrg_id, src_lrg_id);
}
void extend(uint idx, uint lrg_id) {
- _names.extend(idx, lrg_id);
+ _names.at_put_grow(idx, lrg_id);
}
void uf_extend(uint dst_lrg_id, uint src_lrg_id) {
- _uf_map.extend(dst_lrg_id, src_lrg_id);
+ _uf_map.at_put_grow(dst_lrg_id, src_lrg_id);
}
- LiveRangeMap(uint unique)
- : _names(unique)
- , _uf_map(unique)
+ LiveRangeMap(Arena* arena, uint unique)
+ : _names(arena, unique, unique, 0)
+ , _uf_map(arena, unique, unique, 0)
, _max_lrg_id(0) {}
uint find_id( const Node *n ) {
@@ -355,14 +355,14 @@ public:
void compress_uf_map_for_nodes();
uint find(uint lidx) {
- uint uf_lidx = _uf_map[lidx];
+ uint uf_lidx = _uf_map.at(lidx);
return (uf_lidx == lidx) ? uf_lidx : find_compress(lidx);
}
// Convert a Node into a Live Range Index - a lidx
uint find(const Node *node) {
uint lidx = live_range_id(node);
- uint uf_lidx = _uf_map[lidx];
+ uint uf_lidx = _uf_map.at(lidx);
return (uf_lidx == lidx) ? uf_lidx : find_compress(node);
}
@@ -371,10 +371,10 @@ public:
// Like Find above, but no path compress, so bad asymptotic behavior
uint find_const(const Node *node) const {
- if(node->_idx >= _names.Size()) {
+ if(node->_idx >= (uint)_names.length()) {
return 0; // not mapped, usual for debug dump
}
- return find_const(_names[node->_idx]);
+ return find_const(_names.at(node->_idx));
}
};
diff --git a/hotspot/src/share/vm/opto/coalesce.hpp b/hotspot/src/share/vm/opto/coalesce.hpp
index a6359af101c..3a361b25f11 100644
--- a/hotspot/src/share/vm/opto/coalesce.hpp
+++ b/hotspot/src/share/vm/opto/coalesce.hpp
@@ -29,7 +29,6 @@
class LoopTree;
class LRG;
-class LRG_List;
class Matcher;
class PhaseIFG;
class PhaseCFG;
diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp
index b426bcce1a2..1c625d679b3 100644
--- a/hotspot/src/share/vm/opto/compile.cpp
+++ b/hotspot/src/share/vm/opto/compile.cpp
@@ -1297,6 +1297,10 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const {
// Array pointers need some flattening
const TypeAryPtr *ta = tj->isa_aryptr();
+ if (ta && ta->is_stable()) {
+ // Erase stability property for alias analysis.
+ tj = ta = ta->cast_to_stable(false);
+ }
if( ta && is_known_inst ) {
if ( offset != Type::OffsetBot &&
offset > arrayOopDesc::length_offset_in_bytes() ) {
@@ -1497,6 +1501,7 @@ void Compile::AliasType::Init(int i, const TypePtr* at) {
_index = i;
_adr_type = at;
_field = NULL;
+ _element = NULL;
_is_rewritable = true; // default
const TypeOopPtr *atoop = (at != NULL) ? at->isa_oopptr() : NULL;
if (atoop != NULL && atoop->is_known_instance()) {
@@ -1615,6 +1620,16 @@ Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_cr
&& flat->is_instptr()->klass() == env()->Class_klass())
alias_type(idx)->set_rewritable(false);
}
+ if (flat->isa_aryptr()) {
+#ifdef ASSERT
+ const int header_size_min = arrayOopDesc::base_offset_in_bytes(T_BYTE);
+ // (T_BYTE has the weakest alignment and size restrictions...)
+ assert(flat->offset() < header_size_min, "array body reference must be OffsetBot");
+#endif
+ if (flat->offset() == TypePtr::OffsetBot) {
+ alias_type(idx)->set_element(flat->is_aryptr()->elem());
+ }
+ }
if (flat->isa_klassptr()) {
if (flat->offset() == in_bytes(Klass::super_check_offset_offset()))
alias_type(idx)->set_rewritable(false);
@@ -1677,7 +1692,7 @@ Compile::AliasType* Compile::alias_type(ciField* field) {
else
t = TypeOopPtr::make_from_klass_raw(field->holder());
AliasType* atp = alias_type(t->add_offset(field->offset_in_bytes()), field);
- assert(field->is_final() == !atp->is_rewritable(), "must get the rewritable bits correct");
+ assert((field->is_final() || field->is_stable()) == !atp->is_rewritable(), "must get the rewritable bits correct");
return atp;
}
@@ -2631,7 +2646,7 @@ void Compile::final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc) {
addp->in(AddPNode::Base) == n->in(AddPNode::Base),
"Base pointers must match" );
#ifdef _LP64
- if ((UseCompressedOops || UseCompressedKlassPointers) &&
+ if ((UseCompressedOops || UseCompressedClassPointers) &&
addp->Opcode() == Op_ConP &&
addp == n->in(AddPNode::Base) &&
n->in(AddPNode::Offset)->is_Con()) {
@@ -3018,7 +3033,7 @@ void Compile::final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_
// Skip next transformation if compressed oops are not used.
if ((UseCompressedOops && !Matcher::gen_narrow_oop_implicit_null_checks()) ||
- (!UseCompressedOops && !UseCompressedKlassPointers))
+ (!UseCompressedOops && !UseCompressedClassPointers))
return;
// Go over safepoints nodes to skip DecodeN/DecodeNKlass nodes for debug edges.
diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp
index 60787464bd0..8d862c24125 100644
--- a/hotspot/src/share/vm/opto/compile.hpp
+++ b/hotspot/src/share/vm/opto/compile.hpp
@@ -72,6 +72,7 @@ class Scope;
class StartNode;
class SafePointNode;
class JVMState;
+class Type;
class TypeData;
class TypePtr;
class TypeOopPtr;
@@ -119,6 +120,7 @@ class Compile : public Phase {
int _index; // unique index, used with MergeMemNode
const TypePtr* _adr_type; // normalized address type
ciField* _field; // relevant instance field, or null if none
+ const Type* _element; // relevant array element type, or null if none
bool _is_rewritable; // false if the memory is write-once only
int _general_index; // if this is type is an instance, the general
// type that this is an instance of
@@ -129,6 +131,7 @@ class Compile : public Phase {
int index() const { return _index; }
const TypePtr* adr_type() const { return _adr_type; }
ciField* field() const { return _field; }
+ const Type* element() const { return _element; }
bool is_rewritable() const { return _is_rewritable; }
bool is_volatile() const { return (_field ? _field->is_volatile() : false); }
int general_index() const { return (_general_index != 0) ? _general_index : _index; }
@@ -137,7 +140,14 @@ class Compile : public Phase {
void set_field(ciField* f) {
assert(!_field,"");
_field = f;
- if (f->is_final()) _is_rewritable = false;
+ if (f->is_final() || f->is_stable()) {
+ // In the case of @Stable, multiple writes are possible but may be assumed to be no-ops.
+ _is_rewritable = false;
+ }
+ }
+ void set_element(const Type* e) {
+ assert(_element == NULL, "");
+ _element = e;
}
void print_on(outputStream* st) PRODUCT_RETURN;
diff --git a/hotspot/src/share/vm/opto/connode.cpp b/hotspot/src/share/vm/opto/connode.cpp
index eb343a822e5..b59025ad4f3 100644
--- a/hotspot/src/share/vm/opto/connode.cpp
+++ b/hotspot/src/share/vm/opto/connode.cpp
@@ -630,7 +630,7 @@ const Type *EncodePKlassNode::Value( PhaseTransform *phase ) const {
if (t == Type::TOP) return Type::TOP;
assert (t != TypePtr::NULL_PTR, "null klass?");
- assert(UseCompressedKlassPointers && t->isa_klassptr(), "only klass ptr here");
+ assert(UseCompressedClassPointers && t->isa_klassptr(), "only klass ptr here");
return t->make_narrowklass();
}
diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp
index 18772dfd0a8..dcdd104ee72 100644
--- a/hotspot/src/share/vm/opto/graphKit.cpp
+++ b/hotspot/src/share/vm/opto/graphKit.cpp
@@ -3825,8 +3825,13 @@ Node* GraphKit::load_String_value(Node* ctrl, Node* str) {
TypeAry::make(TypeInt::CHAR,TypeInt::POS),
ciTypeArrayKlass::make(T_CHAR), true, 0);
int value_field_idx = C->get_alias_index(value_field_type);
- return make_load(ctrl, basic_plus_adr(str, str, value_offset),
- value_type, T_OBJECT, value_field_idx);
+ Node* load = make_load(ctrl, basic_plus_adr(str, str, value_offset),
+ value_type, T_OBJECT, value_field_idx);
+ // String.value field is known to be @Stable.
+ if (UseImplicitStableValues) {
+ load = cast_array_to_stable(load, value_type);
+ }
+ return load;
}
void GraphKit::store_String_offset(Node* ctrl, Node* str, Node* value) {
@@ -3844,9 +3849,6 @@ void GraphKit::store_String_value(Node* ctrl, Node* str, Node* value) {
const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
false, NULL, 0);
const TypePtr* value_field_type = string_type->add_offset(value_offset);
- const TypeAryPtr* value_type = TypeAryPtr::make(TypePtr::NotNull,
- TypeAry::make(TypeInt::CHAR,TypeInt::POS),
- ciTypeArrayKlass::make(T_CHAR), true, 0);
int value_field_idx = C->get_alias_index(value_field_type);
store_to_memory(ctrl, basic_plus_adr(str, value_offset),
value, T_OBJECT, value_field_idx);
@@ -3861,3 +3863,9 @@ void GraphKit::store_String_length(Node* ctrl, Node* str, Node* value) {
store_to_memory(ctrl, basic_plus_adr(str, count_offset),
value, T_INT, count_field_idx);
}
+
+Node* GraphKit::cast_array_to_stable(Node* ary, const TypeAryPtr* ary_type) {
+ // Reify the property as a CastPP node in Ideal graph to comply with monotonicity
+ // assumption of CCP analysis.
+ return _gvn.transform(new(C) CastPPNode(ary, ary_type->cast_to_stable(true)));
+}
diff --git a/hotspot/src/share/vm/opto/graphKit.hpp b/hotspot/src/share/vm/opto/graphKit.hpp
index e9d102cb6c5..1fd4e86d2e7 100644
--- a/hotspot/src/share/vm/opto/graphKit.hpp
+++ b/hotspot/src/share/vm/opto/graphKit.hpp
@@ -836,6 +836,9 @@ class GraphKit : public Phase {
// Insert a loop predicate into the graph
void add_predicate(int nargs = 0);
void add_predicate_impl(Deoptimization::DeoptReason reason, int nargs);
+
+ // Produce new array node of stable type
+ Node* cast_array_to_stable(Node* ary, const TypeAryPtr* ary_type);
};
// Helper class to support building of control flow branches. Upon
diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp
index 60525d73ef7..2bfa25fa9c2 100644
--- a/hotspot/src/share/vm/opto/library_call.cpp
+++ b/hotspot/src/share/vm/opto/library_call.cpp
@@ -1280,6 +1280,11 @@ Node* LibraryCallKit::string_indexOf(Node* string_object, ciTypeArray* target_ar
const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin));
const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot);
+ // String.value field is known to be @Stable.
+ if (UseImplicitStableValues) {
+ target = cast_array_to_stable(target, target_type);
+ }
+
IdealKit kit(this, false, true);
#define __ kit.
Node* zero = __ ConI(0);
@@ -3729,6 +3734,8 @@ Node* LibraryCallKit::generate_virtual_guard(Node* obj_klass,
RegionNode* slow_region) {
ciMethod* method = callee();
int vtable_index = method->vtable_index();
+ assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index,
+ err_msg_res("bad index %d", vtable_index));
// Get the Method* out of the appropriate vtable entry.
int entry_offset = (InstanceKlass::vtable_start_offset() +
vtable_index*vtableEntry::size()) * wordSize +
@@ -3779,6 +3786,8 @@ LibraryCallKit::generate_method_call(vmIntrinsics::ID method_id, bool is_virtual
// so the vtable index is fixed.
// No need to use the linkResolver to get it.
vtable_index = method->vtable_index();
+ assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index,
+ err_msg_res("bad index %d", vtable_index));
}
slow_call = new(C) CallDynamicJavaNode(tf,
SharedRuntime::get_resolve_virtual_call_stub(),
@@ -4199,7 +4208,7 @@ void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, b
// 12 - 64-bit VM, compressed klass
// 16 - 64-bit VM, normal klass
if (base_off % BytesPerLong != 0) {
- assert(UseCompressedKlassPointers, "");
+ assert(UseCompressedClassPointers, "");
if (is_array) {
// Exclude length to copy by 8 bytes words.
base_off += sizeof(int);
diff --git a/hotspot/src/share/vm/opto/live.cpp b/hotspot/src/share/vm/opto/live.cpp
index 280d22204c2..02bbb1b97ab 100644
--- a/hotspot/src/share/vm/opto/live.cpp
+++ b/hotspot/src/share/vm/opto/live.cpp
@@ -91,7 +91,7 @@ void PhaseLive::compute(uint maxlrg) {
break;
}
- uint r = _names[n->_idx];
+ uint r = _names.at(n->_idx);
assert(!def_outside->member(r), "Use of external LRG overlaps the same LRG defined in this block");
def->insert( r );
use->remove( r );
@@ -100,7 +100,7 @@ void PhaseLive::compute(uint maxlrg) {
Node *nk = n->in(k);
uint nkidx = nk->_idx;
if (_cfg.get_block_for_node(nk) != block) {
- uint u = _names[nkidx];
+ uint u = _names.at(nkidx);
use->insert(u);
DEBUG_ONLY(def_outside->insert(u);)
}
@@ -112,7 +112,7 @@ void PhaseLive::compute(uint maxlrg) {
#endif
// Remove anything defined by Phis and the block start instruction
for (uint k = i; k > 0; k--) {
- uint r = _names[block->get_node(k - 1)->_idx];
+ uint r = _names.at(block->get_node(k - 1)->_idx);
def->insert(r);
use->remove(r);
}
@@ -124,7 +124,7 @@ void PhaseLive::compute(uint maxlrg) {
// PhiNode uses go in the live-out set of prior blocks.
for (uint k = i; k > 0; k--) {
- add_liveout(p, _names[block->get_node(k-1)->in(l)->_idx], first_pass);
+ add_liveout(p, _names.at(block->get_node(k-1)->in(l)->_idx), first_pass);
}
}
freeset(block);
@@ -256,7 +256,7 @@ void PhaseLive::dump( const Block *b ) const {
tty->print("LiveOut: "); _live[b->_pre_order-1].dump();
uint cnt = b->number_of_nodes();
for( uint i=0; iprint("L%d/", _names[b->get_node(i)->_idx] );
+ tty->print("L%d/", _names.at(b->get_node(i)->_idx));
b->get_node(i)->dump();
}
tty->print("\n");
@@ -321,7 +321,7 @@ void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const {
#ifdef _LP64
UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_CastPP ||
UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_DecodeN ||
- UseCompressedKlassPointers && check->as_Mach()->ideal_Opcode() == Op_DecodeNKlass ||
+ UseCompressedClassPointers && check->as_Mach()->ideal_Opcode() == Op_DecodeNKlass ||
#endif
check->as_Mach()->ideal_Opcode() == Op_LoadP ||
check->as_Mach()->ideal_Opcode() == Op_LoadKlass)) {
diff --git a/hotspot/src/share/vm/opto/live.hpp b/hotspot/src/share/vm/opto/live.hpp
index c2ebe758cf8..e449bb3f3a6 100644
--- a/hotspot/src/share/vm/opto/live.hpp
+++ b/hotspot/src/share/vm/opto/live.hpp
@@ -40,27 +40,7 @@ class IndexSet;
//------------------------------LRG_List---------------------------------------
// Map Node indices to Live RanGe indices.
// Array lookup in the optimized case.
-class LRG_List : public ResourceObj {
- friend class VMStructs;
- uint _cnt, _max;
- uint* _lidxs;
- ReallocMark _nesting; // assertion check for reallocations
-public:
- LRG_List( uint max );
-
- uint lookup( uint nidx ) const {
- return _lidxs[nidx];
- }
- uint operator[] (uint nidx) const { return lookup(nidx); }
-
- void map( uint nidx, uint lidx ) {
- assert( nidx < _cnt, "oob" );
- _lidxs[nidx] = lidx;
- }
- void extend( uint nidx, uint lidx );
-
- uint Size() const { return _cnt; }
-};
+typedef GrowableArray LRG_List;
//------------------------------PhaseLive--------------------------------------
// Compute live-in/live-out
diff --git a/hotspot/src/share/vm/opto/macro.cpp b/hotspot/src/share/vm/opto/macro.cpp
index 137c529ed0c..06bf9e608c0 100644
--- a/hotspot/src/share/vm/opto/macro.cpp
+++ b/hotspot/src/share/vm/opto/macro.cpp
@@ -2191,7 +2191,7 @@ void PhaseMacroExpand::expand_lock_node(LockNode *lock) {
Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes());
klass_node = transform_later( LoadKlassNode::make(_igvn, mem, k_adr, _igvn.type(k_adr)->is_ptr()) );
#ifdef _LP64
- if (UseCompressedKlassPointers && klass_node->is_DecodeNKlass()) {
+ if (UseCompressedClassPointers && klass_node->is_DecodeNKlass()) {
assert(klass_node->in(1)->Opcode() == Op_LoadNKlass, "sanity");
klass_node->in(1)->init_req(0, ctrl);
} else
diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp
index aa03b5ff6c5..49694b6e92e 100644
--- a/hotspot/src/share/vm/opto/memnode.cpp
+++ b/hotspot/src/share/vm/opto/memnode.cpp
@@ -962,6 +962,19 @@ uint LoadNode::hash() const {
return (uintptr_t)in(Control) + (uintptr_t)in(Memory) + (uintptr_t)in(Address);
}
+static bool skip_through_membars(Compile::AliasType* atp, const TypeInstPtr* tp, bool eliminate_boxing) {
+ if ((atp != NULL) && (atp->index() >= Compile::AliasIdxRaw)) {
+ bool non_volatile = (atp->field() != NULL) && !atp->field()->is_volatile();
+ bool is_stable_ary = FoldStableValues &&
+ (tp != NULL) && (tp->isa_aryptr() != NULL) &&
+ tp->isa_aryptr()->is_stable();
+
+ return (eliminate_boxing && non_volatile) || is_stable_ary;
+ }
+
+ return false;
+}
+
//---------------------------can_see_stored_value------------------------------
// This routine exists to make sure this set of tests is done the same
// everywhere. We need to make a coordinated change: first LoadNode::Ideal
@@ -976,11 +989,9 @@ Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const {
const TypeInstPtr* tp = phase->type(ld_adr)->isa_instptr();
Compile::AliasType* atp = (tp != NULL) ? phase->C->alias_type(tp) : NULL;
// This is more general than load from boxing objects.
- if (phase->C->eliminate_boxing() && (atp != NULL) &&
- (atp->index() >= Compile::AliasIdxRaw) &&
- (atp->field() != NULL) && !atp->field()->is_volatile()) {
+ if (skip_through_membars(atp, tp, phase->C->eliminate_boxing())) {
uint alias_idx = atp->index();
- bool final = atp->field()->is_final();
+ bool final = !atp->is_rewritable();
Node* result = NULL;
Node* current = st;
// Skip through chains of MemBarNodes checking the MergeMems for
@@ -1015,7 +1026,6 @@ Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const {
}
}
-
// Loop around twice in the case Load -> Initialize -> Store.
// (See PhaseIterGVN::add_users_to_worklist, which knows about this case.)
for (int trip = 0; trip <= 1; trip++) {
@@ -1577,6 +1587,40 @@ LoadNode::load_array_final_field(const TypeKlassPtr *tkls,
return NULL;
}
+// Try to constant-fold a stable array element.
+static const Type* fold_stable_ary_elem(const TypeAryPtr* ary, int off, BasicType loadbt) {
+ assert(ary->is_stable(), "array should be stable");
+
+ if (ary->const_oop() != NULL) {
+ // Decode the results of GraphKit::array_element_address.
+ ciArray* aobj = ary->const_oop()->as_array();
+ ciConstant con = aobj->element_value_by_offset(off);
+
+ if (con.basic_type() != T_ILLEGAL && !con.is_null_or_zero()) {
+ const Type* con_type = Type::make_from_constant(con);
+ if (con_type != NULL) {
+ if (con_type->isa_aryptr()) {
+ // Join with the array element type, in case it is also stable.
+ int dim = ary->stable_dimension();
+ con_type = con_type->is_aryptr()->cast_to_stable(true, dim-1);
+ }
+ if (loadbt == T_NARROWOOP && con_type->isa_oopptr()) {
+ con_type = con_type->make_narrowoop();
+ }
+#ifndef PRODUCT
+ if (TraceIterativeGVN) {
+ tty->print("FoldStableValues: array element [off=%d]: con_type=", off);
+ con_type->dump(); tty->cr();
+ }
+#endif //PRODUCT
+ return con_type;
+ }
+ }
+ }
+
+ return NULL;
+}
+
//------------------------------Value-----------------------------------------
const Type *LoadNode::Value( PhaseTransform *phase ) const {
// Either input is TOP ==> the result is TOP
@@ -1591,8 +1635,31 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const {
Compile* C = phase->C;
// Try to guess loaded type from pointer type
- if (tp->base() == Type::AryPtr) {
- const Type *t = tp->is_aryptr()->elem();
+ if (tp->isa_aryptr()) {
+ const TypeAryPtr* ary = tp->is_aryptr();
+ const Type *t = ary->elem();
+
+ // Determine whether the reference is beyond the header or not, by comparing
+ // the offset against the offset of the start of the array's data.
+ // Different array types begin at slightly different offsets (12 vs. 16).
+ // We choose T_BYTE as an example base type that is least restrictive
+ // as to alignment, which will therefore produce the smallest
+ // possible base offset.
+ const int min_base_off = arrayOopDesc::base_offset_in_bytes(T_BYTE);
+ const bool off_beyond_header = ((uint)off >= (uint)min_base_off);
+
+ // Try to constant-fold a stable array element.
+ if (FoldStableValues && ary->is_stable()) {
+ // Make sure the reference is not into the header
+ if (off_beyond_header && off != Type::OffsetBot) {
+ assert(adr->is_AddP() && adr->in(AddPNode::Offset)->is_Con(), "offset is a constant");
+ const Type* con_type = fold_stable_ary_elem(ary, off, memory_type());
+ if (con_type != NULL) {
+ return con_type;
+ }
+ }
+ }
+
// Don't do this for integer types. There is only potential profit if
// the element type t is lower than _type; that is, for int types, if _type is
// more restrictive than t. This only happens here if one is short and the other
@@ -1613,14 +1680,7 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const {
&& Opcode() != Op_LoadKlass && Opcode() != Op_LoadNKlass) {
// t might actually be lower than _type, if _type is a unique
// concrete subclass of abstract class t.
- // Make sure the reference is not into the header, by comparing
- // the offset against the offset of the start of the array's data.
- // Different array types begin at slightly different offsets (12 vs. 16).
- // We choose T_BYTE as an example base type that is least restrictive
- // as to alignment, which will therefore produce the smallest
- // possible base offset.
- const int min_base_off = arrayOopDesc::base_offset_in_bytes(T_BYTE);
- if ((uint)off >= (uint)min_base_off) { // is the offset beyond the header?
+ if (off_beyond_header) { // is the offset beyond the header?
const Type* jt = t->join(_type);
// In any case, do not allow the join, per se, to empty out the type.
if (jt->empty() && !t->empty()) {
@@ -1971,7 +2031,7 @@ Node *LoadKlassNode::make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* a
assert(adr_type != NULL, "expecting TypeKlassPtr");
#ifdef _LP64
if (adr_type->is_ptr_to_narrowklass()) {
- assert(UseCompressedKlassPointers, "no compressed klasses");
+ assert(UseCompressedClassPointers, "no compressed klasses");
Node* load_klass = gvn.transform(new (C) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowklass()));
return new (C) DecodeNKlassNode(load_klass, load_klass->bottom_type()->make_ptr());
}
@@ -2309,7 +2369,7 @@ StoreNode* StoreNode::make( PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, cons
val = gvn.transform(new (C) EncodePNode(val, val->bottom_type()->make_narrowoop()));
return new (C) StoreNNode(ctl, mem, adr, adr_type, val);
} else if (adr->bottom_type()->is_ptr_to_narrowklass() ||
- (UseCompressedKlassPointers && val->bottom_type()->isa_klassptr() &&
+ (UseCompressedClassPointers && val->bottom_type()->isa_klassptr() &&
adr->bottom_type()->isa_rawptr())) {
val = gvn.transform(new (C) EncodePKlassNode(val, val->bottom_type()->make_narrowklass()));
return new (C) StoreNKlassNode(ctl, mem, adr, adr_type, val);
diff --git a/hotspot/src/share/vm/opto/parse.hpp b/hotspot/src/share/vm/opto/parse.hpp
index 91025bf56fb..ea01b08475e 100644
--- a/hotspot/src/share/vm/opto/parse.hpp
+++ b/hotspot/src/share/vm/opto/parse.hpp
@@ -518,7 +518,7 @@ class Parse : public GraphKit {
// loading from a constant field or the constant pool
// returns false if push failed (non-perm field constants only, not ldcs)
- bool push_constant(ciConstant con, bool require_constant = false, bool is_autobox_cache = false);
+ bool push_constant(ciConstant con, bool require_constant = false, bool is_autobox_cache = false, const Type* basic_type = NULL);
// implementation of object creation bytecodes
void emit_guard_for_new(ciInstanceKlass* klass);
diff --git a/hotspot/src/share/vm/opto/parse3.cpp b/hotspot/src/share/vm/opto/parse3.cpp
index 28eb0580bad..8c545f3ece5 100644
--- a/hotspot/src/share/vm/opto/parse3.cpp
+++ b/hotspot/src/share/vm/opto/parse3.cpp
@@ -147,7 +147,15 @@ void Parse::do_field_access(bool is_get, bool is_field) {
void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) {
// Does this field have a constant value? If so, just push the value.
if (field->is_constant()) {
- // final field
+ // final or stable field
+ const Type* stable_type = NULL;
+ if (FoldStableValues && field->is_stable()) {
+ stable_type = Type::get_const_type(field->type());
+ if (field->type()->is_array_klass()) {
+ int stable_dimension = field->type()->as_array_klass()->dimension();
+ stable_type = stable_type->is_aryptr()->cast_to_stable(true, stable_dimension);
+ }
+ }
if (field->is_static()) {
// final static field
if (C->eliminate_boxing()) {
@@ -167,11 +175,10 @@ void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) {
}
}
}
- if (push_constant(field->constant_value()))
+ if (push_constant(field->constant_value(), false, false, stable_type))
return;
- }
- else {
- // final non-static field
+ } else {
+ // final or stable non-static field
// Treat final non-static fields of trusted classes (classes in
// java.lang.invoke and sun.invoke packages and subpackages) as
// compile time constants.
@@ -179,8 +186,12 @@ void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) {
const TypeOopPtr* oop_ptr = obj->bottom_type()->isa_oopptr();
ciObject* constant_oop = oop_ptr->const_oop();
ciConstant constant = field->constant_value_of(constant_oop);
- if (push_constant(constant, true))
- return;
+ if (FoldStableValues && field->is_stable() && constant.is_null_or_zero()) {
+ // fall through to field load; the field is not yet initialized
+ } else {
+ if (push_constant(constant, true, false, stable_type))
+ return;
+ }
}
}
}
@@ -301,7 +312,8 @@ void Parse::do_put_xxx(Node* obj, ciField* field, bool is_field) {
// Note the presence of writes to final non-static fields, so that we
// can insert a memory barrier later on to keep the writes from floating
// out of the constructor.
- if (is_field && field->is_final()) {
+ // Any method can write a @Stable field; insert memory barriers after those also.
+ if (is_field && (field->is_final() || field->is_stable())) {
set_wrote_final(true);
// Preserve allocation ptr to create precedent edge to it in membar
// generated on exit from constructor.
@@ -314,35 +326,21 @@ void Parse::do_put_xxx(Node* obj, ciField* field, bool is_field) {
}
-bool Parse::push_constant(ciConstant constant, bool require_constant, bool is_autobox_cache) {
+
+bool Parse::push_constant(ciConstant constant, bool require_constant, bool is_autobox_cache, const Type* stable_type) {
+ const Type* con_type = Type::make_from_constant(constant, require_constant, is_autobox_cache);
switch (constant.basic_type()) {
- case T_BOOLEAN: push( intcon(constant.as_boolean()) ); break;
- case T_INT: push( intcon(constant.as_int()) ); break;
- case T_CHAR: push( intcon(constant.as_char()) ); break;
- case T_BYTE: push( intcon(constant.as_byte()) ); break;
- case T_SHORT: push( intcon(constant.as_short()) ); break;
- case T_FLOAT: push( makecon(TypeF::make(constant.as_float())) ); break;
- case T_DOUBLE: push_pair( makecon(TypeD::make(constant.as_double())) ); break;
- case T_LONG: push_pair( longcon(constant.as_long()) ); break;
case T_ARRAY:
- case T_OBJECT: {
+ case T_OBJECT:
// cases:
// can_be_constant = (oop not scavengable || ScavengeRootsInCode != 0)
// should_be_constant = (oop not scavengable || ScavengeRootsInCode >= 2)
// An oop is not scavengable if it is in the perm gen.
- ciObject* oop_constant = constant.as_object();
- if (oop_constant->is_null_object()) {
- push( zerocon(T_OBJECT) );
- break;
- } else if (require_constant || oop_constant->should_be_constant()) {
- push( makecon(TypeOopPtr::make_from_constant(oop_constant, require_constant, is_autobox_cache)) );
- break;
- } else {
- // we cannot inline the oop, but we can use it later to narrow a type
- return false;
- }
- }
- case T_ILLEGAL: {
+ if (stable_type != NULL && con_type != NULL && con_type->isa_oopptr())
+ con_type = con_type->join(stable_type);
+ break;
+
+ case T_ILLEGAL:
// Invalid ciConstant returned due to OutOfMemoryError in the CI
assert(C->env()->failing(), "otherwise should not see this");
// These always occur because of object types; we are going to
@@ -350,17 +348,16 @@ bool Parse::push_constant(ciConstant constant, bool require_constant, bool is_au
push( zerocon(T_OBJECT) );
return false;
}
- default:
- ShouldNotReachHere();
- return false;
- }
- // success
+ if (con_type == NULL)
+ // we cannot inline the oop, but we can use it later to narrow a type
+ return false;
+
+ push_node(constant.basic_type(), makecon(con_type));
return true;
}
-
//=============================================================================
void Parse::do_anewarray() {
bool will_link;
diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp
index fabcf1cad16..e25c529a886 100644
--- a/hotspot/src/share/vm/opto/type.cpp
+++ b/hotspot/src/share/vm/opto/type.cpp
@@ -189,6 +189,38 @@ const Type* Type::get_typeflow_type(ciType* type) {
}
+//-----------------------make_from_constant------------------------------------
+const Type* Type::make_from_constant(ciConstant constant,
+ bool require_constant, bool is_autobox_cache) {
+ switch (constant.basic_type()) {
+ case T_BOOLEAN: return TypeInt::make(constant.as_boolean());
+ case T_CHAR: return TypeInt::make(constant.as_char());
+ case T_BYTE: return TypeInt::make(constant.as_byte());
+ case T_SHORT: return TypeInt::make(constant.as_short());
+ case T_INT: return TypeInt::make(constant.as_int());
+ case T_LONG: return TypeLong::make(constant.as_long());
+ case T_FLOAT: return TypeF::make(constant.as_float());
+ case T_DOUBLE: return TypeD::make(constant.as_double());
+ case T_ARRAY:
+ case T_OBJECT:
+ {
+ // cases:
+ // can_be_constant = (oop not scavengable || ScavengeRootsInCode != 0)
+ // should_be_constant = (oop not scavengable || ScavengeRootsInCode >= 2)
+ // An oop is not scavengable if it is in the perm gen.
+ ciObject* oop_constant = constant.as_object();
+ if (oop_constant->is_null_object()) {
+ return Type::get_zero_type(T_OBJECT);
+ } else if (require_constant || oop_constant->should_be_constant()) {
+ return TypeOopPtr::make_from_constant(oop_constant, require_constant, is_autobox_cache);
+ }
+ }
+ }
+ // Fall through to failure
+ return NULL;
+}
+
+
//------------------------------make-------------------------------------------
// Create a simple Type, with default empty symbol sets. Then hashcons it
// and look for an existing copy in the type dictionary.
@@ -1824,12 +1856,12 @@ inline const TypeInt* normalize_array_size(const TypeInt* size) {
}
//------------------------------make-------------------------------------------
-const TypeAry *TypeAry::make( const Type *elem, const TypeInt *size) {
+const TypeAry* TypeAry::make(const Type* elem, const TypeInt* size, bool stable) {
if (UseCompressedOops && elem->isa_oopptr()) {
elem = elem->make_narrowoop();
}
size = normalize_array_size(size);
- return (TypeAry*)(new TypeAry(elem,size))->hashcons();
+ return (TypeAry*)(new TypeAry(elem,size,stable))->hashcons();
}
//------------------------------meet-------------------------------------------
@@ -1850,7 +1882,8 @@ const Type *TypeAry::xmeet( const Type *t ) const {
case Array: { // Meeting 2 arrays?
const TypeAry *a = t->is_ary();
return TypeAry::make(_elem->meet(a->_elem),
- _size->xmeet(a->_size)->is_int());
+ _size->xmeet(a->_size)->is_int(),
+ _stable & a->_stable);
}
case Top:
break;
@@ -1863,7 +1896,7 @@ const Type *TypeAry::xmeet( const Type *t ) const {
const Type *TypeAry::xdual() const {
const TypeInt* size_dual = _size->dual()->is_int();
size_dual = normalize_array_size(size_dual);
- return new TypeAry( _elem->dual(), size_dual);
+ return new TypeAry(_elem->dual(), size_dual, !_stable);
}
//------------------------------eq---------------------------------------------
@@ -1871,13 +1904,14 @@ const Type *TypeAry::xdual() const {
bool TypeAry::eq( const Type *t ) const {
const TypeAry *a = (const TypeAry*)t;
return _elem == a->_elem &&
+ _stable == a->_stable &&
_size == a->_size;
}
//------------------------------hash-------------------------------------------
// Type-specific hashing function.
int TypeAry::hash(void) const {
- return (intptr_t)_elem + (intptr_t)_size;
+ return (intptr_t)_elem + (intptr_t)_size + (_stable ? 43 : 0);
}
//----------------------interface_vs_oop---------------------------------------
@@ -1894,6 +1928,7 @@ bool TypeAry::interface_vs_oop(const Type *t) const {
//------------------------------dump2------------------------------------------
#ifndef PRODUCT
void TypeAry::dump2( Dict &d, uint depth, outputStream *st ) const {
+ if (_stable) st->print("stable:");
_elem->dump2(d, depth, st);
st->print("[");
_size->dump2(d, depth, st);
@@ -2381,7 +2416,7 @@ TypeOopPtr::TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int
#ifdef _LP64
if (_offset != 0) {
if (_offset == oopDesc::klass_offset_in_bytes()) {
- _is_ptr_to_narrowklass = UseCompressedKlassPointers;
+ _is_ptr_to_narrowklass = UseCompressedClassPointers;
} else if (klass() == NULL) {
// Array with unknown body type
assert(this->isa_aryptr(), "only arrays without klass");
@@ -3457,11 +3492,39 @@ const TypeAryPtr* TypeAryPtr::cast_to_size(const TypeInt* new_size) const {
assert(new_size != NULL, "");
new_size = narrow_size_type(new_size);
if (new_size == size()) return this;
- const TypeAry* new_ary = TypeAry::make(elem(), new_size);
+ const TypeAry* new_ary = TypeAry::make(elem(), new_size, is_stable());
return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id);
}
+//------------------------------cast_to_stable---------------------------------
+const TypeAryPtr* TypeAryPtr::cast_to_stable(bool stable, int stable_dimension) const {
+ if (stable_dimension <= 0 || (stable_dimension == 1 && stable == this->is_stable()))
+ return this;
+
+ const Type* elem = this->elem();
+ const TypePtr* elem_ptr = elem->make_ptr();
+
+ if (stable_dimension > 1 && elem_ptr != NULL && elem_ptr->isa_aryptr()) {
+ // If this is widened from a narrow oop, TypeAry::make will re-narrow it.
+ elem = elem_ptr = elem_ptr->is_aryptr()->cast_to_stable(stable, stable_dimension - 1);
+ }
+
+ const TypeAry* new_ary = TypeAry::make(elem, size(), stable);
+
+ return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id);
+}
+
+//-----------------------------stable_dimension--------------------------------
+int TypeAryPtr::stable_dimension() const {
+ if (!is_stable()) return 0;
+ int dim = 1;
+ const TypePtr* elem_ptr = elem()->make_ptr();
+ if (elem_ptr != NULL && elem_ptr->isa_aryptr())
+ dim += elem_ptr->is_aryptr()->stable_dimension();
+ return dim;
+}
+
//------------------------------eq---------------------------------------------
// Structural equality check for Type representations
bool TypeAryPtr::eq( const Type *t ) const {
@@ -3570,7 +3633,7 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const {
// Something like byte[int+] meets char[int+].
// This must fall to bottom, not (int[-128..65535])[int+].
instance_id = InstanceBot;
- tary = TypeAry::make(Type::BOTTOM, tary->_size);
+ tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable);
}
} else // Non integral arrays.
// Must fall to bottom if exact klasses in upper lattice
@@ -3584,7 +3647,7 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const {
(tap ->_klass_is_exact && !tap->klass()->is_subtype_of(klass())) ||
// 'this' is exact and super or unrelated:
(this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) {
- tary = TypeAry::make(Type::BOTTOM, tary->_size);
+ tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable);
return make( NotNull, NULL, tary, lazy_klass, false, off, InstanceBot );
}
diff --git a/hotspot/src/share/vm/opto/type.hpp b/hotspot/src/share/vm/opto/type.hpp
index 55d98bd5e51..d4832591843 100644
--- a/hotspot/src/share/vm/opto/type.hpp
+++ b/hotspot/src/share/vm/opto/type.hpp
@@ -372,6 +372,10 @@ public:
// Mapping from CI type system to compiler type:
static const Type* get_typeflow_type(ciType* type);
+ static const Type* make_from_constant(ciConstant constant,
+ bool require_constant = false,
+ bool is_autobox_cache = false);
+
private:
// support arrays
static const BasicType _basic_type[];
@@ -588,8 +592,8 @@ public:
//------------------------------TypeAry----------------------------------------
// Class of Array Types
class TypeAry : public Type {
- TypeAry( const Type *elem, const TypeInt *size) : Type(Array),
- _elem(elem), _size(size) {}
+ TypeAry(const Type* elem, const TypeInt* size, bool stable) : Type(Array),
+ _elem(elem), _size(size), _stable(stable) {}
public:
virtual bool eq( const Type *t ) const;
virtual int hash() const; // Type specific hashing
@@ -599,10 +603,11 @@ public:
private:
const Type *_elem; // Element type of array
const TypeInt *_size; // Elements in array
+ const bool _stable; // Are elements @Stable?
friend class TypeAryPtr;
public:
- static const TypeAry *make( const Type *elem, const TypeInt *size);
+ static const TypeAry* make(const Type* elem, const TypeInt* size, bool stable = false);
virtual const Type *xmeet( const Type *t ) const;
virtual const Type *xdual() const; // Compute dual right now.
@@ -988,6 +993,7 @@ public:
const TypeAry* ary() const { return _ary; }
const Type* elem() const { return _ary->_elem; }
const TypeInt* size() const { return _ary->_size; }
+ bool is_stable() const { return _ary->_stable; }
bool is_autobox_cache() const { return _is_autobox_cache; }
@@ -1011,6 +1017,9 @@ public:
virtual const Type *xmeet( const Type *t ) const;
virtual const Type *xdual() const; // Compute dual right now.
+ const TypeAryPtr* cast_to_stable(bool stable, int stable_dimension = 1) const;
+ int stable_dimension() const;
+
// Convenience common pre-built types.
static const TypeAryPtr *RANGE;
static const TypeAryPtr *OOPS;
diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp
index ea44e2c6679..c7886920b3e 100644
--- a/hotspot/src/share/vm/prims/jni.cpp
+++ b/hotspot/src/share/vm/prims/jni.cpp
@@ -1336,6 +1336,7 @@ static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receive
if (call_type == JNI_VIRTUAL) {
// jni_GetMethodID makes sure class is linked and initialized
// so m should have a valid vtable index.
+ assert(!m->has_itable_index(), "");
int vtbl_index = m->vtable_index();
if (vtbl_index != Method::nonvirtual_vtable_index) {
Klass* k = h_recv->klass();
@@ -1355,12 +1356,7 @@ static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receive
// interface call
KlassHandle h_holder(THREAD, holder);
- int itbl_index = m->cached_itable_index();
- if (itbl_index == -1) {
- itbl_index = klassItable::compute_itable_index(m);
- m->set_cached_itable_index(itbl_index);
- // the above may have grabbed a lock, 'm' and anything non-handlized can't be used again
- }
+ int itbl_index = m->itable_index();
Klass* k = h_recv->klass();
selected_method = InstanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK);
}
@@ -5037,6 +5033,7 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {
#include "gc_implementation/g1/heapRegionRemSet.hpp"
#endif
#include "utilities/quickSort.hpp"
+#include "utilities/ostream.hpp"
#if INCLUDE_VM_STRUCTS
#include "runtime/vmStructs.hpp"
#endif
@@ -5048,18 +5045,23 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {
// Forward declaration
void TestReservedSpace_test();
void TestReserveMemorySpecial_test();
+void TestVirtualSpace_test();
+void MetaspaceAux_test();
void execute_internal_vm_tests() {
if (ExecuteInternalVMTests) {
tty->print_cr("Running internal VM tests");
run_unit_test(TestReservedSpace_test());
run_unit_test(TestReserveMemorySpecial_test());
+ run_unit_test(TestVirtualSpace_test());
+ run_unit_test(MetaspaceAux_test());
run_unit_test(GlobalDefinitions::test_globals());
run_unit_test(GCTimerAllTest::all());
run_unit_test(arrayOopDesc::test_max_array_length());
run_unit_test(CollectedHeap::test_is_in());
run_unit_test(QuickSort::test_quick_sort());
run_unit_test(AltHashing::test_alt_hash());
+ run_unit_test(test_loggc_filename());
#if INCLUDE_VM_STRUCTS
run_unit_test(VMStructs::test());
#endif
diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp
index caed2d13612..d7a961edfbb 100644
--- a/hotspot/src/share/vm/prims/jvm.cpp
+++ b/hotspot/src/share/vm/prims/jvm.cpp
@@ -1824,7 +1824,7 @@ JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass,
}
if (!publicOnly || fs.access_flags().is_public()) {
- fd.initialize(k(), fs.index());
+ fd.reinitialize(k(), fs.index());
oop field = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL);
result->obj_at_put(out_idx, field);
++out_idx;
diff --git a/hotspot/src/share/vm/prims/jvmti.xml b/hotspot/src/share/vm/prims/jvmti.xml
index 87a28ae0cfc..98a0a0640aa 100644
--- a/hotspot/src/share/vm/prims/jvmti.xml
+++ b/hotspot/src/share/vm/prims/jvmti.xml
@@ -458,8 +458,10 @@
the same name from being loaded dynamically.
The VM will invoke the Agent_OnUnload_L function of the agent, if such
- a function is exported, at the same point during startup as it would
- have called the dynamic entry point Agent_OnUnLoad.
+ a function is exported, at the same point during VM execution as it would
+ have called the dynamic entry point Agent_OnUnLoad. A statically loaded
+ agent cannot be unloaded. The Agent_OnUnload_L function will still be
+ called to do any other agent shutdown related tasks.
If a statically linked agent L exports a function called
Agent_OnUnLoad_L and a function called Agent_OnUnLoad, the Agent_OnUnLoad
function will be ignored.
diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
index 803cf9a7545..0e3bbc35c5b 100644
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
@@ -1072,8 +1072,17 @@ jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) {
}
res = merge_cp_and_rewrite(the_class, scratch_class, THREAD);
- if (res != JVMTI_ERROR_NONE) {
- return res;
+ if (HAS_PENDING_EXCEPTION) {
+ Symbol* ex_name = PENDING_EXCEPTION->klass()->name();
+ // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
+ RC_TRACE_WITH_THREAD(0x00000002, THREAD,
+ ("merge_cp_and_rewrite exception: '%s'", ex_name->as_C_string()));
+ CLEAR_PENDING_EXCEPTION;
+ if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
+ return JVMTI_ERROR_OUT_OF_MEMORY;
+ } else {
+ return JVMTI_ERROR_INTERNAL;
+ }
}
if (VerifyMergedCPBytecodes) {
@@ -1105,6 +1114,9 @@ jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) {
}
if (HAS_PENDING_EXCEPTION) {
Symbol* ex_name = PENDING_EXCEPTION->klass()->name();
+ // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
+ RC_TRACE_WITH_THREAD(0x00000002, THREAD,
+ ("Rewriter::rewrite or link_methods exception: '%s'", ex_name->as_C_string()));
CLEAR_PENDING_EXCEPTION;
if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
return JVMTI_ERROR_OUT_OF_MEMORY;
@@ -1395,8 +1407,8 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite(
ClassLoaderData* loader_data = the_class->class_loader_data();
ConstantPool* merge_cp_oop =
ConstantPool::allocate(loader_data,
- merge_cp_length,
- THREAD);
+ merge_cp_length,
+ CHECK_(JVMTI_ERROR_OUT_OF_MEMORY));
MergeCPCleaner cp_cleaner(loader_data, merge_cp_oop);
HandleMark hm(THREAD); // make sure handles are cleared before
@@ -1472,7 +1484,8 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite(
// Replace the new constant pool with a shrunken copy of the
// merged constant pool
- set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, THREAD);
+ set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length,
+ CHECK_(JVMTI_ERROR_OUT_OF_MEMORY));
// The new constant pool replaces scratch_cp so have cleaner clean it up.
// It can't be cleaned up while there are handles to it.
cp_cleaner.add_scratch_cp(scratch_cp());
@@ -1502,7 +1515,8 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite(
// merged constant pool so now the rewritten bytecodes have
// valid references; the previous new constant pool will get
// GCed.
- set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, THREAD);
+ set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length,
+ CHECK_(JVMTI_ERROR_OUT_OF_MEMORY));
// The new constant pool replaces scratch_cp so have cleaner clean it up.
// It can't be cleaned up while there are handles to it.
cp_cleaner.add_scratch_cp(scratch_cp());
@@ -1590,11 +1604,23 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_methods(
for (int i = methods->length() - 1; i >= 0; i--) {
methodHandle method(THREAD, methods->at(i));
methodHandle new_method;
- rewrite_cp_refs_in_method(method, &new_method, CHECK_false);
+ rewrite_cp_refs_in_method(method, &new_method, THREAD);
if (!new_method.is_null()) {
// the method has been replaced so save the new method version
+ // even in the case of an exception. original method is on the
+ // deallocation list.
methods->at_put(i, new_method());
}
+ if (HAS_PENDING_EXCEPTION) {
+ Symbol* ex_name = PENDING_EXCEPTION->klass()->name();
+ // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
+ RC_TRACE_WITH_THREAD(0x00000002, THREAD,
+ ("rewrite_cp_refs_in_method exception: '%s'", ex_name->as_C_string()));
+ // Need to clear pending exception here as the super caller sets
+ // the JVMTI_ERROR_INTERNAL if the returned value is false.
+ CLEAR_PENDING_EXCEPTION;
+ return false;
+ }
}
return true;
@@ -1674,10 +1700,7 @@ void VM_RedefineClasses::rewrite_cp_refs_in_method(methodHandle method,
Pause_No_Safepoint_Verifier pnsv(&nsv);
// ldc is 2 bytes and ldc_w is 3 bytes
- m = rc.insert_space_at(bci, 3, inst_buffer, THREAD);
- if (m.is_null() || HAS_PENDING_EXCEPTION) {
- guarantee(false, "insert_space_at() failed");
- }
+ m = rc.insert_space_at(bci, 3, inst_buffer, CHECK);
}
// return the new method so that the caller can update
@@ -2487,8 +2510,8 @@ void VM_RedefineClasses::set_new_constant_pool(
// scratch_cp is a merged constant pool and has enough space for a
// worst case merge situation. We want to associate the minimum
// sized constant pool with the klass to save space.
- constantPoolHandle smaller_cp(THREAD,
- ConstantPool::allocate(loader_data, scratch_cp_length, THREAD));
+ ConstantPool* cp = ConstantPool::allocate(loader_data, scratch_cp_length, CHECK);
+ constantPoolHandle smaller_cp(THREAD, cp);
// preserve version() value in the smaller copy
int version = scratch_cp->version();
@@ -2500,6 +2523,11 @@ void VM_RedefineClasses::set_new_constant_pool(
smaller_cp->set_pool_holder(scratch_class());
scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD);
+ if (HAS_PENDING_EXCEPTION) {
+ // Exception is handled in the caller
+ loader_data->add_to_deallocate_list(smaller_cp());
+ return;
+ }
scratch_cp = smaller_cp;
// attach new constant pool to klass
@@ -2930,7 +2958,7 @@ void VM_RedefineClasses::check_methods_and_mark_as_obsolete(
for (int i = 0; i < _deleted_methods_length; ++i) {
Method* old_method = _deleted_methods[i];
- assert(old_method->vtable_index() < 0,
+ assert(!old_method->has_vtable_index(),
"cannot delete methods with vtable entries");;
// Mark all deleted methods as old and obsolete
diff --git a/hotspot/src/share/vm/prims/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp
index ac1c796eb31..88b82b358e6 100644
--- a/hotspot/src/share/vm/prims/methodHandles.cpp
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp
@@ -127,25 +127,37 @@ Handle MethodHandles::new_MemberName(TRAPS) {
}
oop MethodHandles::init_MemberName(Handle mname, Handle target) {
+ // This method is used from java.lang.invoke.MemberName constructors.
+ // It fills in the new MemberName from a java.lang.reflect.Member.
Thread* thread = Thread::current();
oop target_oop = target();
Klass* target_klass = target_oop->klass();
if (target_klass == SystemDictionary::reflect_Field_klass()) {
oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
int slot = java_lang_reflect_Field::slot(target_oop); // fd.index()
- int mods = java_lang_reflect_Field::modifiers(target_oop);
- oop type = java_lang_reflect_Field::type(target_oop);
- oop name = java_lang_reflect_Field::name(target_oop);
KlassHandle k(thread, java_lang_Class::as_Klass(clazz));
- intptr_t offset = InstanceKlass::cast(k())->field_offset(slot);
- return init_field_MemberName(mname, k, accessFlags_from(mods), type, name, offset);
+ if (!k.is_null() && k->oop_is_instance()) {
+ fieldDescriptor fd(InstanceKlass::cast(k()), slot);
+ oop mname2 = init_field_MemberName(mname, fd);
+ if (mname2 != NULL) {
+ // Since we have the reified name and type handy, add them to the result.
+ if (java_lang_invoke_MemberName::name(mname2) == NULL)
+ java_lang_invoke_MemberName::set_name(mname2, java_lang_reflect_Field::name(target_oop));
+ if (java_lang_invoke_MemberName::type(mname2) == NULL)
+ java_lang_invoke_MemberName::set_type(mname2, java_lang_reflect_Field::type(target_oop));
+ }
+ return mname2;
+ }
} else if (target_klass == SystemDictionary::reflect_Method_klass()) {
oop clazz = java_lang_reflect_Method::clazz(target_oop);
int slot = java_lang_reflect_Method::slot(target_oop);
KlassHandle k(thread, java_lang_Class::as_Klass(clazz));
if (!k.is_null() && k->oop_is_instance()) {
Method* m = InstanceKlass::cast(k())->method_with_idnum(slot);
- return init_method_MemberName(mname, m, true, k);
+ if (m == NULL || is_signature_polymorphic(m->intrinsic_id()))
+ return NULL; // do not resolve unless there is a concrete signature
+ CallInfo info(m, k());
+ return init_method_MemberName(mname, info);
}
} else if (target_klass == SystemDictionary::reflect_Constructor_klass()) {
oop clazz = java_lang_reflect_Constructor::clazz(target_oop);
@@ -153,65 +165,50 @@ oop MethodHandles::init_MemberName(Handle mname, Handle target) {
KlassHandle k(thread, java_lang_Class::as_Klass(clazz));
if (!k.is_null() && k->oop_is_instance()) {
Method* m = InstanceKlass::cast(k())->method_with_idnum(slot);
- return init_method_MemberName(mname, m, false, k);
- }
- } else if (target_klass == SystemDictionary::MemberName_klass()) {
- // Note: This only works if the MemberName has already been resolved.
- oop clazz = java_lang_invoke_MemberName::clazz(target_oop);
- int flags = java_lang_invoke_MemberName::flags(target_oop);
- Metadata* vmtarget=java_lang_invoke_MemberName::vmtarget(target_oop);
- intptr_t vmindex = java_lang_invoke_MemberName::vmindex(target_oop);
- KlassHandle k(thread, java_lang_Class::as_Klass(clazz));
- int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
- if (vmtarget == NULL) return NULL; // not resolved
- if ((flags & IS_FIELD) != 0) {
- assert(vmtarget->is_klass(), "field vmtarget is Klass*");
- int basic_mods = (ref_kind_is_static(ref_kind) ? JVM_ACC_STATIC : 0);
- // FIXME: how does k (receiver_limit) contribute?
- KlassHandle k_vmtarget(thread, (Klass*)vmtarget);
- return init_field_MemberName(mname, k_vmtarget, accessFlags_from(basic_mods), NULL, NULL, vmindex);
- } else if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) {
- assert(vmtarget->is_method(), "method or constructor vmtarget is Method*");
- return init_method_MemberName(mname, (Method*)vmtarget, ref_kind_does_dispatch(ref_kind), k);
- } else {
- return NULL;
+ if (m == NULL) return NULL;
+ CallInfo info(m, k());
+ return init_method_MemberName(mname, info);
}
}
return NULL;
}
-oop MethodHandles::init_method_MemberName(Handle mname, Method* m, bool do_dispatch,
- KlassHandle receiver_limit_h) {
- Klass* receiver_limit = receiver_limit_h();
- AccessFlags mods = m->access_flags();
- int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS );
- int vmindex = Method::nonvirtual_vtable_index; // implies never any dispatch
- Klass* mklass = m->method_holder();
- if (receiver_limit == NULL)
- receiver_limit = mklass;
- if (m->is_initializer()) {
- flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
- } else if (mods.is_static()) {
- flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT);
- } else if (receiver_limit != mklass &&
- !receiver_limit->is_subtype_of(mklass)) {
- return NULL; // bad receiver limit
- } else if (do_dispatch && receiver_limit->is_interface() &&
- mklass->is_interface()) {
+oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
+ assert(info.resolved_appendix().is_null(), "only normal methods here");
+ KlassHandle receiver_limit = info.resolved_klass();
+ methodHandle m = info.resolved_method();
+ int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS );
+ int vmindex = Method::invalid_vtable_index;
+
+ switch (info.call_kind()) {
+ case CallInfo::itable_call:
+ vmindex = info.itable_index();
+ // More importantly, the itable index only works with the method holder.
+ receiver_limit = m->method_holder();
+ assert(receiver_limit->verify_itable_index(vmindex), "");
flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT);
- receiver_limit = mklass; // ignore passed-in limit; interfaces are interconvertible
- vmindex = klassItable::compute_itable_index(m);
- } else if (do_dispatch && mklass != receiver_limit && mklass->is_interface()) {
+ break;
+
+ case CallInfo::vtable_call:
+ vmindex = info.vtable_index();
flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
- // it is a miranda method, so m->vtable_index is not what we want
- ResourceMark rm;
- klassVtable* vt = InstanceKlass::cast(receiver_limit)->vtable();
- vmindex = vt->index_of_miranda(m->name(), m->signature());
- } else if (!do_dispatch || m->can_be_statically_bound()) {
- flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
- } else {
- flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
- vmindex = m->vtable_index();
+ assert(receiver_limit->is_subtype_of(m->method_holder()), "virtual call must be type-safe");
+ break;
+
+ case CallInfo::direct_call:
+ vmindex = Method::nonvirtual_vtable_index;
+ if (m->is_static()) {
+ flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT);
+ } else if (m->is_initializer()) {
+ flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
+ assert(receiver_limit == m->method_holder(), "constructor call must be exactly typed");
+ } else {
+ flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
+ assert(receiver_limit->is_subtype_of(m->method_holder()), "special call must be type-safe");
+ }
+ break;
+
+ default: assert(false, "bad CallInfo"); return NULL;
}
// @CallerSensitive annotation detected
@@ -221,7 +218,7 @@ oop MethodHandles::init_method_MemberName(Handle mname, Method* m, bool do_dispa
oop mname_oop = mname();
java_lang_invoke_MemberName::set_flags( mname_oop, flags);
- java_lang_invoke_MemberName::set_vmtarget(mname_oop, m);
+ java_lang_invoke_MemberName::set_vmtarget(mname_oop, m());
java_lang_invoke_MemberName::set_vmindex( mname_oop, vmindex); // vtable/itable index
java_lang_invoke_MemberName::set_clazz( mname_oop, receiver_limit->java_mirror());
// Note: name and type can be lazily computed by resolve_MemberName,
@@ -237,59 +234,19 @@ oop MethodHandles::init_method_MemberName(Handle mname, Method* m, bool do_dispa
return mname();
}
-Handle MethodHandles::init_method_MemberName(Handle mname, CallInfo& info, TRAPS) {
- Handle empty;
- if (info.resolved_appendix().not_null()) {
- // The resolved MemberName must not be accompanied by an appendix argument,
- // since there is no way to bind this value into the MemberName.
- // Caller is responsible to prevent this from happening.
- THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty);
- }
- methodHandle m = info.resolved_method();
- KlassHandle defc = info.resolved_klass();
- int vmindex = Method::invalid_vtable_index;
- if (defc->is_interface() && m->method_holder()->is_interface()) {
- // static interface methods do not reference vtable or itable
- if (m->is_static()) {
- vmindex = Method::nonvirtual_vtable_index;
- }
- // interface methods invoked via invokespecial also
- // do not reference vtable or itable.
- int ref_kind = ((java_lang_invoke_MemberName::flags(mname()) >>
- REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK);
- if (ref_kind == JVM_REF_invokeSpecial) {
- vmindex = Method::nonvirtual_vtable_index;
- }
- // If neither m is static nor ref_kind is invokespecial,
- // set it to itable index.
- if (vmindex == Method::invalid_vtable_index) {
- // LinkResolver does not report itable indexes! (fix this?)
- vmindex = klassItable::compute_itable_index(m());
- }
- } else if (m->can_be_statically_bound()) {
- // LinkResolver reports vtable index even for final methods!
- vmindex = Method::nonvirtual_vtable_index;
- } else {
- vmindex = info.vtable_index();
- }
- oop res = init_method_MemberName(mname, m(), (vmindex >= 0), defc());
- assert(res == NULL || (java_lang_invoke_MemberName::vmindex(res) == vmindex), "");
- return Handle(THREAD, res);
-}
-
-oop MethodHandles::init_field_MemberName(Handle mname, KlassHandle field_holder,
- AccessFlags mods, oop type, oop name,
- intptr_t offset, bool is_setter) {
- int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS );
- flags |= IS_FIELD | ((mods.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT);
+oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) {
+ int flags = (jushort)( fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS );
+ flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT);
if (is_setter) flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT);
- Metadata* vmtarget = field_holder();
- int vmindex = offset; // determines the field uniquely when combined with static bit
+ Metadata* vmtarget = fd.field_holder();
+ int vmindex = fd.offset(); // determines the field uniquely when combined with static bit
oop mname_oop = mname();
java_lang_invoke_MemberName::set_flags(mname_oop, flags);
java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget);
java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex);
- java_lang_invoke_MemberName::set_clazz(mname_oop, field_holder->java_mirror());
+ java_lang_invoke_MemberName::set_clazz(mname_oop, fd.field_holder()->java_mirror());
+ oop type = field_signature_type_or_null(fd.signature());
+ oop name = field_name_or_null(fd.name());
if (name != NULL)
java_lang_invoke_MemberName::set_name(mname_oop, name);
if (type != NULL)
@@ -305,19 +262,6 @@ oop MethodHandles::init_field_MemberName(Handle mname, KlassHandle field_holder,
return mname();
}
-Handle MethodHandles::init_field_MemberName(Handle mname, FieldAccessInfo& info, TRAPS) {
- return Handle();
-#if 0 // FIXME
- KlassHandle field_holder = info.klass();
- intptr_t field_offset = info.field_offset();
- return init_field_MemberName(mname_oop, field_holder(),
- info.access_flags(),
- type, name,
- field_offset, false /*is_setter*/);
-#endif
-}
-
-
// JVM 2.9 Special Methods:
// A method is signature polymorphic if and only if all of the following conditions hold :
// * It is declared in the java.lang.invoke.MethodHandle class.
@@ -573,12 +517,12 @@ static oop object_java_mirror() {
return SystemDictionary::Object_klass()->java_mirror();
}
-static oop field_name_or_null(Symbol* s) {
+oop MethodHandles::field_name_or_null(Symbol* s) {
if (s == NULL) return NULL;
return StringTable::lookup(s);
}
-static oop field_signature_type_or_null(Symbol* s) {
+oop MethodHandles::field_signature_type_or_null(Symbol* s) {
if (s == NULL) return NULL;
BasicType bt = FieldType::basic_type(s);
if (is_java_primitive(bt)) {
@@ -701,7 +645,14 @@ Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
return empty;
}
}
- return init_method_MemberName(mname, result, THREAD);
+ if (result.resolved_appendix().not_null()) {
+ // The resolved MemberName must not be accompanied by an appendix argument,
+ // since there is no way to bind this value into the MemberName.
+ // Caller is responsible to prevent this from happening.
+ THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty);
+ }
+ oop mname2 = init_method_MemberName(mname, result);
+ return Handle(THREAD, mname2);
}
case IS_CONSTRUCTOR:
{
@@ -719,22 +670,21 @@ Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
}
}
assert(result.is_statically_bound(), "");
- return init_method_MemberName(mname, result, THREAD);
+ oop mname2 = init_method_MemberName(mname, result);
+ return Handle(THREAD, mname2);
}
case IS_FIELD:
{
- // This is taken from LinkResolver::resolve_field, sans access checks.
- fieldDescriptor fd; // find_field initializes fd if found
- KlassHandle sel_klass(THREAD, InstanceKlass::cast(defc())->find_field(name, type, &fd));
- // check if field exists; i.e., if a klass containing the field def has been selected
- if (sel_klass.is_null()) return empty; // should not happen
- oop type = field_signature_type_or_null(fd.signature());
- oop name = field_name_or_null(fd.name());
- bool is_setter = (ref_kind_is_valid(ref_kind) && ref_kind_is_setter(ref_kind));
- mname = Handle(THREAD,
- init_field_MemberName(mname, sel_klass,
- fd.access_flags(), type, name, fd.offset(), is_setter));
- return mname;
+ fieldDescriptor result; // find_field initializes fd if found
+ {
+ assert(!HAS_PENDING_EXCEPTION, "");
+ LinkResolver::resolve_field(result, defc, name, type, KlassHandle(), Bytecodes::_nop, false, false, THREAD);
+ if (HAS_PENDING_EXCEPTION) {
+ return empty;
+ }
+ }
+ oop mname2 = init_field_MemberName(mname, result, ref_kind_is_setter(ref_kind));
+ return Handle(THREAD, mname2);
}
default:
THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format", empty);
@@ -793,7 +743,6 @@ void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) {
}
case IS_FIELD:
{
- // This is taken from LinkResolver::resolve_field, sans access checks.
assert(vmtarget->is_klass(), "field vmtarget is Klass*");
if (!((Klass*) vmtarget)->oop_is_instance()) break;
instanceKlassHandle defc(THREAD, (Klass*) vmtarget);
@@ -872,11 +821,7 @@ int MethodHandles::find_MemberNames(KlassHandle k,
Handle result(thread, results->obj_at(rfill++));
if (!java_lang_invoke_MemberName::is_instance(result()))
return -99; // caller bug!
- oop type = field_signature_type_or_null(st.signature());
- oop name = field_name_or_null(st.name());
- oop saved = MethodHandles::init_field_MemberName(result, st.klass(),
- st.access_flags(), type, name,
- st.offset());
+ oop saved = MethodHandles::init_field_MemberName(result, st.field_descriptor());
if (saved != result())
results->obj_at_put(rfill-1, saved); // show saved instance to user
} else if (++overflow >= overflow_limit) {
@@ -926,7 +871,8 @@ int MethodHandles::find_MemberNames(KlassHandle k,
Handle result(thread, results->obj_at(rfill++));
if (!java_lang_invoke_MemberName::is_instance(result()))
return -99; // caller bug!
- oop saved = MethodHandles::init_method_MemberName(result, m, true, NULL);
+ CallInfo info(m);
+ oop saved = MethodHandles::init_method_MemberName(result, info);
if (saved != result())
results->obj_at_put(rfill-1, saved); // show saved instance to user
} else if (++overflow >= overflow_limit) {
@@ -1227,7 +1173,8 @@ JVM_ENTRY(jobject, MHN_getMemberVMInfo(JNIEnv *env, jobject igcls, jobject mname
x = ((Klass*) vmtarget)->java_mirror();
} else if (vmtarget->is_method()) {
Handle mname2 = MethodHandles::new_MemberName(CHECK_NULL);
- x = MethodHandles::init_method_MemberName(mname2, (Method*)vmtarget, false, NULL);
+ CallInfo info((Method*)vmtarget);
+ x = MethodHandles::init_method_MemberName(mname2, info);
}
result->obj_at_put(1, x);
return JNIHandles::make_local(env, result());
diff --git a/hotspot/src/share/vm/prims/methodHandles.hpp b/hotspot/src/share/vm/prims/methodHandles.hpp
index 50ce7af86ea..7ae7bd36fb5 100644
--- a/hotspot/src/share/vm/prims/methodHandles.hpp
+++ b/hotspot/src/share/vm/prims/methodHandles.hpp
@@ -49,19 +49,18 @@ class MethodHandles: AllStatic {
// Adapters.
static MethodHandlesAdapterBlob* _adapter_code;
+ // utility functions for reifying names and types
+ static oop field_name_or_null(Symbol* s);
+ static oop field_signature_type_or_null(Symbol* s);
+
public:
// working with member names
static Handle resolve_MemberName(Handle mname, TRAPS); // compute vmtarget/vmindex from name/type
static void expand_MemberName(Handle mname, int suppress, TRAPS); // expand defc/name/type if missing
static Handle new_MemberName(TRAPS); // must be followed by init_MemberName
static oop init_MemberName(Handle mname_h, Handle target_h); // compute vmtarget/vmindex from target
- static oop init_method_MemberName(Handle mname_h, Method* m, bool do_dispatch,
- KlassHandle receiver_limit_h);
- static oop init_field_MemberName(Handle mname_h, KlassHandle field_holder_h,
- AccessFlags mods, oop type, oop name,
- intptr_t offset, bool is_setter = false);
- static Handle init_method_MemberName(Handle mname_h, CallInfo& info, TRAPS);
- static Handle init_field_MemberName(Handle mname_h, FieldAccessInfo& info, TRAPS);
+ static oop init_field_MemberName(Handle mname_h, fieldDescriptor& fd, bool is_setter = false);
+ static oop init_method_MemberName(Handle mname_h, CallInfo& info);
static int method_ref_kind(Method* m, bool do_dispatch_if_possible = true);
static int find_MemberNames(KlassHandle k, Symbol* name, Symbol* sig,
int mflags, KlassHandle caller,
diff --git a/hotspot/src/share/vm/prims/whitebox.cpp b/hotspot/src/share/vm/prims/whitebox.cpp
index 0f5607e22b2..6f6a2000a3f 100644
--- a/hotspot/src/share/vm/prims/whitebox.cpp
+++ b/hotspot/src/share/vm/prims/whitebox.cpp
@@ -33,6 +33,7 @@
#include "prims/whitebox.hpp"
#include "prims/wbtestmethods/parserTests.hpp"
+#include "runtime/arguments.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/os.hpp"
#include "utilities/debug.hpp"
@@ -94,6 +95,11 @@ WB_ENTRY(jboolean, WB_IsClassAlive(JNIEnv* env, jobject target, jstring name))
return closure.found();
WB_END
+WB_ENTRY(jlong, WB_GetCompressedOopsMaxHeapSize(JNIEnv* env, jobject o)) {
+ return (jlong)Arguments::max_heap_for_compressed_oops();
+}
+WB_END
+
WB_ENTRY(void, WB_PrintHeapSizes(JNIEnv* env, jobject o)) {
CollectorPolicy * p = Universe::heap()->collector_policy();
gclog_or_tty->print_cr("Minimum heap "SIZE_FORMAT" Initial heap "
@@ -436,6 +442,8 @@ static JNINativeMethod methods[] = {
CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
(void*) &WB_ParseCommandLine
},
+ {CC"getCompressedOopsMaxHeapSize", CC"()J",
+ (void*)&WB_GetCompressedOopsMaxHeapSize},
{CC"printHeapSizes", CC"()V", (void*)&WB_PrintHeapSizes },
#if INCLUDE_ALL_GCS
{CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark},
diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
index d8a6f90eeef..93b31f1859a 100644
--- a/hotspot/src/share/vm/runtime/arguments.cpp
+++ b/hotspot/src/share/vm/runtime/arguments.cpp
@@ -28,6 +28,7 @@
#include "compiler/compilerOracle.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/cardTableRS.hpp"
+#include "memory/genCollectedHeap.hpp"
#include "memory/referenceProcessor.hpp"
#include "memory/universe.inline.hpp"
#include "oops/oop.inline.hpp"
@@ -54,6 +55,8 @@
#endif
#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
+#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
#endif // INCLUDE_ALL_GCS
// Note: This is a special bug reporting site for the JVM
@@ -90,6 +93,7 @@ char* Arguments::_java_command = NULL;
SystemProperty* Arguments::_system_properties = NULL;
const char* Arguments::_gc_log_filename = NULL;
bool Arguments::_has_profile = false;
+size_t Arguments::_conservative_max_heap_alignment = 0;
uintx Arguments::_min_heap_size = 0;
Arguments::Mode Arguments::_mode = _mixed;
bool Arguments::_java_compiler = false;
@@ -1391,10 +1395,17 @@ bool verify_object_alignment() {
return true;
}
-inline uintx max_heap_for_compressed_oops() {
+uintx Arguments::max_heap_for_compressed_oops() {
// Avoid sign flip.
assert(OopEncodingHeapMax > (uint64_t)os::vm_page_size(), "Unusual page size");
- LP64_ONLY(return OopEncodingHeapMax - os::vm_page_size());
+ // We need to fit both the NULL page and the heap into the memory budget, while
+ // keeping alignment constraints of the heap. To guarantee the latter, as the
+ // NULL page is located before the heap, we pad the NULL page to the conservative
+ // maximum alignment that the GC may ever impose upon the heap.
+ size_t displacement_due_to_null_page = align_size_up_(os::vm_page_size(),
+ Arguments::conservative_max_heap_alignment());
+
+ LP64_ONLY(return OopEncodingHeapMax - displacement_due_to_null_page);
NOT_LP64(ShouldNotReachHere(); return 0);
}
@@ -1439,7 +1450,7 @@ void Arguments::set_use_compressed_oops() {
if (UseCompressedOops && !FLAG_IS_DEFAULT(UseCompressedOops)) {
warning("Max heap size too large for Compressed Oops");
FLAG_SET_DEFAULT(UseCompressedOops, false);
- FLAG_SET_DEFAULT(UseCompressedKlassPointers, false);
+ FLAG_SET_DEFAULT(UseCompressedClassPointers, false);
}
}
#endif // _LP64
@@ -1452,22 +1463,22 @@ void Arguments::set_use_compressed_oops() {
void Arguments::set_use_compressed_klass_ptrs() {
#ifndef ZERO
#ifdef _LP64
- // UseCompressedOops must be on for UseCompressedKlassPointers to be on.
+ // UseCompressedOops must be on for UseCompressedClassPointers to be on.
if (!UseCompressedOops) {
- if (UseCompressedKlassPointers) {
- warning("UseCompressedKlassPointers requires UseCompressedOops");
+ if (UseCompressedClassPointers) {
+ warning("UseCompressedClassPointers requires UseCompressedOops");
}
- FLAG_SET_DEFAULT(UseCompressedKlassPointers, false);
+ FLAG_SET_DEFAULT(UseCompressedClassPointers, false);
} else {
- // Turn on UseCompressedKlassPointers too
- if (FLAG_IS_DEFAULT(UseCompressedKlassPointers)) {
- FLAG_SET_ERGO(bool, UseCompressedKlassPointers, true);
+ // Turn on UseCompressedClassPointers too
+ if (FLAG_IS_DEFAULT(UseCompressedClassPointers)) {
+ FLAG_SET_ERGO(bool, UseCompressedClassPointers, true);
}
- // Check the ClassMetaspaceSize to make sure we use compressed klass ptrs.
- if (UseCompressedKlassPointers) {
- if (ClassMetaspaceSize > KlassEncodingMetaspaceMax) {
- warning("Class metaspace size is too large for UseCompressedKlassPointers");
- FLAG_SET_DEFAULT(UseCompressedKlassPointers, false);
+ // Check the CompressedClassSpaceSize to make sure we use compressed klass ptrs.
+ if (UseCompressedClassPointers) {
+ if (CompressedClassSpaceSize > KlassEncodingMetaspaceMax) {
+ warning("CompressedClassSpaceSize is too large for UseCompressedClassPointers");
+ FLAG_SET_DEFAULT(UseCompressedClassPointers, false);
}
}
}
@@ -1475,6 +1486,23 @@ void Arguments::set_use_compressed_klass_ptrs() {
#endif // !ZERO
}
+void Arguments::set_conservative_max_heap_alignment() {
+ // The conservative maximum required alignment for the heap is the maximum of
+ // the alignments imposed by several sources: any requirements from the heap
+ // itself, the collector policy and the maximum page size we may run the VM
+ // with.
+ size_t heap_alignment = GenCollectedHeap::conservative_max_heap_alignment();
+#if INCLUDE_ALL_GCS
+ if (UseParallelGC) {
+ heap_alignment = ParallelScavengeHeap::conservative_max_heap_alignment();
+ } else if (UseG1GC) {
+ heap_alignment = G1CollectedHeap::conservative_max_heap_alignment();
+ }
+#endif // INCLUDE_ALL_GCS
+ _conservative_max_heap_alignment = MAX3(heap_alignment, os::max_page_size(),
+ CollectorPolicy::compute_max_alignment());
+}
+
void Arguments::set_ergonomics_flags() {
if (os::is_server_class_machine()) {
@@ -1503,6 +1531,8 @@ void Arguments::set_ergonomics_flags() {
}
}
+ set_conservative_max_heap_alignment();
+
#ifndef ZERO
#ifdef _LP64
set_use_compressed_oops();
@@ -1839,7 +1869,7 @@ void check_gclog_consistency() {
(NumberOfGCLogFiles == 0) ||
(GCLogFileSize == 0)) {
jio_fprintf(defaultStream::output_stream(),
- "To enable GC log rotation, use -Xloggc: -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles= -XX:GCLogFileSize=\n"
+ "To enable GC log rotation, use -Xloggc: -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles= -XX:GCLogFileSize=[k|K|m|M|g|G]\n"
"where num_of_file > 0 and num_of_size > 0\n"
"GC log rotation is turned off\n");
UseGCLogFileRotation = false;
@@ -1853,6 +1883,51 @@ void check_gclog_consistency() {
}
}
+// This function is called for -Xloggc:, it can be used
+// to check if a given file name(or string) conforms to the following
+// specification:
+// A valid string only contains "[A-Z][a-z][0-9].-_%[p|t]"
+// %p and %t only allowed once. We only limit usage of filename not path
+bool is_filename_valid(const char *file_name) {
+ const char* p = file_name;
+ char file_sep = os::file_separator()[0];
+ const char* cp;
+ // skip prefix path
+ for (cp = file_name; *cp != '\0'; cp++) {
+ if (*cp == '/' || *cp == file_sep) {
+ p = cp + 1;
+ }
+ }
+
+ int count_p = 0;
+ int count_t = 0;
+ while (*p != '\0') {
+ if ((*p >= '0' && *p <= '9') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= 'a' && *p <= 'z') ||
+ *p == '-' ||
+ *p == '_' ||
+ *p == '.') {
+ p++;
+ continue;
+ }
+ if (*p == '%') {
+ if(*(p + 1) == 'p') {
+ p += 2;
+ count_p ++;
+ continue;
+ }
+ if (*(p + 1) == 't') {
+ p += 2;
+ count_t ++;
+ continue;
+ }
+ }
+ return false;
+ }
+ return count_p < 2 && count_t < 2;
+}
+
// Check consistency of GC selection
bool Arguments::check_gc_consistency() {
check_gclog_consistency();
@@ -2148,8 +2223,8 @@ bool Arguments::check_vm_args_consistency() {
status = status && verify_object_alignment();
- status = status && verify_interval(ClassMetaspaceSize, 1*M, 3*G,
- "ClassMetaspaceSize");
+ status = status && verify_interval(CompressedClassSpaceSize, 1*M, 3*G,
+ "CompressedClassSpaceSize");
status = status && verify_interval(MarkStackSizeMax,
1, (max_jint - 1), "MarkStackSizeMax");
@@ -2806,6 +2881,13 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
// ostream_init_log(), when called will use this filename
// to initialize a fileStream.
_gc_log_filename = strdup(tail);
+ if (!is_filename_valid(_gc_log_filename)) {
+ jio_fprintf(defaultStream::output_stream(),
+ "Invalid file name for use with -Xloggc: Filename can only contain the "
+ "characters [A-Z][a-z][0-9]-_.%%[p|t] but it has been %s\n"
+ "Note %%p or %%t can only be used once\n", _gc_log_filename);
+ return JNI_EINVAL;
+ }
FLAG_SET_CMDLINE(bool, PrintGC, true);
FLAG_SET_CMDLINE(bool, PrintGCTimeStamps, true);
@@ -3274,13 +3356,13 @@ void Arguments::set_shared_spaces_flags() {
}
UseSharedSpaces = false;
#ifdef _LP64
- if (!UseCompressedOops || !UseCompressedKlassPointers) {
+ if (!UseCompressedOops || !UseCompressedClassPointers) {
vm_exit_during_initialization(
- "Cannot dump shared archive when UseCompressedOops or UseCompressedKlassPointers is off.", NULL);
+ "Cannot dump shared archive when UseCompressedOops or UseCompressedClassPointers is off.", NULL);
}
} else {
- // UseCompressedOops and UseCompressedKlassPointers must be on for UseSharedSpaces.
- if (!UseCompressedOops || !UseCompressedKlassPointers) {
+ // UseCompressedOops and UseCompressedClassPointers must be on for UseSharedSpaces.
+ if (!UseCompressedOops || !UseCompressedClassPointers) {
no_shared_spaces();
}
#endif
@@ -3326,6 +3408,33 @@ static char* get_shared_archive_path() {
return shared_archive_path;
}
+#ifndef PRODUCT
+// Determine whether LogVMOutput should be implicitly turned on.
+static bool use_vm_log() {
+ if (LogCompilation || !FLAG_IS_DEFAULT(LogFile) ||
+ PrintCompilation || PrintInlining || PrintDependencies || PrintNativeNMethods ||
+ PrintDebugInfo || PrintRelocations || PrintNMethods || PrintExceptionHandlers ||
+ PrintAssembly || TraceDeoptimization || TraceDependencies ||
+ (VerifyDependencies && FLAG_IS_CMDLINE(VerifyDependencies))) {
+ return true;
+ }
+
+#ifdef COMPILER1
+ if (PrintC1Statistics) {
+ return true;
+ }
+#endif // COMPILER1
+
+#ifdef COMPILER2
+ if (PrintOptoAssembly || PrintOptoStatistics) {
+ return true;
+ }
+#endif // COMPILER2
+
+ return false;
+}
+#endif // PRODUCT
+
// Parse entry point called from JNI_CreateJavaVM
jint Arguments::parse(const JavaVMInitArgs* args) {
@@ -3506,6 +3615,11 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
no_shared_spaces();
#endif // INCLUDE_CDS
+ return JNI_OK;
+}
+
+jint Arguments::apply_ergo() {
+
// Set flags based on ergonomics.
set_ergonomics_flags();
@@ -3581,7 +3695,7 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
FLAG_SET_DEFAULT(ProfileInterpreter, false);
FLAG_SET_DEFAULT(UseBiasedLocking, false);
LP64_ONLY(FLAG_SET_DEFAULT(UseCompressedOops, false));
- LP64_ONLY(FLAG_SET_DEFAULT(UseCompressedKlassPointers, false));
+ LP64_ONLY(FLAG_SET_DEFAULT(UseCompressedClassPointers, false));
#endif // CC_INTERP
#ifdef COMPILER2
@@ -3610,6 +3724,10 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
DebugNonSafepoints = true;
}
+ if (FLAG_IS_CMDLINE(CompressedClassSpaceSize) && !UseCompressedClassPointers) {
+ warning("Setting CompressedClassSpaceSize has no effect when compressed class pointers are not used");
+ }
+
#ifndef PRODUCT
if (CompileTheWorld) {
// Force NmethodSweeper to sweep whole CodeCache each time.
@@ -3617,7 +3735,13 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
NmethodSweepFraction = 1;
}
}
-#endif
+
+ if (!LogVMOutput && FLAG_IS_DEFAULT(LogVMOutput)) {
+ if (use_vm_log()) {
+ LogVMOutput = true;
+ }
+ }
+#endif // PRODUCT
if (PrintCommandLineFlags) {
CommandLineFlags::printSetFlags(tty);
diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp
index 43256b75082..4b2a821a5a3 100644
--- a/hotspot/src/share/vm/runtime/arguments.hpp
+++ b/hotspot/src/share/vm/runtime/arguments.hpp
@@ -144,7 +144,7 @@ public:
void set_os_lib(void* os_lib) { _os_lib = os_lib; }
AgentLibrary* next() const { return _next; }
bool is_static_lib() const { return _is_static_lib; }
- void set_static_lib(bool static_lib) { _is_static_lib = static_lib; }
+ void set_static_lib(bool is_static_lib) { _is_static_lib = is_static_lib; }
bool valid() { return (_state == agent_valid); }
void set_valid() { _state = agent_valid; }
void set_invalid() { _state = agent_invalid; }
@@ -280,6 +280,9 @@ class Arguments : AllStatic {
// Option flags
static bool _has_profile;
static const char* _gc_log_filename;
+ // Value of the conservative maximum heap alignment needed
+ static size_t _conservative_max_heap_alignment;
+
static uintx _min_heap_size;
// -Xrun arguments
@@ -327,6 +330,7 @@ class Arguments : AllStatic {
// Garbage-First (UseG1GC)
static void set_g1_gc_flags();
// GC ergonomics
+ static void set_conservative_max_heap_alignment();
static void set_use_compressed_oops();
static void set_use_compressed_klass_ptrs();
static void set_ergonomics_flags();
@@ -430,8 +434,10 @@ class Arguments : AllStatic {
static char* SharedArchivePath;
public:
- // Parses the arguments
+ // Parses the arguments, first phase
static jint parse(const JavaVMInitArgs* args);
+ // Apply ergonomics
+ static jint apply_ergo();
// Adjusts the arguments after the OS have adjusted the arguments
static jint adjust_after_os();
// Check for consistency in the selection of the garbage collector.
@@ -445,6 +451,10 @@ class Arguments : AllStatic {
// Used by os_solaris
static bool process_settings_file(const char* file_name, bool should_exist, jboolean ignore_unrecognized);
+ static size_t conservative_max_heap_alignment() { return _conservative_max_heap_alignment; }
+ // Return the maximum size a heap with compressed oops can take
+ static size_t max_heap_for_compressed_oops();
+
// return a char* array containing all options
static char** jvm_flags_array() { return _jvm_flags_array; }
static char** jvm_args_array() { return _jvm_args_array; }
diff --git a/hotspot/src/share/vm/runtime/deoptimization.cpp b/hotspot/src/share/vm/runtime/deoptimization.cpp
index 7f71c2d8b76..007bfe7aa13 100644
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp
@@ -1751,7 +1751,7 @@ int Deoptimization::trap_state_set_recompiled(int trap_state, bool z) {
else return trap_state & ~DS_RECOMPILE_BIT;
}
//---------------------------format_trap_state---------------------------------
-// This is used for debugging and diagnostics, including hotspot.log output.
+// This is used for debugging and diagnostics, including LogFile output.
const char* Deoptimization::format_trap_state(char* buf, size_t buflen,
int trap_state) {
DeoptReason reason = trap_state_reason(trap_state);
@@ -1828,7 +1828,7 @@ const char* Deoptimization::trap_action_name(int action) {
return buf;
}
-// This is used for debugging and diagnostics, including hotspot.log output.
+// This is used for debugging and diagnostics, including LogFile output.
const char* Deoptimization::format_trap_request(char* buf, size_t buflen,
int trap_request) {
jint unloaded_class_index = trap_request_index(trap_request);
diff --git a/hotspot/src/share/vm/runtime/fieldDescriptor.cpp b/hotspot/src/share/vm/runtime/fieldDescriptor.cpp
index 23d679494ac..79e3ddcd85d 100644
--- a/hotspot/src/share/vm/runtime/fieldDescriptor.cpp
+++ b/hotspot/src/share/vm/runtime/fieldDescriptor.cpp
@@ -97,18 +97,32 @@ oop fieldDescriptor::string_initial_value(TRAPS) const {
return constants()->uncached_string_at(initial_value_index(), CHECK_0);
}
-void fieldDescriptor::initialize(InstanceKlass* ik, int index) {
- _cp = ik->constants();
+void fieldDescriptor::reinitialize(InstanceKlass* ik, int index) {
+ if (_cp.is_null() || field_holder() != ik) {
+ _cp = constantPoolHandle(Thread::current(), ik->constants());
+ // _cp should now reference ik's constant pool; i.e., ik is now field_holder.
+ assert(field_holder() == ik, "must be already initialized to this class");
+ }
FieldInfo* f = ik->field(index);
assert(!f->is_internal(), "regular Java fields only");
_access_flags = accessFlags_from(f->access_flags());
guarantee(f->name_index() != 0 && f->signature_index() != 0, "bad constant pool index for fieldDescriptor");
_index = index;
+ verify();
}
#ifndef PRODUCT
+void fieldDescriptor::verify() const {
+ if (_cp.is_null()) {
+ assert(_index == badInt, "constructor must be called"); // see constructor
+ } else {
+ assert(_index >= 0, "good index");
+ assert(_index < field_holder()->java_fields_count(), "oob");
+ }
+}
+
void fieldDescriptor::print_on(outputStream* st) const {
access_flags().print_on(st);
name()->print_value_on(st);
diff --git a/hotspot/src/share/vm/runtime/fieldDescriptor.hpp b/hotspot/src/share/vm/runtime/fieldDescriptor.hpp
index 12b75cab144..9c3101b38ba 100644
--- a/hotspot/src/share/vm/runtime/fieldDescriptor.hpp
+++ b/hotspot/src/share/vm/runtime/fieldDescriptor.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -53,6 +53,13 @@ class fieldDescriptor VALUE_OBJ_CLASS_SPEC {
}
public:
+ fieldDescriptor() {
+ DEBUG_ONLY(_index = badInt);
+ }
+ fieldDescriptor(InstanceKlass* ik, int index) {
+ DEBUG_ONLY(_index = badInt);
+ reinitialize(ik, index);
+ }
Symbol* name() const {
return field()->name(_cp);
}
@@ -112,12 +119,13 @@ class fieldDescriptor VALUE_OBJ_CLASS_SPEC {
}
// Initialization
- void initialize(InstanceKlass* ik, int index);
+ void reinitialize(InstanceKlass* ik, int index);
// Print
void print() { print_on(tty); }
void print_on(outputStream* st) const PRODUCT_RETURN;
void print_on_for(outputStream* st, oop obj) PRODUCT_RETURN;
+ void verify() const PRODUCT_RETURN;
};
#endif // SHARE_VM_RUNTIME_FIELDDESCRIPTOR_HPP
diff --git a/hotspot/src/share/vm/runtime/frame.cpp b/hotspot/src/share/vm/runtime/frame.cpp
index 6f5724323cd..4fae1c8fe11 100644
--- a/hotspot/src/share/vm/runtime/frame.cpp
+++ b/hotspot/src/share/vm/runtime/frame.cpp
@@ -652,7 +652,7 @@ void frame::interpreter_frame_print_on(outputStream* st) const {
// Return whether the frame is in the VM or os indicating a Hotspot problem.
// Otherwise, it's likely a bug in the native library that the Java code calls,
// hopefully indicating where to submit bugs.
-static void print_C_frame(outputStream* st, char* buf, int buflen, address pc) {
+void frame::print_C_frame(outputStream* st, char* buf, int buflen, address pc) {
// C/C++ frame
bool in_vm = os::address_is_in_vm(pc);
st->print(in_vm ? "V" : "C");
diff --git a/hotspot/src/share/vm/runtime/frame.hpp b/hotspot/src/share/vm/runtime/frame.hpp
index 096b467b5f8..78292c662ec 100644
--- a/hotspot/src/share/vm/runtime/frame.hpp
+++ b/hotspot/src/share/vm/runtime/frame.hpp
@@ -406,6 +406,7 @@ class frame VALUE_OBJ_CLASS_SPEC {
void print_on(outputStream* st) const;
void interpreter_frame_print_on(outputStream* st) const;
void print_on_error(outputStream* st, char* buf, int buflen, bool verbose = false) const;
+ static void print_C_frame(outputStream* st, char* buf, int buflen, address pc);
// Add annotated descriptions of memory locations belonging to this frame to values
void describe(FrameValues& values, int frame_no);
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index c9bcbe1f4d3..f2cf5efabeb 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -443,8 +443,8 @@ class CommandLineFlags {
"Use 32-bit object references in 64-bit VM " \
"lp64_product means flag is always constant in 32 bit VM") \
\
- lp64_product(bool, UseCompressedKlassPointers, false, \
- "Use 32-bit klass pointers in 64-bit VM " \
+ lp64_product(bool, UseCompressedClassPointers, false, \
+ "Use 32-bit class pointers in 64-bit VM " \
"lp64_product means flag is always constant in 32 bit VM") \
\
notproduct(bool, CheckCompressedOops, true, \
@@ -880,7 +880,7 @@ class CommandLineFlags {
"stay alive at the expense of JVM performance") \
\
diagnostic(bool, LogCompilation, false, \
- "Log compilation activity in detail to hotspot.log or LogFile") \
+ "Log compilation activity in detail to LogFile") \
\
product(bool, PrintCompilation, false, \
"Print compilations") \
@@ -2498,16 +2498,17 @@ class CommandLineFlags {
"Print all VM flags with default values and descriptions and exit")\
\
diagnostic(bool, SerializeVMOutput, true, \
- "Use a mutex to serialize output to tty and hotspot.log") \
+ "Use a mutex to serialize output to tty and LogFile") \
\
diagnostic(bool, DisplayVMOutput, true, \
"Display all VM output on the tty, independently of LogVMOutput") \
\
- diagnostic(bool, LogVMOutput, trueInDebug, \
- "Save VM output to hotspot.log, or to LogFile") \
+ diagnostic(bool, LogVMOutput, false, \
+ "Save VM output to LogFile") \
\
diagnostic(ccstr, LogFile, NULL, \
- "If LogVMOutput is on, save VM output to this file [hotspot.log]") \
+ "If LogVMOutput or LogCompilation is on, save VM output to " \
+ "this file [default: ./hotspot_pid%p.log] (%p replaced with pid)") \
\
product(ccstr, ErrorFile, NULL, \
"If an error occurs, save the error data to this file " \
@@ -3039,9 +3040,9 @@ class CommandLineFlags {
product(uintx, MaxMetaspaceSize, max_uintx, \
"Maximum size of Metaspaces (in bytes)") \
\
- product(uintx, ClassMetaspaceSize, 1*G, \
- "Maximum size of InstanceKlass area in Metaspace used for " \
- "UseCompressedKlassPointers") \
+ product(uintx, CompressedClassSpaceSize, 1*G, \
+ "Maximum size of class area in Metaspace when compressed " \
+ "class pointers are used") \
\
product(uintx, MinHeapFreeRatio, 40, \
"Min percentage of heap free after GC to avoid expansion") \
@@ -3649,6 +3650,9 @@ class CommandLineFlags {
experimental(bool, TrustFinalNonStaticFields, false, \
"trust final non-static declarations for constant folding") \
\
+ experimental(bool, FoldStableValues, false, \
+ "Private flag to control optimizations for stable variables") \
+ \
develop(bool, TraceInvokeDynamic, false, \
"trace internal invoke dynamic operations") \
\
diff --git a/hotspot/src/share/vm/runtime/interfaceSupport.hpp b/hotspot/src/share/vm/runtime/interfaceSupport.hpp
index f995a4ee714..4d2ca5137ea 100644
--- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp
@@ -471,16 +471,6 @@ class RuntimeHistogramElement : public HistogramElement {
VM_ENTRY_BASE(result_type, header, thread) \
debug_only(VMEntryWrapper __vew;)
-// Another special case for nmethod_entry_point so the nmethod that the
-// interpreter is about to branch to doesn't get flushed before as we
-// branch to it's interpreter_entry_point. Skip stress testing here too.
-// Also we don't allow async exceptions because it is just too painful.
-#define IRT_ENTRY_FOR_NMETHOD(result_type, header) \
- result_type header { \
- nmethodLocker _nmlock(nm); \
- ThreadInVMfromJavaNoAsyncException __tiv(thread); \
- VM_ENTRY_BASE(result_type, header, thread)
-
#define IRT_END }
diff --git a/hotspot/src/share/vm/runtime/mutexLocker.cpp b/hotspot/src/share/vm/runtime/mutexLocker.cpp
index f513b7b376c..19f98cc2e4f 100644
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp
@@ -45,7 +45,6 @@ Mutex* InlineCacheBuffer_lock = NULL;
Mutex* VMStatistic_lock = NULL;
Mutex* JNIGlobalHandle_lock = NULL;
Mutex* JNIHandleBlockFreeList_lock = NULL;
-Mutex* JNICachedItableIndex_lock = NULL;
Mutex* MemberNameTable_lock = NULL;
Mutex* JmethodIdCreation_lock = NULL;
Mutex* JfieldIdCreation_lock = NULL;
@@ -253,7 +252,6 @@ void mutex_init() {
}
def(Heap_lock , Monitor, nonleaf+1, false);
def(JfieldIdCreation_lock , Mutex , nonleaf+1, true ); // jfieldID, Used in VM_Operation
- def(JNICachedItableIndex_lock , Mutex , nonleaf+1, false); // Used to cache an itable index during JNI invoke
def(MemberNameTable_lock , Mutex , nonleaf+1, false); // Used to protect MemberNameTable
def(CompiledIC_lock , Mutex , nonleaf+2, false); // locks VtableStubs_lock, InlineCacheBuffer_lock
diff --git a/hotspot/src/share/vm/runtime/mutexLocker.hpp b/hotspot/src/share/vm/runtime/mutexLocker.hpp
index d98b8d890fd..361febdcdb8 100644
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -50,7 +50,6 @@ extern Mutex* InlineCacheBuffer_lock; // a lock used to guard the Inl
extern Mutex* VMStatistic_lock; // a lock used to guard statistics count increment
extern Mutex* JNIGlobalHandle_lock; // a lock on creating JNI global handles
extern Mutex* JNIHandleBlockFreeList_lock; // a lock on the JNI handle block free list
-extern Mutex* JNICachedItableIndex_lock; // a lock on caching an itable index during JNI invoke
extern Mutex* MemberNameTable_lock; // a lock on the MemberNameTable updates
extern Mutex* JmethodIdCreation_lock; // a lock on creating JNI method identifiers
extern Mutex* JfieldIdCreation_lock; // a lock on creating JNI static field identifiers
diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp
index 0c83565195c..e2d930a1d59 100644
--- a/hotspot/src/share/vm/runtime/os.cpp
+++ b/hotspot/src/share/vm/runtime/os.cpp
@@ -314,6 +314,11 @@ static void signal_thread_entry(JavaThread* thread, TRAPS) {
}
}
+void os::init_before_ergo() {
+ // We need to initialize large page support here because ergonomics takes some
+ // decisions depending on large page support and the calculated large page size.
+ large_page_init();
+}
void os::signal_init() {
if (!ReduceSignalUsage) {
@@ -454,6 +459,7 @@ void* os::native_java_library() {
*/
void* os::find_agent_function(AgentLibrary *agent_lib, bool check_lib,
const char *syms[], size_t syms_len) {
+ assert(agent_lib != NULL, "sanity check");
const char *lib_name;
void *handle = agent_lib->os_lib();
void *entryName = NULL;
@@ -484,6 +490,7 @@ bool os::find_builtin_agent(AgentLibrary *agent_lib, const char *syms[],
void *proc_handle;
void *save_handle;
+ assert(agent_lib != NULL, "sanity check");
if (agent_lib->name() == NULL) {
return false;
}
@@ -493,14 +500,13 @@ bool os::find_builtin_agent(AgentLibrary *agent_lib, const char *syms[],
// We want to look in this process' symbol table.
agent_lib->set_os_lib(proc_handle);
ret = find_agent_function(agent_lib, true, syms, syms_len);
- agent_lib->set_os_lib(save_handle);
if (ret != NULL) {
// Found an entry point like Agent_OnLoad_lib_name so we have a static agent
- agent_lib->set_os_lib(proc_handle);
agent_lib->set_valid();
agent_lib->set_static_lib(true);
return true;
}
+ agent_lib->set_os_lib(save_handle);
return false;
}
diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp
index e43d68981cb..17fcd3bdd79 100644
--- a/hotspot/src/share/vm/runtime/os.hpp
+++ b/hotspot/src/share/vm/runtime/os.hpp
@@ -91,6 +91,8 @@ const bool ExecMem = true;
typedef void (*java_call_t)(JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread);
class os: AllStatic {
+ friend class VMStructs;
+
public:
enum { page_sizes_max = 9 }; // Size of _page_sizes array (8 plus a sentinel)
@@ -139,7 +141,10 @@ class os: AllStatic {
public:
static void init(void); // Called before command line parsing
+ static void init_before_ergo(void); // Called after command line parsing
+ // before VM ergonomics processing.
static jint init_2(void); // Called after command line parsing
+ // and VM ergonomics processing
static void init_globals(void) { // Called from init_globals() in init.cpp
init_globals_ext();
}
@@ -254,6 +259,11 @@ class os: AllStatic {
static size_t page_size_for_region(size_t region_min_size,
size_t region_max_size,
uint min_pages);
+ // Return the largest page size that can be used
+ static size_t max_page_size() {
+ // The _page_sizes array is sorted in descending order.
+ 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
@@ -795,6 +805,14 @@ class os: AllStatic {
#endif
public:
+#ifndef PLATFORM_PRINT_NATIVE_STACK
+ // No platform-specific code for printing the native stack.
+ static bool platform_print_native_stack(outputStream* st, void* context,
+ char *buf, int buf_size) {
+ return false;
+ }
+#endif
+
// debugging support (mostly used by debug.cpp but also fatal error handler)
static bool find(address pc, outputStream* st = tty); // OS specific function to make sense out of an address
diff --git a/hotspot/src/share/vm/runtime/reflection.cpp b/hotspot/src/share/vm/runtime/reflection.cpp
index f06a7f922aa..be29fdecfcf 100644
--- a/hotspot/src/share/vm/runtime/reflection.cpp
+++ b/hotspot/src/share/vm/runtime/reflection.cpp
@@ -952,7 +952,8 @@ oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method,
}
} else {
// if the method can be overridden, we resolve using the vtable index.
- int index = reflected_method->vtable_index();
+ assert(!reflected_method->has_itable_index(), "");
+ int index = reflected_method->vtable_index();
method = reflected_method;
if (index != Method::nonvirtual_vtable_index) {
// target_klass might be an arrayKlassOop but all vtables start at
diff --git a/hotspot/src/share/vm/runtime/reflectionUtils.hpp b/hotspot/src/share/vm/runtime/reflectionUtils.hpp
index d51b2ab7874..71a500976a7 100644
--- a/hotspot/src/share/vm/runtime/reflectionUtils.hpp
+++ b/hotspot/src/share/vm/runtime/reflectionUtils.hpp
@@ -109,6 +109,8 @@ class FieldStream : public KlassStream {
private:
int length() const { return _klass->java_fields_count(); }
+ fieldDescriptor _fd_buf;
+
public:
FieldStream(instanceKlassHandle klass, bool local_only, bool classes_only)
: KlassStream(klass, local_only, classes_only) {
@@ -134,6 +136,12 @@ class FieldStream : public KlassStream {
int offset() const {
return _klass->field_offset( index() );
}
+ // bridge to a heavier API:
+ fieldDescriptor& field_descriptor() const {
+ fieldDescriptor& field = const_cast(_fd_buf);
+ field.reinitialize(_klass(), _index);
+ return field;
+ }
};
class FilteredField : public CHeapObj {
diff --git a/hotspot/src/share/vm/runtime/sweeper.cpp b/hotspot/src/share/vm/runtime/sweeper.cpp
index ebecda50be0..37315aec328 100644
--- a/hotspot/src/share/vm/runtime/sweeper.cpp
+++ b/hotspot/src/share/vm/runtime/sweeper.cpp
@@ -269,6 +269,7 @@ void NMethodSweeper::sweep_code_cache() {
// the number of nmethods changes during the sweep so the final
// stage must iterate until it there are no more nmethods.
int todo = (CodeCache::nof_nmethods() - _seen) / _invocations;
+ int swept_count = 0;
assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here");
assert(!CodeCache_lock->owned_by_self(), "just checking");
@@ -278,6 +279,7 @@ void NMethodSweeper::sweep_code_cache() {
// The last invocation iterates until there are no more nmethods
for (int i = 0; (i < todo || _invocations == 1) && _current != NULL; i++) {
+ swept_count++;
if (SafepointSynchronize::is_synchronizing()) { // Safepoint request
if (PrintMethodFlushing && Verbose) {
tty->print_cr("### Sweep at %d out of %d, invocation: %d, yielding to safepoint", _seen, CodeCache::nof_nmethods(), _invocations);
@@ -331,7 +333,7 @@ void NMethodSweeper::sweep_code_cache() {
event.set_endtime(sweep_end_counter);
event.set_sweepIndex(_traversals);
event.set_sweepFractionIndex(NmethodSweepFraction - _invocations + 1);
- event.set_sweptCount(todo);
+ event.set_sweptCount(swept_count);
event.set_flushedCount(_flushed_count);
event.set_markedCount(_marked_count);
event.set_zombifiedCount(_zombified_count);
diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp
index d5bc3a00006..a0f0bdba713 100644
--- a/hotspot/src/share/vm/runtime/thread.cpp
+++ b/hotspot/src/share/vm/runtime/thread.cpp
@@ -333,6 +333,8 @@ Thread::~Thread() {
// Reclaim the objectmonitors from the omFreeList of the moribund thread.
ObjectSynchronizer::omFlush (this) ;
+ EVENT_THREAD_DESTRUCT(this);
+
// stack_base can be NULL if the thread is never started or exited before
// record_stack_base_and_size called. Although, we would like to ensure
// that all started threads do call record_stack_base_and_size(), there is
@@ -3329,6 +3331,11 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
jint parse_result = Arguments::parse(args);
if (parse_result != JNI_OK) return parse_result;
+ os::init_before_ergo();
+
+ jint ergo_result = Arguments::apply_ergo();
+ if (ergo_result != JNI_OK) return ergo_result;
+
if (PauseAtStartup) {
os::pause();
}
@@ -3714,7 +3721,7 @@ static OnLoadEntry_t lookup_on_load(AgentLibrary* agent, const char *on_load_sym
const char *name = agent->name();
const char *msg = "Could not find agent library ";
- // First check to see if agent is statcally linked into executable
+ // First check to see if agent is statically linked into executable
if (os::find_builtin_agent(agent, on_load_symbols, num_symbol_entries)) {
library = agent->os_lib();
} else if (agent->is_absolute_path()) {
diff --git a/hotspot/src/share/vm/runtime/virtualspace.cpp b/hotspot/src/share/vm/runtime/virtualspace.cpp
index 9e01fe0292f..98ee7635002 100644
--- a/hotspot/src/share/vm/runtime/virtualspace.cpp
+++ b/hotspot/src/share/vm/runtime/virtualspace.cpp
@@ -453,6 +453,42 @@ size_t VirtualSpace::uncommitted_size() const {
return reserved_size() - committed_size();
}
+size_t VirtualSpace::actual_committed_size() const {
+ // Special VirtualSpaces commit all reserved space up front.
+ if (special()) {
+ return reserved_size();
+ }
+
+ size_t committed_low = pointer_delta(_lower_high, _low_boundary, sizeof(char));
+ size_t committed_middle = pointer_delta(_middle_high, _lower_high_boundary, sizeof(char));
+ size_t committed_high = pointer_delta(_upper_high, _middle_high_boundary, sizeof(char));
+
+#ifdef ASSERT
+ size_t lower = pointer_delta(_lower_high_boundary, _low_boundary, sizeof(char));
+ size_t middle = pointer_delta(_middle_high_boundary, _lower_high_boundary, sizeof(char));
+ size_t upper = pointer_delta(_upper_high_boundary, _middle_high_boundary, sizeof(char));
+
+ if (committed_high > 0) {
+ assert(committed_low == lower, "Must be");
+ assert(committed_middle == middle, "Must be");
+ }
+
+ if (committed_middle > 0) {
+ assert(committed_low == lower, "Must be");
+ }
+ if (committed_middle < middle) {
+ assert(committed_high == 0, "Must be");
+ }
+
+ if (committed_low < lower) {
+ assert(committed_high == 0, "Must be");
+ assert(committed_middle == 0, "Must be");
+ }
+#endif
+
+ return committed_low + committed_middle + committed_high;
+}
+
bool VirtualSpace::contains(const void* p) const {
return low() <= (const char*) p && (const char*) p < high();
@@ -718,16 +754,19 @@ void VirtualSpace::check_for_contiguity() {
assert(high() <= upper_high(), "upper high");
}
-void VirtualSpace::print() {
- tty->print ("Virtual space:");
- if (special()) tty->print(" (pinned in memory)");
- tty->cr();
- tty->print_cr(" - committed: " SIZE_FORMAT, committed_size());
- tty->print_cr(" - reserved: " SIZE_FORMAT, reserved_size());
- tty->print_cr(" - [low, high]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low(), high());
- tty->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low_boundary(), high_boundary());
+void VirtualSpace::print_on(outputStream* out) {
+ out->print ("Virtual space:");
+ if (special()) out->print(" (pinned in memory)");
+ out->cr();
+ out->print_cr(" - committed: " SIZE_FORMAT, committed_size());
+ out->print_cr(" - reserved: " SIZE_FORMAT, reserved_size());
+ out->print_cr(" - [low, high]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low(), high());
+ out->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low_boundary(), high_boundary());
}
+void VirtualSpace::print() {
+ print_on(tty);
+}
/////////////// Unit tests ///////////////
@@ -910,6 +949,109 @@ void TestReservedSpace_test() {
TestReservedSpace::test_reserved_space();
}
+#define assert_equals(actual, expected) \
+ assert(actual == expected, \
+ err_msg("Got " SIZE_FORMAT " expected " \
+ SIZE_FORMAT, actual, expected));
+
+#define assert_ge(value1, value2) \
+ assert(value1 >= value2, \
+ err_msg("'" #value1 "': " SIZE_FORMAT " '" \
+ #value2 "': " SIZE_FORMAT, value1, value2));
+
+#define assert_lt(value1, value2) \
+ assert(value1 < value2, \
+ err_msg("'" #value1 "': " SIZE_FORMAT " '" \
+ #value2 "': " SIZE_FORMAT, value1, value2));
+
+
+class TestVirtualSpace : AllStatic {
+ public:
+ static void test_virtual_space_actual_committed_space(size_t reserve_size, size_t commit_size) {
+ size_t granularity = os::vm_allocation_granularity();
+ size_t reserve_size_aligned = align_size_up(reserve_size, granularity);
+
+ ReservedSpace reserved(reserve_size_aligned);
+
+ assert(reserved.is_reserved(), "Must be");
+
+ VirtualSpace vs;
+ bool initialized = vs.initialize(reserved, 0);
+ assert(initialized, "Failed to initialize VirtualSpace");
+
+ vs.expand_by(commit_size, false);
+
+ if (vs.special()) {
+ assert_equals(vs.actual_committed_size(), reserve_size_aligned);
+ } else {
+ assert_ge(vs.actual_committed_size(), commit_size);
+ // Approximate the commit granularity.
+ size_t commit_granularity = UseLargePages ? os::large_page_size() : os::vm_page_size();
+ assert_lt(vs.actual_committed_size(), commit_size + commit_granularity);
+ }
+
+ reserved.release();
+ }
+
+ static void test_virtual_space_actual_committed_space_one_large_page() {
+ if (!UseLargePages) {
+ return;
+ }
+
+ size_t large_page_size = os::large_page_size();
+
+ ReservedSpace reserved(large_page_size, large_page_size, true, false);
+
+ assert(reserved.is_reserved(), "Must be");
+
+ VirtualSpace vs;
+ bool initialized = vs.initialize(reserved, 0);
+ assert(initialized, "Failed to initialize VirtualSpace");
+
+ vs.expand_by(large_page_size, false);
+
+ assert_equals(vs.actual_committed_size(), large_page_size);
+
+ reserved.release();
+ }
+
+ static void test_virtual_space_actual_committed_space() {
+ test_virtual_space_actual_committed_space(4 * K, 0);
+ test_virtual_space_actual_committed_space(4 * K, 4 * K);
+ test_virtual_space_actual_committed_space(8 * K, 0);
+ test_virtual_space_actual_committed_space(8 * K, 4 * K);
+ test_virtual_space_actual_committed_space(8 * K, 8 * K);
+ test_virtual_space_actual_committed_space(12 * K, 0);
+ test_virtual_space_actual_committed_space(12 * K, 4 * K);
+ test_virtual_space_actual_committed_space(12 * K, 8 * K);
+ test_virtual_space_actual_committed_space(12 * K, 12 * K);
+ test_virtual_space_actual_committed_space(64 * K, 0);
+ test_virtual_space_actual_committed_space(64 * K, 32 * K);
+ test_virtual_space_actual_committed_space(64 * K, 64 * K);
+ test_virtual_space_actual_committed_space(2 * M, 0);
+ test_virtual_space_actual_committed_space(2 * M, 4 * K);
+ test_virtual_space_actual_committed_space(2 * M, 64 * K);
+ test_virtual_space_actual_committed_space(2 * M, 1 * M);
+ test_virtual_space_actual_committed_space(2 * M, 2 * M);
+ test_virtual_space_actual_committed_space(10 * M, 0);
+ test_virtual_space_actual_committed_space(10 * M, 4 * K);
+ test_virtual_space_actual_committed_space(10 * M, 8 * K);
+ test_virtual_space_actual_committed_space(10 * M, 1 * M);
+ test_virtual_space_actual_committed_space(10 * M, 2 * M);
+ test_virtual_space_actual_committed_space(10 * M, 5 * M);
+ test_virtual_space_actual_committed_space(10 * M, 10 * M);
+ }
+
+ static void test_virtual_space() {
+ test_virtual_space_actual_committed_space();
+ test_virtual_space_actual_committed_space_one_large_page();
+ }
+};
+
+void TestVirtualSpace_test() {
+ TestVirtualSpace::test_virtual_space();
+}
+
#endif // PRODUCT
#endif
diff --git a/hotspot/src/share/vm/runtime/virtualspace.hpp b/hotspot/src/share/vm/runtime/virtualspace.hpp
index bca9b6c14fc..02b14734a00 100644
--- a/hotspot/src/share/vm/runtime/virtualspace.hpp
+++ b/hotspot/src/share/vm/runtime/virtualspace.hpp
@@ -183,11 +183,16 @@ class VirtualSpace VALUE_OBJ_CLASS_SPEC {
// Destruction
~VirtualSpace();
- // Testers (all sizes are byte sizes)
- size_t committed_size() const;
- size_t reserved_size() const;
+ // Reserved memory
+ size_t reserved_size() const;
+ // Actually committed OS memory
+ size_t actual_committed_size() const;
+ // Memory used/expanded in this virtual space
+ size_t committed_size() const;
+ // Memory left to use/expand in this virtual space
size_t uncommitted_size() const;
- bool contains(const void* p) const;
+
+ bool contains(const void* p) const;
// Operations
// returns true on success, false otherwise
@@ -198,7 +203,8 @@ class VirtualSpace VALUE_OBJ_CLASS_SPEC {
void check_for_contiguity() PRODUCT_RETURN;
// Debugging
- void print() PRODUCT_RETURN;
+ void print_on(outputStream* out) PRODUCT_RETURN;
+ void print();
};
#endif // SHARE_VM_RUNTIME_VIRTUALSPACE_HPP
diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp
index 7e0df23a3e1..55405b27fd4 100644
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp
@@ -315,7 +315,6 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
nonstatic_field(InstanceKlass, _breakpoints, BreakpointInfo*) \
nonstatic_field(InstanceKlass, _generic_signature_index, u2) \
nonstatic_field(InstanceKlass, _methods_jmethod_ids, jmethodID*) \
- nonstatic_field(InstanceKlass, _methods_cached_itable_indices, int*) \
volatile_nonstatic_field(InstanceKlass, _idnum_allocated_count, u2) \
nonstatic_field(InstanceKlass, _annotations, Annotations*) \
nonstatic_field(InstanceKlass, _dependencies, nmethodBucket*) \
@@ -330,11 +329,13 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
nonstatic_field(Klass, _java_mirror, oop) \
nonstatic_field(Klass, _modifier_flags, jint) \
nonstatic_field(Klass, _super, Klass*) \
+ nonstatic_field(Klass, _subklass, Klass*) \
nonstatic_field(Klass, _layout_helper, jint) \
nonstatic_field(Klass, _name, Symbol*) \
nonstatic_field(Klass, _access_flags, AccessFlags) \
- nonstatic_field(Klass, _subklass, Klass*) \
+ nonstatic_field(Klass, _prototype_header, markOop) \
nonstatic_field(Klass, _next_sibling, Klass*) \
+ nonstatic_field(vtableEntry, _method, Method*) \
nonstatic_field(MethodData, _size, int) \
nonstatic_field(MethodData, _method, Method*) \
nonstatic_field(MethodData, _data_size, int) \
@@ -342,10 +343,15 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
nonstatic_field(MethodData, _nof_decompiles, uint) \
nonstatic_field(MethodData, _nof_overflow_recompiles, uint) \
nonstatic_field(MethodData, _nof_overflow_traps, uint) \
+ nonstatic_field(MethodData, _trap_hist._array[0], u1) \
nonstatic_field(MethodData, _eflags, intx) \
nonstatic_field(MethodData, _arg_local, intx) \
nonstatic_field(MethodData, _arg_stack, intx) \
nonstatic_field(MethodData, _arg_returned, intx) \
+ nonstatic_field(DataLayout, _header._struct._tag, u1) \
+ nonstatic_field(DataLayout, _header._struct._flags, u1) \
+ nonstatic_field(DataLayout, _header._struct._bci, u2) \
+ nonstatic_field(DataLayout, _cells[0], intptr_t) \
nonstatic_field(MethodCounters, _interpreter_invocation_count, int) \
nonstatic_field(MethodCounters, _interpreter_throwout_count, u2) \
nonstatic_field(MethodCounters, _number_of_breakpoints, u2) \
@@ -357,6 +363,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
nonstatic_field(Method, _access_flags, AccessFlags) \
nonstatic_field(Method, _vtable_index, int) \
nonstatic_field(Method, _method_size, u2) \
+ nonstatic_field(Method, _intrinsic_id, u1) \
nonproduct_nonstatic_field(Method, _compiled_invocation_count, int) \
volatile_nonstatic_field(Method, _code, nmethod*) \
nonstatic_field(Method, _i2i_entry, address) \
@@ -443,12 +450,19 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
static_field(Universe, _bootstrapping, bool) \
static_field(Universe, _fully_initialized, bool) \
static_field(Universe, _verify_count, int) \
+ static_field(Universe, _non_oop_bits, intptr_t) \
static_field(Universe, _narrow_oop._base, address) \
static_field(Universe, _narrow_oop._shift, int) \
static_field(Universe, _narrow_oop._use_implicit_null_checks, bool) \
static_field(Universe, _narrow_klass._base, address) \
static_field(Universe, _narrow_klass._shift, int) \
\
+ /******/ \
+ /* os */ \
+ /******/ \
+ \
+ static_field(os, _polling_page, address) \
+ \
/**********************************************************************************/ \
/* Generation and Space hierarchies */ \
/**********************************************************************************/ \
@@ -456,6 +470,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
unchecked_nonstatic_field(ageTable, sizes, sizeof(ageTable::sizes)) \
\
nonstatic_field(BarrierSet, _max_covered_regions, int) \
+ nonstatic_field(BarrierSet, _kind, BarrierSet::Name) \
nonstatic_field(BlockOffsetTable, _bottom, HeapWord*) \
nonstatic_field(BlockOffsetTable, _end, HeapWord*) \
\
@@ -495,6 +510,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
nonstatic_field(CollectedHeap, _barrier_set, BarrierSet*) \
nonstatic_field(CollectedHeap, _defer_initial_card_mark, bool) \
nonstatic_field(CollectedHeap, _is_gc_active, bool) \
+ nonstatic_field(CollectedHeap, _total_collections, unsigned int) \
nonstatic_field(CompactibleSpace, _compaction_top, HeapWord*) \
nonstatic_field(CompactibleSpace, _first_dead, HeapWord*) \
nonstatic_field(CompactibleSpace, _end_of_live, HeapWord*) \
@@ -505,7 +521,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
nonstatic_field(ContiguousSpace, _saved_mark_word, HeapWord*) \
\
nonstatic_field(DefNewGeneration, _next_gen, Generation*) \
- nonstatic_field(DefNewGeneration, _tenuring_threshold, uint) \
+ nonstatic_field(DefNewGeneration, _tenuring_threshold, uint) \
nonstatic_field(DefNewGeneration, _age_table, ageTable) \
nonstatic_field(DefNewGeneration, _eden_space, EdenSpace*) \
nonstatic_field(DefNewGeneration, _from_space, ContiguousSpace*) \
@@ -552,6 +568,11 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
nonstatic_field(ThreadLocalAllocBuffer, _desired_size, size_t) \
nonstatic_field(ThreadLocalAllocBuffer, _refill_waste_limit, size_t) \
static_field(ThreadLocalAllocBuffer, _target_refills, unsigned) \
+ nonstatic_field(ThreadLocalAllocBuffer, _number_of_refills, unsigned) \
+ nonstatic_field(ThreadLocalAllocBuffer, _fast_refill_waste, unsigned) \
+ nonstatic_field(ThreadLocalAllocBuffer, _slow_refill_waste, unsigned) \
+ nonstatic_field(ThreadLocalAllocBuffer, _gc_waste, unsigned) \
+ nonstatic_field(ThreadLocalAllocBuffer, _slow_allocations, unsigned) \
nonstatic_field(VirtualSpace, _low_boundary, char*) \
nonstatic_field(VirtualSpace, _high_boundary, char*) \
nonstatic_field(VirtualSpace, _low, char*) \
@@ -713,6 +734,13 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
\
static_field(ClassLoaderDataGraph, _head, ClassLoaderData*) \
\
+ /**********/ \
+ /* Arrays */ \
+ /**********/ \
+ \
+ nonstatic_field(Array, _length, int) \
+ nonstatic_field(Array, _data[0], Klass*) \
+ \
/*******************/ \
/* GrowableArrays */ \
/*******************/ \
@@ -720,7 +748,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
nonstatic_field(GenericGrowableArray, _len, int) \
nonstatic_field(GenericGrowableArray, _max, int) \
nonstatic_field(GenericGrowableArray, _arena, Arena*) \
- nonstatic_field(GrowableArray, _data, int*) \
+ nonstatic_field(GrowableArray, _data, int*) \
\
/********************************/ \
/* CodeCache (NOTE: incomplete) */ \
@@ -763,7 +791,20 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
/* StubRoutines (NOTE: incomplete) */ \
/***********************************/ \
\
+ static_field(StubRoutines, _verify_oop_count, jint) \
static_field(StubRoutines, _call_stub_return_address, address) \
+ static_field(StubRoutines, _aescrypt_encryptBlock, address) \
+ static_field(StubRoutines, _aescrypt_decryptBlock, address) \
+ static_field(StubRoutines, _cipherBlockChaining_encryptAESCrypt, address) \
+ static_field(StubRoutines, _cipherBlockChaining_decryptAESCrypt, address) \
+ static_field(StubRoutines, _updateBytesCRC32, address) \
+ static_field(StubRoutines, _crc_table_adr, address) \
+ \
+ /*****************/ \
+ /* SharedRuntime */ \
+ /*****************/ \
+ \
+ static_field(SharedRuntime, _ic_miss_blob, RuntimeStub*) \
\
/***************************************/ \
/* PcDesc and other compiled code info */ \
@@ -853,6 +894,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
volatile_nonstatic_field(Thread, _suspend_flags, uint32_t) \
nonstatic_field(Thread, _active_handles, JNIHandleBlock*) \
nonstatic_field(Thread, _tlab, ThreadLocalAllocBuffer) \
+ nonstatic_field(Thread, _allocated_bytes, jlong) \
nonstatic_field(Thread, _current_pending_monitor, ObjectMonitor*) \
nonstatic_field(Thread, _current_pending_monitor_is_from_java, bool) \
nonstatic_field(Thread, _current_waiting_monitor, ObjectMonitor*) \
@@ -866,6 +908,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
nonstatic_field(JavaThread, _pending_async_exception, oop) \
volatile_nonstatic_field(JavaThread, _exception_oop, oop) \
volatile_nonstatic_field(JavaThread, _exception_pc, address) \
+ volatile_nonstatic_field(JavaThread, _is_method_handle_return, int) \
nonstatic_field(JavaThread, _is_compiling, bool) \
nonstatic_field(JavaThread, _special_runtime_exit_condition, JavaThread::AsyncRequests) \
nonstatic_field(JavaThread, _saved_exception_pc, address) \
@@ -875,6 +918,8 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
nonstatic_field(JavaThread, _stack_size, size_t) \
nonstatic_field(JavaThread, _vframe_array_head, vframeArray*) \
nonstatic_field(JavaThread, _vframe_array_last, vframeArray*) \
+ nonstatic_field(JavaThread, _satb_mark_queue, ObjPtrQueue) \
+ nonstatic_field(JavaThread, _dirty_card_queue, DirtyCardQueue) \
nonstatic_field(Thread, _resource_area, ResourceArea*) \
nonstatic_field(CompilerThread, _env, ciEnv*) \
\
@@ -1187,7 +1232,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
unchecked_nonstatic_field(Array, _data, sizeof(int)) \
unchecked_nonstatic_field(Array, _data, sizeof(u1)) \
unchecked_nonstatic_field(Array, _data, sizeof(u2)) \
- unchecked_nonstatic_field(Array, _data, sizeof(Method*)) \
+ unchecked_nonstatic_field(Array, _data, sizeof(Method*)) \
unchecked_nonstatic_field(Array, _data, sizeof(Klass*)) \
\
/*********************************/ \
@@ -1203,7 +1248,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
/* Miscellaneous fields */ \
/************************/ \
\
- nonstatic_field(CompileTask, _method, Method*) \
+ nonstatic_field(CompileTask, _method, Method*) \
nonstatic_field(CompileTask, _osr_bci, int) \
nonstatic_field(CompileTask, _comp_level, int) \
nonstatic_field(CompileTask, _compile_id, uint) \
@@ -1217,7 +1262,11 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
\
nonstatic_field(vframeArrayElement, _frame, frame) \
nonstatic_field(vframeArrayElement, _bci, int) \
- nonstatic_field(vframeArrayElement, _method, Method*) \
+ nonstatic_field(vframeArrayElement, _method, Method*) \
+ \
+ nonstatic_field(PtrQueue, _active, bool) \
+ nonstatic_field(PtrQueue, _buf, void**) \
+ nonstatic_field(PtrQueue, _index, size_t) \
\
nonstatic_field(AccessFlags, _flags, jint) \
nonstatic_field(elapsedTimer, _counter, jlong) \
@@ -1363,7 +1412,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
/* MetadataOopDesc hierarchy (NOTE: some missing) */ \
/**************************************************/ \
\
- declare_toplevel_type(CompiledICHolder) \
+ declare_toplevel_type(CompiledICHolder) \
declare_toplevel_type(MetaspaceObj) \
declare_type(Metadata, MetaspaceObj) \
declare_type(Klass, Metadata) \
@@ -1374,17 +1423,20 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
declare_type(InstanceClassLoaderKlass, InstanceKlass) \
declare_type(InstanceMirrorKlass, InstanceKlass) \
declare_type(InstanceRefKlass, InstanceKlass) \
- declare_type(ConstantPool, Metadata) \
- declare_type(ConstantPoolCache, MetaspaceObj) \
- declare_type(MethodData, Metadata) \
- declare_type(Method, Metadata) \
- declare_type(MethodCounters, MetaspaceObj) \
- declare_type(ConstMethod, MetaspaceObj) \
+ declare_type(ConstantPool, Metadata) \
+ declare_type(ConstantPoolCache, MetaspaceObj) \
+ declare_type(MethodData, Metadata) \
+ declare_type(Method, Metadata) \
+ declare_type(MethodCounters, MetaspaceObj) \
+ declare_type(ConstMethod, MetaspaceObj) \
+ \
+ declare_toplevel_type(vtableEntry) \
\
declare_toplevel_type(Symbol) \
declare_toplevel_type(Symbol*) \
declare_toplevel_type(volatile Metadata*) \
\
+ declare_toplevel_type(DataLayout) \
declare_toplevel_type(nmethodBucket) \
\
/********/ \
@@ -1432,6 +1484,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
declare_type(ModRefBarrierSet, BarrierSet) \
declare_type(CardTableModRefBS, ModRefBarrierSet) \
declare_type(CardTableModRefBSForCTRS, CardTableModRefBS) \
+ declare_toplevel_type(BarrierSet::Name) \
declare_toplevel_type(GenRemSet) \
declare_type(CardTableRS, GenRemSet) \
declare_toplevel_type(BlockOffsetSharedArray) \
@@ -1450,6 +1503,8 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
declare_toplevel_type(ThreadLocalAllocBuffer) \
declare_toplevel_type(VirtualSpace) \
declare_toplevel_type(WaterMark) \
+ declare_toplevel_type(ObjPtrQueue) \
+ declare_toplevel_type(DirtyCardQueue) \
\
/* Pointers to Garbage Collection types */ \
\
@@ -2068,6 +2123,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
declare_toplevel_type(StubQueue*) \
declare_toplevel_type(Thread*) \
declare_toplevel_type(Universe) \
+ declare_toplevel_type(os) \
declare_toplevel_type(vframeArray) \
declare_toplevel_type(vframeArrayElement) \
declare_toplevel_type(Annotations*) \
@@ -2076,6 +2132,8 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
/* Miscellaneous types */ \
/***************/ \
\
+ declare_toplevel_type(PtrQueue) \
+ \
/* freelist */ \
declare_toplevel_type(FreeChunk*) \
declare_toplevel_type(Metablock*) \
@@ -2106,6 +2164,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
/* Useful globals */ \
/******************/ \
\
+ declare_preprocessor_constant("ASSERT", DEBUG_ONLY(1) NOT_DEBUG(0)) \
\
/**************/ \
/* Stack bias */ \
@@ -2122,6 +2181,8 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
declare_constant(BytesPerWord) \
declare_constant(BytesPerLong) \
\
+ declare_constant(LogKlassAlignmentInBytes) \
+ \
/********************************************/ \
/* Generation and Space Hierarchy Constants */ \
/********************************************/ \
@@ -2130,6 +2191,9 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
\
declare_constant(BarrierSet::ModRef) \
declare_constant(BarrierSet::CardTableModRef) \
+ declare_constant(BarrierSet::CardTableExtension) \
+ declare_constant(BarrierSet::G1SATBCT) \
+ declare_constant(BarrierSet::G1SATBCTLogging) \
declare_constant(BarrierSet::Other) \
\
declare_constant(BlockOffsetSharedArray::LogN) \
@@ -2248,8 +2312,11 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
declare_constant(Klass::_primary_super_limit) \
declare_constant(Klass::_lh_instance_slow_path_bit) \
declare_constant(Klass::_lh_log2_element_size_shift) \
+ declare_constant(Klass::_lh_log2_element_size_mask) \
declare_constant(Klass::_lh_element_type_shift) \
+ declare_constant(Klass::_lh_element_type_mask) \
declare_constant(Klass::_lh_header_size_shift) \
+ declare_constant(Klass::_lh_header_size_mask) \
declare_constant(Klass::_lh_array_tag_shift) \
declare_constant(Klass::_lh_array_tag_type_value) \
declare_constant(Klass::_lh_array_tag_obj_value) \
@@ -2268,6 +2335,12 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
declare_constant(ConstMethod::_has_default_annotations) \
declare_constant(ConstMethod::_has_type_annotations) \
\
+ /**************/ \
+ /* DataLayout */ \
+ /**************/ \
+ \
+ declare_constant(DataLayout::cell_size) \
+ \
/*************************************/ \
/* InstanceKlass enum */ \
/*************************************/ \
@@ -2402,6 +2475,13 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
declare_constant(Deoptimization::Reason_LIMIT) \
declare_constant(Deoptimization::Reason_RECORDED_LIMIT) \
\
+ declare_constant(Deoptimization::Action_none) \
+ declare_constant(Deoptimization::Action_maybe_recompile) \
+ declare_constant(Deoptimization::Action_reinterpret) \
+ declare_constant(Deoptimization::Action_make_not_entrant) \
+ declare_constant(Deoptimization::Action_make_not_compilable) \
+ declare_constant(Deoptimization::Action_LIMIT) \
+ \
/*********************/ \
/* Matcher (C2 only) */ \
/*********************/ \
@@ -2468,6 +2548,16 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
declare_constant(vmSymbols::FIRST_SID) \
declare_constant(vmSymbols::SID_LIMIT) \
\
+ /****************/ \
+ /* vmIntrinsics */ \
+ /****************/ \
+ \
+ declare_constant(vmIntrinsics::_invokeBasic) \
+ declare_constant(vmIntrinsics::_linkToVirtual) \
+ declare_constant(vmIntrinsics::_linkToStatic) \
+ declare_constant(vmIntrinsics::_linkToSpecial) \
+ declare_constant(vmIntrinsics::_linkToInterface) \
+ \
/********************************/ \
/* Calling convention constants */ \
/********************************/ \
@@ -2515,6 +2605,8 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
declare_constant(markOopDesc::biased_lock_bit_in_place) \
declare_constant(markOopDesc::age_mask) \
declare_constant(markOopDesc::age_mask_in_place) \
+ declare_constant(markOopDesc::epoch_mask) \
+ declare_constant(markOopDesc::epoch_mask_in_place) \
declare_constant(markOopDesc::hash_mask) \
declare_constant(markOopDesc::hash_mask_in_place) \
declare_constant(markOopDesc::biased_lock_alignment) \
diff --git a/hotspot/src/share/vm/services/gcNotifier.cpp b/hotspot/src/share/vm/services/gcNotifier.cpp
index 7d1fe5d8944..1025072339a 100644
--- a/hotspot/src/share/vm/services/gcNotifier.cpp
+++ b/hotspot/src/share/vm/services/gcNotifier.cpp
@@ -209,7 +209,7 @@ void GCNotifier::sendNotificationInternal(TRAPS) {
GCNotificationRequest *request = getRequest();
if (request != NULL) {
NotificationMark nm(request);
- Handle objGcInfo = createGcInfo(request->gcManager, request->gcStatInfo, THREAD);
+ Handle objGcInfo = createGcInfo(request->gcManager, request->gcStatInfo, CHECK);
Handle objName = java_lang_String::create_from_str(request->gcManager->name(), CHECK);
Handle objAction = java_lang_String::create_from_str(request->gcAction, CHECK);
diff --git a/hotspot/src/share/vm/services/memPtr.cpp b/hotspot/src/share/vm/services/memPtr.cpp
index 3e124e2bde2..bc460517c58 100644
--- a/hotspot/src/share/vm/services/memPtr.cpp
+++ b/hotspot/src/share/vm/services/memPtr.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -34,9 +34,9 @@ jint SequenceGenerator::next() {
jint seq = Atomic::add(1, &_seq_number);
if (seq < 0) {
MemTracker::shutdown(MemTracker::NMT_sequence_overflow);
+ } else {
+ NOT_PRODUCT(_max_seq_number = (seq > _max_seq_number) ? seq : _max_seq_number;)
}
- assert(seq > 0, "counter overflow");
- NOT_PRODUCT(_max_seq_number = (seq > _max_seq_number) ? seq : _max_seq_number;)
return seq;
}
diff --git a/hotspot/src/share/vm/services/memoryPool.cpp b/hotspot/src/share/vm/services/memoryPool.cpp
index 777b8b8f382..cfae726cf7b 100644
--- a/hotspot/src/share/vm/services/memoryPool.cpp
+++ b/hotspot/src/share/vm/services/memoryPool.cpp
@@ -260,10 +260,10 @@ MemoryUsage CodeHeapPool::get_memory_usage() {
}
MetaspacePool::MetaspacePool() :
- MemoryPool("Metaspace", NonHeap, capacity_in_bytes(), calculate_max_size(), true, false) { }
+ MemoryPool("Metaspace", NonHeap, 0, calculate_max_size(), true, false) { }
MemoryUsage MetaspacePool::get_memory_usage() {
- size_t committed = align_size_down_(capacity_in_bytes(), os::vm_page_size());
+ size_t committed = MetaspaceAux::committed_bytes();
return MemoryUsage(initial_size(), used_in_bytes(), committed, max_size());
}
@@ -271,26 +271,19 @@ size_t MetaspacePool::used_in_bytes() {
return MetaspaceAux::allocated_used_bytes();
}
-size_t MetaspacePool::capacity_in_bytes() const {
- return MetaspaceAux::allocated_capacity_bytes();
-}
-
size_t MetaspacePool::calculate_max_size() const {
- return FLAG_IS_CMDLINE(MaxMetaspaceSize) ? MaxMetaspaceSize : max_uintx;
+ return FLAG_IS_CMDLINE(MaxMetaspaceSize) ? MaxMetaspaceSize :
+ MemoryUsage::undefined_size();
}
CompressedKlassSpacePool::CompressedKlassSpacePool() :
- MemoryPool("Compressed Class Space", NonHeap, capacity_in_bytes(), ClassMetaspaceSize, true, false) { }
+ MemoryPool("Compressed Class Space", NonHeap, 0, CompressedClassSpaceSize, true, false) { }
size_t CompressedKlassSpacePool::used_in_bytes() {
return MetaspaceAux::allocated_used_bytes(Metaspace::ClassType);
}
-size_t CompressedKlassSpacePool::capacity_in_bytes() const {
- return MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType);
-}
-
MemoryUsage CompressedKlassSpacePool::get_memory_usage() {
- size_t committed = align_size_down_(capacity_in_bytes(), os::vm_page_size());
+ size_t committed = MetaspaceAux::committed_bytes(Metaspace::ClassType);
return MemoryUsage(initial_size(), used_in_bytes(), committed, max_size());
}
diff --git a/hotspot/src/share/vm/services/memoryPool.hpp b/hotspot/src/share/vm/services/memoryPool.hpp
index 08efe08e838..4ec810a985f 100644
--- a/hotspot/src/share/vm/services/memoryPool.hpp
+++ b/hotspot/src/share/vm/services/memoryPool.hpp
@@ -224,7 +224,6 @@ public:
class MetaspacePool : public MemoryPool {
size_t calculate_max_size() const;
- size_t capacity_in_bytes() const;
public:
MetaspacePool();
MemoryUsage get_memory_usage();
@@ -232,7 +231,6 @@ class MetaspacePool : public MemoryPool {
};
class CompressedKlassSpacePool : public MemoryPool {
- size_t capacity_in_bytes() const;
public:
CompressedKlassSpacePool();
MemoryUsage get_memory_usage();
diff --git a/hotspot/src/share/vm/services/memoryService.cpp b/hotspot/src/share/vm/services/memoryService.cpp
index bf0fb9cad24..6508cd2086a 100644
--- a/hotspot/src/share/vm/services/memoryService.cpp
+++ b/hotspot/src/share/vm/services/memoryService.cpp
@@ -409,7 +409,7 @@ void MemoryService::add_metaspace_memory_pools() {
mgr->add_pool(_metaspace_pool);
_pools_list->append(_metaspace_pool);
- if (UseCompressedKlassPointers) {
+ if (UseCompressedClassPointers) {
_compressed_class_pool = new CompressedKlassSpacePool();
mgr->add_pool(_compressed_class_pool);
_pools_list->append(_compressed_class_pool);
diff --git a/hotspot/src/share/vm/services/memoryUsage.hpp b/hotspot/src/share/vm/services/memoryUsage.hpp
index efc6f2966d1..9027f8e76b7 100644
--- a/hotspot/src/share/vm/services/memoryUsage.hpp
+++ b/hotspot/src/share/vm/services/memoryUsage.hpp
@@ -63,10 +63,12 @@ public:
size_t committed() const { return _committed; }
size_t max_size() const { return _maxSize; }
+ static size_t undefined_size() { return (size_t) -1; }
+
inline static jlong convert_to_jlong(size_t val) {
// In the 64-bit vm, a size_t can overflow a jlong (which is signed).
jlong ret;
- if (val == (size_t)-1) {
+ if (val == undefined_size()) {
ret = -1L;
} else {
NOT_LP64(ret = val;)
diff --git a/hotspot/src/share/vm/trace/traceMacros.hpp b/hotspot/src/share/vm/trace/traceMacros.hpp
index 1a6dd644935..4776e13507e 100644
--- a/hotspot/src/share/vm/trace/traceMacros.hpp
+++ b/hotspot/src/share/vm/trace/traceMacros.hpp
@@ -26,6 +26,7 @@
#define SHARE_VM_TRACE_TRACE_MACRO_HPP
#define EVENT_THREAD_EXIT(thread)
+#define EVENT_THREAD_DESTRUCT(thread)
#define TRACE_INIT_ID(k)
#define TRACE_DATA TraceThreadData
diff --git a/hotspot/src/share/vm/utilities/accessFlags.hpp b/hotspot/src/share/vm/utilities/accessFlags.hpp
index 99f9a3360f8..a3d3de99c91 100644
--- a/hotspot/src/share/vm/utilities/accessFlags.hpp
+++ b/hotspot/src/share/vm/utilities/accessFlags.hpp
@@ -78,11 +78,13 @@ enum {
JVM_ACC_FIELD_ACCESS_WATCHED = 0x00002000, // field access is watched by JVMTI
JVM_ACC_FIELD_MODIFICATION_WATCHED = 0x00008000, // field modification is watched by JVMTI
JVM_ACC_FIELD_INTERNAL = 0x00000400, // internal field, same as JVM_ACC_ABSTRACT
+ JVM_ACC_FIELD_STABLE = 0x00000020, // @Stable field, same as JVM_ACC_SYNCHRONIZED
JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE = 0x00000800, // field has generic signature
JVM_ACC_FIELD_INTERNAL_FLAGS = JVM_ACC_FIELD_ACCESS_WATCHED |
JVM_ACC_FIELD_MODIFICATION_WATCHED |
JVM_ACC_FIELD_INTERNAL |
+ JVM_ACC_FIELD_STABLE |
JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE,
// flags accepted by set_field_flags()
@@ -148,6 +150,7 @@ class AccessFlags VALUE_OBJ_CLASS_SPEC {
{ return (_flags & JVM_ACC_FIELD_MODIFICATION_WATCHED) != 0; }
bool on_stack() const { return (_flags & JVM_ACC_ON_STACK) != 0; }
bool is_internal() const { return (_flags & JVM_ACC_FIELD_INTERNAL) != 0; }
+ bool is_stable() const { return (_flags & JVM_ACC_FIELD_STABLE) != 0; }
bool field_has_generic_signature() const
{ return (_flags & JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE) != 0; }
diff --git a/hotspot/src/share/vm/utilities/bitMap.inline.hpp b/hotspot/src/share/vm/utilities/bitMap.inline.hpp
index 7bb244795fc..2171e849f8f 100644
--- a/hotspot/src/share/vm/utilities/bitMap.inline.hpp
+++ b/hotspot/src/share/vm/utilities/bitMap.inline.hpp
@@ -52,16 +52,16 @@ inline void BitMap::clear_bit(idx_t bit) {
inline bool BitMap::par_set_bit(idx_t bit) {
verify_index(bit);
- volatile idx_t* const addr = word_addr(bit);
- const idx_t mask = bit_mask(bit);
- idx_t old_val = *addr;
+ volatile bm_word_t* const addr = word_addr(bit);
+ const bm_word_t mask = bit_mask(bit);
+ bm_word_t old_val = *addr;
do {
- const idx_t new_val = old_val | mask;
+ const bm_word_t new_val = old_val | mask;
if (new_val == old_val) {
return false; // Someone else beat us to it.
}
- const idx_t cur_val = (idx_t) Atomic::cmpxchg_ptr((void*) new_val,
+ const bm_word_t cur_val = (bm_word_t) Atomic::cmpxchg_ptr((void*) new_val,
(volatile void*) addr,
(void*) old_val);
if (cur_val == old_val) {
@@ -73,16 +73,16 @@ inline bool BitMap::par_set_bit(idx_t bit) {
inline bool BitMap::par_clear_bit(idx_t bit) {
verify_index(bit);
- volatile idx_t* const addr = word_addr(bit);
- const idx_t mask = ~bit_mask(bit);
- idx_t old_val = *addr;
+ volatile bm_word_t* const addr = word_addr(bit);
+ const bm_word_t mask = ~bit_mask(bit);
+ bm_word_t old_val = *addr;
do {
- const idx_t new_val = old_val & mask;
+ const bm_word_t new_val = old_val & mask;
if (new_val == old_val) {
return false; // Someone else beat us to it.
}
- const idx_t cur_val = (idx_t) Atomic::cmpxchg_ptr((void*) new_val,
+ const bm_word_t cur_val = (bm_word_t) Atomic::cmpxchg_ptr((void*) new_val,
(volatile void*) addr,
(void*) old_val);
if (cur_val == old_val) {
diff --git a/hotspot/src/share/vm/utilities/decoder.cpp b/hotspot/src/share/vm/utilities/decoder.cpp
index 5489fe6fefb..3fc934b4f32 100644
--- a/hotspot/src/share/vm/utilities/decoder.cpp
+++ b/hotspot/src/share/vm/utilities/decoder.cpp
@@ -24,7 +24,6 @@
#include "precompiled.hpp"
#include "prims/jvm.h"
-#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
#include "utilities/decoder.hpp"
#include "utilities/vmError.hpp"
@@ -80,6 +79,23 @@ AbstractDecoder* Decoder::create_decoder() {
return decoder;
}
+inline bool DecoderLocker::is_first_error_thread() {
+ return (os::current_thread_id() == VMError::get_first_error_tid());
+}
+
+DecoderLocker::DecoderLocker() :
+ MutexLockerEx(DecoderLocker::is_first_error_thread() ?
+ NULL : Decoder::shared_decoder_lock(), true) {
+ _decoder = is_first_error_thread() ?
+ Decoder::get_error_handler_instance() : Decoder::get_shared_instance();
+ assert(_decoder != NULL, "null decoder");
+}
+
+Mutex* Decoder::shared_decoder_lock() {
+ assert(_shared_decoder_lock != NULL, "Just check");
+ return _shared_decoder_lock;
+}
+
bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const char* modulepath) {
assert(_shared_decoder_lock != NULL, "Just check");
bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
diff --git a/hotspot/src/share/vm/utilities/decoder.hpp b/hotspot/src/share/vm/utilities/decoder.hpp
index 0d2af80986c..0cc880f1915 100644
--- a/hotspot/src/share/vm/utilities/decoder.hpp
+++ b/hotspot/src/share/vm/utilities/decoder.hpp
@@ -28,6 +28,7 @@
#include "memory/allocation.hpp"
#include "runtime/mutex.hpp"
+#include "runtime/mutexLocker.hpp"
class AbstractDecoder : public CHeapObj {
public:
@@ -124,6 +125,19 @@ private:
protected:
static Mutex* _shared_decoder_lock;
+ static Mutex* shared_decoder_lock();
+
+ friend class DecoderLocker;
+};
+
+class DecoderLocker : public MutexLockerEx {
+ AbstractDecoder* _decoder;
+ inline bool is_first_error_thread();
+public:
+ DecoderLocker();
+ AbstractDecoder* decoder() {
+ return _decoder;
+ }
};
#endif // SHARE_VM_UTILITIES_DECODER_HPP
diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp
index 2f04fa0e437..e4215504a4d 100644
--- a/hotspot/src/share/vm/utilities/ostream.cpp
+++ b/hotspot/src/share/vm/utilities/ostream.cpp
@@ -342,7 +342,7 @@ void stringStream::write(const char* s, size_t len) {
}
char* stringStream::as_string() {
- char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos+1);
+ char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos + 1);
strncpy(copy, buffer, buffer_pos);
copy[buffer_pos] = 0; // terminating null
return copy;
@@ -355,14 +355,190 @@ outputStream* tty;
outputStream* gclog_or_tty;
extern Mutex* tty_lock;
+#define EXTRACHARLEN 32
+#define CURRENTAPPX ".current"
+#define FILENAMEBUFLEN 1024
+// convert YYYY-MM-DD HH:MM:SS to YYYY-MM-DD_HH-MM-SS
+char* get_datetime_string(char *buf, size_t len) {
+ os::local_time_string(buf, len);
+ int i = (int)strlen(buf);
+ while (i-- >= 0) {
+ if (buf[i] == ' ') buf[i] = '_';
+ else if (buf[i] == ':') buf[i] = '-';
+ }
+ return buf;
+}
+
+static const char* make_log_name_internal(const char* log_name, const char* force_directory,
+ int pid, const char* tms) {
+ const char* basename = log_name;
+ char file_sep = os::file_separator()[0];
+ const char* cp;
+ char pid_text[32];
+
+ for (cp = log_name; *cp != '\0'; cp++) {
+ if (*cp == '/' || *cp == file_sep) {
+ basename = cp + 1;
+ }
+ }
+ const char* nametail = log_name;
+ // Compute buffer length
+ size_t buffer_length;
+ if (force_directory != NULL) {
+ buffer_length = strlen(force_directory) + strlen(os::file_separator()) +
+ strlen(basename) + 1;
+ } else {
+ buffer_length = strlen(log_name) + 1;
+ }
+
+ // const char* star = strchr(basename, '*');
+ const char* pts = strstr(basename, "%p");
+ int pid_pos = (pts == NULL) ? -1 : (pts - nametail);
+
+ if (pid_pos >= 0) {
+ jio_snprintf(pid_text, sizeof(pid_text), "pid%u", pid);
+ buffer_length += strlen(pid_text);
+ }
+
+ pts = strstr(basename, "%t");
+ int tms_pos = (pts == NULL) ? -1 : (pts - nametail);
+ if (tms_pos >= 0) {
+ buffer_length += strlen(tms);
+ }
+
+ // Create big enough buffer.
+ char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
+
+ strcpy(buf, "");
+ if (force_directory != NULL) {
+ strcat(buf, force_directory);
+ strcat(buf, os::file_separator());
+ nametail = basename; // completely skip directory prefix
+ }
+
+ // who is first, %p or %t?
+ int first = -1, second = -1;
+ const char *p1st = NULL;
+ const char *p2nd = NULL;
+
+ if (pid_pos >= 0 && tms_pos >= 0) {
+ // contains both %p and %t
+ if (pid_pos < tms_pos) {
+ // case foo%pbar%tmonkey.log
+ first = pid_pos;
+ p1st = pid_text;
+ second = tms_pos;
+ p2nd = tms;
+ } else {
+ // case foo%tbar%pmonkey.log
+ first = tms_pos;
+ p1st = tms;
+ second = pid_pos;
+ p2nd = pid_text;
+ }
+ } else if (pid_pos >= 0) {
+ // contains %p only
+ first = pid_pos;
+ p1st = pid_text;
+ } else if (tms_pos >= 0) {
+ // contains %t only
+ first = tms_pos;
+ p1st = tms;
+ }
+
+ int buf_pos = (int)strlen(buf);
+ const char* tail = nametail;
+
+ if (first >= 0) {
+ tail = nametail + first + 2;
+ strncpy(&buf[buf_pos], nametail, first);
+ strcpy(&buf[buf_pos + first], p1st);
+ buf_pos = (int)strlen(buf);
+ if (second >= 0) {
+ strncpy(&buf[buf_pos], tail, second - first - 2);
+ strcpy(&buf[buf_pos + second - first - 2], p2nd);
+ tail = nametail + second + 2;
+ }
+ }
+ strcat(buf, tail); // append rest of name, or all of name
+ return buf;
+}
+
+// log_name comes from -XX:LogFile=log_name or -Xloggc:log_name
+// in log_name, %p => pipd1234 and
+// %t => YYYY-MM-DD_HH-MM-SS
+static const char* make_log_name(const char* log_name, const char* force_directory) {
+ char timestr[32];
+ get_datetime_string(timestr, sizeof(timestr));
+ return make_log_name_internal(log_name, force_directory, os::current_process_id(),
+ timestr);
+}
+
+#ifndef PRODUCT
+void test_loggc_filename() {
+ int pid;
+ char tms[32];
+ char i_result[FILENAMEBUFLEN];
+ const char* o_result;
+ get_datetime_string(tms, sizeof(tms));
+ pid = os::current_process_id();
+
+ // test.log
+ jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test.log", tms);
+ o_result = make_log_name_internal("test.log", NULL, pid, tms);
+ assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test.log\", NULL)");
+ FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+
+ // test-%t-%p.log
+ jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test-%s-pid%u.log", tms, pid);
+ o_result = make_log_name_internal("test-%t-%p.log", NULL, pid, tms);
+ assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t-%%p.log\", NULL)");
+ FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+
+ // test-%t%p.log
+ jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test-%spid%u.log", tms, pid);
+ o_result = make_log_name_internal("test-%t%p.log", NULL, pid, tms);
+ assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t%%p.log\", NULL)");
+ FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+
+ // %p%t.log
+ jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "pid%u%s.log", pid, tms);
+ o_result = make_log_name_internal("%p%t.log", NULL, pid, tms);
+ assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p%%t.log\", NULL)");
+ FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+
+ // %p-test.log
+ jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "pid%u-test.log", pid);
+ o_result = make_log_name_internal("%p-test.log", NULL, pid, tms);
+ assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p-test.log\", NULL)");
+ FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+
+ // %t.log
+ jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "%s.log", tms);
+ o_result = make_log_name_internal("%t.log", NULL, pid, tms);
+ assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%t.log\", NULL)");
+ FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+}
+#endif // PRODUCT
+
fileStream::fileStream(const char* file_name) {
_file = fopen(file_name, "w");
- _need_close = true;
+ if (_file != NULL) {
+ _need_close = true;
+ } else {
+ warning("Cannot open file %s due to %s\n", file_name, strerror(errno));
+ _need_close = false;
+ }
}
fileStream::fileStream(const char* file_name, const char* opentype) {
_file = fopen(file_name, opentype);
- _need_close = true;
+ if (_file != NULL) {
+ _need_close = true;
+ } else {
+ warning("Cannot open file %s due to %s\n", file_name, strerror(errno));
+ _need_close = false;
+ }
}
void fileStream::write(const char* s, size_t len) {
@@ -423,34 +599,51 @@ void fdStream::write(const char* s, size_t len) {
update_position(s, len);
}
-rotatingFileStream::~rotatingFileStream() {
+// dump vm version, os version, platform info, build id,
+// memory usage and command line flags into header
+void gcLogFileStream::dump_loggc_header() {
+ if (is_open()) {
+ print_cr(Abstract_VM_Version::internal_vm_info_string());
+ os::print_memory_info(this);
+ print("CommandLine flags: ");
+ CommandLineFlags::printSetFlags(this);
+ }
+}
+
+gcLogFileStream::~gcLogFileStream() {
if (_file != NULL) {
if (_need_close) fclose(_file);
- _file = NULL;
+ _file = NULL;
+ }
+ if (_file_name != NULL) {
FREE_C_HEAP_ARRAY(char, _file_name, mtInternal);
_file_name = NULL;
}
}
-rotatingFileStream::rotatingFileStream(const char* file_name) {
+gcLogFileStream::gcLogFileStream(const char* file_name) {
_cur_file_num = 0;
_bytes_written = 0L;
- _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal);
- jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num);
- _file = fopen(_file_name, "w");
- _need_close = true;
+ _file_name = make_log_name(file_name, NULL);
+
+ // gc log file rotation
+ if (UseGCLogFileRotation && NumberOfGCLogFiles > 1) {
+ char tempbuf[FILENAMEBUFLEN];
+ jio_snprintf(tempbuf, sizeof(tempbuf), "%s.%d" CURRENTAPPX, _file_name, _cur_file_num);
+ _file = fopen(tempbuf, "w");
+ } else {
+ _file = fopen(_file_name, "w");
+ }
+ if (_file != NULL) {
+ _need_close = true;
+ dump_loggc_header();
+ } else {
+ warning("Cannot open file %s due to %s\n", _file_name, strerror(errno));
+ _need_close = false;
+ }
}
-rotatingFileStream::rotatingFileStream(const char* file_name, const char* opentype) {
- _cur_file_num = 0;
- _bytes_written = 0L;
- _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal);
- jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num);
- _file = fopen(_file_name, opentype);
- _need_close = true;
-}
-
-void rotatingFileStream::write(const char* s, size_t len) {
+void gcLogFileStream::write(const char* s, size_t len) {
if (_file != NULL) {
size_t count = fwrite(s, 1, len, _file);
_bytes_written += count;
@@ -466,7 +659,12 @@ void rotatingFileStream::write(const char* s, size_t len) {
// write to gc log file at safepoint. If in future, changes made for mutator threads or
// concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log
// must be synchronized.
-void rotatingFileStream::rotate_log() {
+void gcLogFileStream::rotate_log() {
+ char time_msg[FILENAMEBUFLEN];
+ char time_str[EXTRACHARLEN];
+ char current_file_name[FILENAMEBUFLEN];
+ char renamed_file_name[FILENAMEBUFLEN];
+
if (_bytes_written < (jlong)GCLogFileSize) {
return;
}
@@ -481,27 +679,89 @@ void rotatingFileStream::rotate_log() {
// rotate in same file
rewind();
_bytes_written = 0L;
+ jio_snprintf(time_msg, sizeof(time_msg), "File %s rotated at %s\n",
+ _file_name, os::local_time_string((char *)time_str, sizeof(time_str)));
+ write(time_msg, strlen(time_msg));
+ dump_loggc_header();
return;
}
- // rotate file in names file.0, file.1, file.2, ..., file.
- // close current file, rotate to next file
+#if defined(_WINDOWS)
+#ifndef F_OK
+#define F_OK 0
+#endif
+#endif // _WINDOWS
+
+ // rotate file in names extended_filename.0, extended_filename.1, ...,
+ // extended_filename.. Current rotation file name will
+ // have a form of extended_filename..current where i is the current rotation
+ // file number. After it reaches max file size, the file will be saved and renamed
+ // with .current removed from its tail.
+ size_t filename_len = strlen(_file_name);
if (_file != NULL) {
- _cur_file_num ++;
- if (_cur_file_num >= NumberOfGCLogFiles) _cur_file_num = 0;
- jio_snprintf(_file_name, strlen(Arguments::gc_log_filename()) + 10, "%s.%d",
- Arguments::gc_log_filename(), _cur_file_num);
+ jio_snprintf(renamed_file_name, filename_len + EXTRACHARLEN, "%s.%d",
+ _file_name, _cur_file_num);
+ jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX,
+ _file_name, _cur_file_num);
+ jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file has reached the"
+ " maximum size. Saved as %s\n",
+ os::local_time_string((char *)time_str, sizeof(time_str)),
+ renamed_file_name);
+ write(time_msg, strlen(time_msg));
+
fclose(_file);
_file = NULL;
+
+ bool can_rename = true;
+ if (access(current_file_name, F_OK) != 0) {
+ // current file does not exist?
+ warning("No source file exists, cannot rename\n");
+ can_rename = false;
+ }
+ if (can_rename) {
+ if (access(renamed_file_name, F_OK) == 0) {
+ if (remove(renamed_file_name) != 0) {
+ warning("Could not delete existing file %s\n", renamed_file_name);
+ can_rename = false;
+ }
+ } else {
+ // file does not exist, ok to rename
+ }
+ }
+ if (can_rename && rename(current_file_name, renamed_file_name) != 0) {
+ warning("Could not rename %s to %s\n", _file_name, renamed_file_name);
+ }
}
- _file = fopen(_file_name, "w");
+
+ _cur_file_num++;
+ if (_cur_file_num > NumberOfGCLogFiles - 1) _cur_file_num = 0;
+ jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX,
+ _file_name, _cur_file_num);
+ _file = fopen(current_file_name, "w");
+
if (_file != NULL) {
_bytes_written = 0L;
_need_close = true;
+ // reuse current_file_name for time_msg
+ jio_snprintf(current_file_name, filename_len + EXTRACHARLEN,
+ "%s.%d", _file_name, _cur_file_num);
+ jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file created %s\n",
+ os::local_time_string((char *)time_str, sizeof(time_str)),
+ current_file_name);
+ write(time_msg, strlen(time_msg));
+ dump_loggc_header();
+ // remove the existing file
+ if (access(current_file_name, F_OK) == 0) {
+ if (remove(current_file_name) != 0) {
+ warning("Could not delete existing file %s\n", current_file_name);
+ }
+ }
} else {
- tty->print_cr("failed to open rotation log file %s due to %s\n",
+ warning("failed to open rotation log file %s due to %s\n"
+ "Turned off GC log file rotation\n",
_file_name, strerror(errno));
_need_close = false;
+ FLAG_SET_DEFAULT(UseGCLogFileRotation, false);
}
}
@@ -530,69 +790,9 @@ bool defaultStream::has_log_file() {
return _log_file != NULL;
}
-static const char* make_log_name(const char* log_name, const char* force_directory) {
- const char* basename = log_name;
- char file_sep = os::file_separator()[0];
- const char* cp;
- for (cp = log_name; *cp != '\0'; cp++) {
- if (*cp == '/' || *cp == file_sep) {
- basename = cp+1;
- }
- }
- const char* nametail = log_name;
-
- // Compute buffer length
- size_t buffer_length;
- if (force_directory != NULL) {
- buffer_length = strlen(force_directory) + strlen(os::file_separator()) +
- strlen(basename) + 1;
- } else {
- buffer_length = strlen(log_name) + 1;
- }
-
- const char* star = strchr(basename, '*');
- int star_pos = (star == NULL) ? -1 : (star - nametail);
- int skip = 1;
- if (star == NULL) {
- // Try %p
- star = strstr(basename, "%p");
- if (star != NULL) {
- skip = 2;
- }
- }
- star_pos = (star == NULL) ? -1 : (star - nametail);
-
- char pid[32];
- if (star_pos >= 0) {
- jio_snprintf(pid, sizeof(pid), "%u", os::current_process_id());
- buffer_length += strlen(pid);
- }
-
- // Create big enough buffer.
- char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
-
- strcpy(buf, "");
- if (force_directory != NULL) {
- strcat(buf, force_directory);
- strcat(buf, os::file_separator());
- nametail = basename; // completely skip directory prefix
- }
-
- if (star_pos >= 0) {
- // convert foo*bar.log or foo%pbar.log to foo123bar.log
- int buf_pos = (int) strlen(buf);
- strncpy(&buf[buf_pos], nametail, star_pos);
- strcpy(&buf[buf_pos + star_pos], pid);
- nametail += star_pos + skip; // skip prefix and pid format
- }
-
- strcat(buf, nametail); // append rest of name, or all of name
- return buf;
-}
-
void defaultStream::init_log() {
// %%% Need a MutexLocker?
- const char* log_name = LogFile != NULL ? LogFile : "hotspot.log";
+ const char* log_name = LogFile != NULL ? LogFile : "hotspot_pid%p.log";
const char* try_name = make_log_name(log_name, NULL);
fileStream* file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name);
if (!file->is_open()) {
@@ -603,14 +803,15 @@ void defaultStream::init_log() {
// Note: This feature is for maintainer use only. No need for L10N.
jio_print(warnbuf);
FREE_C_HEAP_ARRAY(char, try_name, mtInternal);
- try_name = make_log_name("hs_pid%p.log", os::get_temp_directory());
+ try_name = make_log_name(log_name, os::get_temp_directory());
jio_snprintf(warnbuf, sizeof(warnbuf),
"Warning: Forcing option -XX:LogFile=%s\n", try_name);
jio_print(warnbuf);
delete file;
file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name);
- FREE_C_HEAP_ARRAY(char, try_name, mtInternal);
}
+ FREE_C_HEAP_ARRAY(char, try_name, mtInternal);
+
if (file->is_open()) {
_log_file = file;
xmlStream* xs = new(ResourceObj::C_HEAP, mtInternal) xmlStream(file);
@@ -877,11 +1078,8 @@ void ostream_init_log() {
gclog_or_tty = tty; // default to tty
if (Arguments::gc_log_filename() != NULL) {
- fileStream * gclog = UseGCLogFileRotation ?
- new(ResourceObj::C_HEAP, mtInternal)
- rotatingFileStream(Arguments::gc_log_filename()) :
- new(ResourceObj::C_HEAP, mtInternal)
- fileStream(Arguments::gc_log_filename());
+ fileStream * gclog = new(ResourceObj::C_HEAP, mtInternal)
+ gcLogFileStream(Arguments::gc_log_filename());
if (gclog->is_open()) {
// now we update the time stamp of the GC log to be synced up
// with tty.
diff --git a/hotspot/src/share/vm/utilities/ostream.hpp b/hotspot/src/share/vm/utilities/ostream.hpp
index 4d13847663e..9b1b1217b49 100644
--- a/hotspot/src/share/vm/utilities/ostream.hpp
+++ b/hotspot/src/share/vm/utilities/ostream.hpp
@@ -231,20 +231,24 @@ class fdStream : public outputStream {
void flush() {};
};
-class rotatingFileStream : public fileStream {
+class gcLogFileStream : public fileStream {
protected:
- char* _file_name;
+ const char* _file_name;
jlong _bytes_written;
- uintx _cur_file_num; // current logfile rotation number, from 0 to MaxGCLogFileNumbers-1
+ uintx _cur_file_num; // current logfile rotation number, from 0 to NumberOfGCLogFiles-1
public:
- rotatingFileStream(const char* file_name);
- rotatingFileStream(const char* file_name, const char* opentype);
- rotatingFileStream(FILE* file) : fileStream(file) {}
- ~rotatingFileStream();
+ gcLogFileStream(const char* file_name);
+ ~gcLogFileStream();
virtual void write(const char* c, size_t len);
virtual void rotate_log();
+ void dump_loggc_header();
};
+#ifndef PRODUCT
+// unit test for checking -Xloggc: parsing result
+void test_loggc_filename();
+#endif
+
void ostream_init();
void ostream_init_log();
void ostream_exit();
diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp
index b07404dc9b7..79769aeb3bc 100644
--- a/hotspot/src/share/vm/utilities/vmError.cpp
+++ b/hotspot/src/share/vm/utilities/vmError.cpp
@@ -574,6 +574,10 @@ void VMError::report(outputStream* st) {
STEP(120, "(printing native stack)" )
if (_verbose) {
+ if (os::platform_print_native_stack(st, _context, buf, sizeof(buf))) {
+ // We have printed the native stack in platform-specific code
+ // Windows/x64 needs special handling.
+ } else {
frame fr = _context ? os::fetch_frame_from_context(_context)
: os::current_frame();
@@ -604,6 +608,7 @@ void VMError::report(outputStream* st) {
st->cr();
}
}
+ }
STEP(130, "(printing Java stack)" )
diff --git a/hotspot/src/share/vm/utilities/vmError.hpp b/hotspot/src/share/vm/utilities/vmError.hpp
index 1b1608bdc90..299cfaa6f3d 100644
--- a/hotspot/src/share/vm/utilities/vmError.hpp
+++ b/hotspot/src/share/vm/utilities/vmError.hpp
@@ -136,6 +136,10 @@ public:
// check to see if fatal error reporting is in progress
static bool fatal_error_in_progress() { return first_error != NULL; }
+
+ static jlong get_first_error_tid() {
+ return first_error_tid;
+ }
};
#endif // SHARE_VM_UTILITIES_VMERROR_HPP
diff --git a/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp b/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp
index 5a626ce7fa3..98d8f438ea4 100644
--- a/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp
+++ b/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -26,10 +26,7 @@
#define SHARE_VM_UTILITIES_YIELDINGWORKGROUP_HPP
#include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
#include "utilities/workgroup.hpp"
-#endif // INCLUDE_ALL_GCS
-
// Forward declarations
class YieldingFlexibleWorkGang;
diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups
index bf5e3f088fb..bae5a9b3469 100644
--- a/hotspot/test/TEST.groups
+++ b/hotspot/test/TEST.groups
@@ -62,7 +62,7 @@ jdk = \
#
needs_jdk = \
gc/TestG1ZeroPGCTJcmdThreadPrint.java \
- gc/metaspace/ClassMetaspaceSizeInJmapHeap.java \
+ gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java \
gc/metaspace/TestMetaspacePerfCounters.java \
runtime/6819213/TestBootNativeLibraryPath.java \
runtime/6878713/Test6878713.sh \
@@ -84,6 +84,7 @@ needs_jdk = \
runtime/NMT/ThreadedVirtualAllocTestType.java \
runtime/NMT/VirtualAllocTestType.java \
runtime/RedefineObject/TestRedefineObject.java \
+ runtime/XCheckJniJsig/XCheckJSig.java \
serviceability/attach/AttachWithStalePidFile.java
# JRE adds further tests to compact3
@@ -159,7 +160,18 @@ needs_full_vm_compact1 = \
gc/g1/TestRegionAlignment.java \
gc/g1/TestShrinkToOneRegion.java \
gc/metaspace/G1AddMetaspaceDependency.java \
- runtime/6929067/Test6929067.sh
+ gc/startup_warnings/TestCMS.java \
+ gc/startup_warnings/TestCMSIncrementalMode.java \
+ gc/startup_warnings/TestCMSNoIncrementalMode.java \
+ gc/startup_warnings/TestDefaultMaxRAMFraction.java \
+ gc/startup_warnings/TestDefNewCMS.java \
+ gc/startup_warnings/TestIncGC.java \
+ gc/startup_warnings/TestParallelGC.java \
+ gc/startup_warnings/TestParallelScavengeSerialOld.java \
+ gc/startup_warnings/TestParNewCMS.java \
+ gc/startup_warnings/TestParNewSerialOld.java \
+ runtime/6929067/Test6929067.sh \
+ runtime/SharedArchiveFile/SharedArchiveFile.java
# Minimal VM on Compact 2 adds in some compact2 tests
#
diff --git a/hotspot/test/gc/TestObjectAlignment.java b/hotspot/test/gc/TestObjectAlignment.java
new file mode 100644
index 00000000000..8cfc9709f16
--- /dev/null
+++ b/hotspot/test/gc/TestObjectAlignment.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test TestObjectAlignment
+ * @key gc
+ * @bug 8021823
+ * @summary G1: Concurrent marking crashes with -XX:ObjectAlignmentInBytes>=32 in 64bit VMs
+ * @library /testlibrary
+ * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=8
+ * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=16
+ * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=32
+ * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=64
+ * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=128
+ * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=256
+ * @run main/othervm TestObjectAlignment -Xmx20M -XX:-ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=8
+ * @run main/othervm TestObjectAlignment -Xmx20M -XX:-ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=16
+ * @run main/othervm TestObjectAlignment -Xmx20M -XX:-ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=32
+ * @run main/othervm TestObjectAlignment -Xmx20M -XX:-ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=64
+ * @run main/othervm TestObjectAlignment -Xmx20M -XX:-ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=128
+ * @run main/othervm TestObjectAlignment -Xmx20M -XX:-ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=256
+ */
+
+import com.oracle.java.testlibrary.ProcessTools;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class TestObjectAlignment {
+
+ public static byte[] garbage;
+
+ private static boolean runsOn32bit() {
+ return System.getProperty("sun.arch.data.model").equals("32");
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (runsOn32bit()) {
+ // 32 bit VMs do not allow setting ObjectAlignmentInBytes, so there is nothing to test. We still get called.
+ return;
+ }
+ for (int i = 0; i < 10; i++) {
+ garbage = new byte[1000];
+ System.gc();
+ }
+ }
+}
diff --git a/hotspot/test/gc/arguments/TestAlignmentToUseLargePages.java b/hotspot/test/gc/arguments/TestAlignmentToUseLargePages.java
new file mode 100644
index 00000000000..125c1aabd51
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestAlignmentToUseLargePages.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test TestAlignmentToUseLargePages
+ * @summary All parallel GC variants may use large pages without the requirement that the
+ * heap alignment is large page aligned. Other collectors also need to start up with odd sized heaps.
+ * @bug 8024396
+ * @key gc
+ * @key regression
+ * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:-UseParallelOldGC -XX:+UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:-UseParallelOldGC -XX:-UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:-UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms7M -Xmx9M -XX:+UseSerialGC -XX:+UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms7M -Xmx9M -XX:+UseSerialGC -XX:-UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms7M -Xmx9M -XX:+UseConcMarkSweepGC -XX:+UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms7M -Xmx9M -XX:+UseConcMarkSweepGC -XX:-UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms7M -Xmx9M -XX:+UseG1GC -XX:+UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms7M -Xmx9M -XX:+UseG1GC -XX:-UseLargePages TestAlignmentToUseLargePages
+ */
+
+public class TestAlignmentToUseLargePages {
+ public static void main(String args[]) throws Exception {
+ // nothing to do
+ }
+}
diff --git a/hotspot/test/gc/arguments/TestCompressedClassFlags.java b/hotspot/test/gc/arguments/TestCompressedClassFlags.java
new file mode 100644
index 00000000000..4135debd89c
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestCompressedClassFlags.java
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+import com.oracle.java.testlibrary.*;
+
+/*
+ * @test
+ * @bug 8015107
+ * @summary Tests that VM prints a warning when -XX:CompressedClassSpaceSize
+ * is used together with -XX:-UseCompressedClassPointers
+ * @library /testlibrary
+ */
+public class TestCompressedClassFlags {
+ public static void main(String[] args) throws Exception {
+ if (Platform.is64bit()) {
+ OutputAnalyzer output = runJava("-XX:CompressedClassSpaceSize=1g",
+ "-XX:-UseCompressedClassPointers",
+ "-version");
+ output.shouldContain("warning");
+ output.shouldNotContain("error");
+ output.shouldHaveExitValue(0);
+ }
+ }
+
+ private static OutputAnalyzer runJava(String ... args) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
+ return new OutputAnalyzer(pb.start());
+ }
+}
diff --git a/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java b/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java
new file mode 100644
index 00000000000..852076e768e
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+ * @test TestUseCompressedOopsErgo
+ * @key gc
+ * @bug 8010722
+ * @summary Tests ergonomics for UseCompressedOops.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestUseCompressedOopsErgo TestUseCompressedOopsErgoTools
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm TestUseCompressedOopsErgo -XX:+UseG1GC
+ * @run main/othervm TestUseCompressedOopsErgo -XX:+UseParallelGC
+ * @run main/othervm TestUseCompressedOopsErgo -XX:+UseParallelGC -XX:-UseParallelOldGC
+ * @run main/othervm TestUseCompressedOopsErgo -XX:+UseConcMarkSweepGC
+ * @run main/othervm TestUseCompressedOopsErgo -XX:+UseSerialGC
+ */
+
+public class TestUseCompressedOopsErgo {
+
+ public static void main(String args[]) throws Exception {
+ if (!TestUseCompressedOopsErgoTools.is64bitVM()) {
+ // this test is relevant for 64 bit VMs only
+ return;
+ }
+ final String[] gcFlags = args;
+ TestUseCompressedOopsErgoTools.checkCompressedOopsErgo(gcFlags);
+ }
+}
+
diff --git a/hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java b/hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java
new file mode 100644
index 00000000000..54c70672d04
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java
@@ -0,0 +1,177 @@
+/*
+* 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.
+*/
+
+import sun.management.ManagementFactoryHelper;
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import com.oracle.java.testlibrary.*;
+import sun.hotspot.WhiteBox;
+
+class DetermineMaxHeapForCompressedOops {
+ public static void main(String[] args) throws Exception {
+ WhiteBox wb = WhiteBox.getWhiteBox();
+ System.out.print(wb.getCompressedOopsMaxHeapSize());
+ }
+}
+
+class TestUseCompressedOopsErgoTools {
+
+ private static long getCompressedClassSpaceSize() {
+ HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean();
+
+ VMOption option = diagnostic.getVMOption("CompressedClassSpaceSize");
+ return Long.parseLong(option.getValue());
+ }
+
+
+ public static long getMaxHeapForCompressedOops(String[] vmargs) throws Exception {
+ OutputAnalyzer output = runWhiteBoxTest(vmargs, DetermineMaxHeapForCompressedOops.class.getName(), new String[] {}, false);
+ return Long.parseLong(output.getStdout());
+ }
+
+ public static boolean is64bitVM() {
+ String val = System.getProperty("sun.arch.data.model");
+ if (val == null) {
+ throw new RuntimeException("Could not read sun.arch.data.model");
+ }
+ if (val.equals("64")) {
+ return true;
+ } else if (val.equals("32")) {
+ return false;
+ }
+ throw new RuntimeException("Unexpected value " + val + " of sun.arch.data.model");
+ }
+
+ /**
+ * Executes a new VM process with the given class and parameters.
+ * @param vmargs Arguments to the VM to run
+ * @param classname Name of the class to run
+ * @param arguments Arguments to the class
+ * @param useTestDotJavaDotOpts Use test.java.opts as part of the VM argument string
+ * @return The OutputAnalyzer with the results for the invocation.
+ */
+ public static OutputAnalyzer runWhiteBoxTest(String[] vmargs, String classname, String[] arguments, boolean useTestDotJavaDotOpts) throws Exception {
+ ArrayList finalargs = new ArrayList();
+
+ String[] whiteboxOpts = new String[] {
+ "-Xbootclasspath/a:.",
+ "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
+ "-cp", System.getProperty("java.class.path"),
+ };
+
+ if (useTestDotJavaDotOpts) {
+ // System.getProperty("test.java.opts") is '' if no options is set,
+ // we need to skip such a result
+ String[] externalVMOpts = new String[0];
+ if (System.getProperty("test.java.opts") != null && System.getProperty("test.java.opts").length() != 0) {
+ externalVMOpts = System.getProperty("test.java.opts").split(" ");
+ }
+ finalargs.addAll(Arrays.asList(externalVMOpts));
+ }
+
+ finalargs.addAll(Arrays.asList(vmargs));
+ finalargs.addAll(Arrays.asList(whiteboxOpts));
+ finalargs.add(classname);
+ finalargs.addAll(Arrays.asList(arguments));
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(finalargs.toArray(new String[0]));
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldHaveExitValue(0);
+ return output;
+ }
+
+ private static String[] join(String[] part1, String part2) {
+ ArrayList result = new ArrayList();
+ result.addAll(Arrays.asList(part1));
+ result.add(part2);
+ return result.toArray(new String[0]);
+ }
+
+ public static void checkCompressedOopsErgo(String[] gcflags) throws Exception {
+ long maxHeapForCompressedOops = getMaxHeapForCompressedOops(gcflags);
+
+ checkUseCompressedOops(gcflags, maxHeapForCompressedOops, true);
+ checkUseCompressedOops(gcflags, maxHeapForCompressedOops - 1, true);
+ checkUseCompressedOops(gcflags, maxHeapForCompressedOops + 1, false);
+
+ // the use of HeapBaseMinAddress should not change the outcome
+ checkUseCompressedOops(join(gcflags, "-XX:HeapBaseMinAddress=32G"), maxHeapForCompressedOops, true);
+ checkUseCompressedOops(join(gcflags, "-XX:HeapBaseMinAddress=32G"), maxHeapForCompressedOops - 1, true);
+ checkUseCompressedOops(join(gcflags, "-XX:HeapBaseMinAddress=32G"), maxHeapForCompressedOops + 1, false);
+
+ // use a different object alignment
+ maxHeapForCompressedOops = getMaxHeapForCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"));
+
+ checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops, true);
+ checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops - 1, true);
+ checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops + 1, false);
+
+ // use a different CompressedClassSpaceSize
+ String compressedClassSpaceSizeArg = "-XX:CompressedClassSpaceSize=" + 2 * getCompressedClassSpaceSize();
+ maxHeapForCompressedOops = getMaxHeapForCompressedOops(join(gcflags, compressedClassSpaceSizeArg));
+
+ checkUseCompressedOops(join(gcflags, compressedClassSpaceSizeArg), maxHeapForCompressedOops, true);
+ checkUseCompressedOops(join(gcflags, compressedClassSpaceSizeArg), maxHeapForCompressedOops - 1, true);
+ checkUseCompressedOops(join(gcflags, compressedClassSpaceSizeArg), maxHeapForCompressedOops + 1, false);
+ }
+
+ private static void checkUseCompressedOops(String[] args, long heapsize, boolean expectUseCompressedOops) throws Exception {
+ ArrayList finalargs = new ArrayList();
+ finalargs.addAll(Arrays.asList(args));
+ finalargs.add("-Xmx" + heapsize);
+ finalargs.add("-XX:+PrintFlagsFinal");
+ finalargs.add("-version");
+
+ String output = expectValid(finalargs.toArray(new String[0]));
+
+ boolean actualUseCompressedOops = getFlagBoolValue(" UseCompressedOops", output);
+
+ Asserts.assertEQ(expectUseCompressedOops, actualUseCompressedOops);
+ }
+
+ private static boolean getFlagBoolValue(String flag, String where) {
+ Matcher m = Pattern.compile(flag + "\\s+:?= (true|false)").matcher(where);
+ if (!m.find()) {
+ throw new RuntimeException("Could not find value for flag " + flag + " in output string");
+ }
+ return m.group(1).equals("true");
+ }
+
+ private static String expect(String[] flags, boolean hasWarning, boolean hasError, int errorcode) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flags);
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldHaveExitValue(errorcode);
+ return output.getStdout();
+ }
+
+ private static String expectValid(String[] flags) throws Exception {
+ return expect(flags, false, false, 0);
+ }
+}
+
diff --git a/hotspot/test/gc/metaspace/ClassMetaspaceSizeInJmapHeap.java b/hotspot/test/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java
similarity index 83%
rename from hotspot/test/gc/metaspace/ClassMetaspaceSizeInJmapHeap.java
rename to hotspot/test/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java
index b3258466a2d..8152a9eb1ca 100644
--- a/hotspot/test/gc/metaspace/ClassMetaspaceSizeInJmapHeap.java
+++ b/hotspot/test/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java
@@ -22,11 +22,11 @@
*/
/*
- * @test ClassMetaspaceSizeInJmapHeap
+ * @test CompressedClassSpaceSizeInJmapHeap
* @bug 8004924
- * @summary Checks that jmap -heap contains the flag ClassMetaspaceSize
+ * @summary Checks that jmap -heap contains the flag CompressedClassSpaceSize
* @library /testlibrary
- * @run main/othervm -XX:ClassMetaspaceSize=50m ClassMetaspaceSizeInJmapHeap
+ * @run main/othervm -XX:CompressedClassSpaceSize=50m CompressedClassSpaceSizeInJmapHeap
*/
import com.oracle.java.testlibrary.*;
@@ -35,7 +35,7 @@ import java.io.File;
import java.nio.charset.Charset;
import java.util.List;
-public class ClassMetaspaceSizeInJmapHeap {
+public class CompressedClassSpaceSizeInJmapHeap {
public static void main(String[] args) throws Exception {
String pid = Integer.toString(ProcessTools.getProcessId());
@@ -44,16 +44,16 @@ public class ClassMetaspaceSizeInJmapHeap {
.addToolArg(pid);
ProcessBuilder pb = new ProcessBuilder(jmap.getCommand());
- File out = new File("ClassMetaspaceSizeInJmapHeap.stdout.txt");
+ File out = new File("CompressedClassSpaceSizeInJmapHeap.stdout.txt");
pb.redirectOutput(out);
- File err = new File("ClassMetaspaceSizeInJmapHeap.stderr.txt");
+ File err = new File("CompressedClassSpaceSizeInJmapHeap.stderr.txt");
pb.redirectError(err);
run(pb);
OutputAnalyzer output = new OutputAnalyzer(read(out));
- output.shouldContain("ClassMetaspaceSize = 52428800 (50.0MB)");
+ output.shouldContain("CompressedClassSpaceSize = 52428800 (50.0MB)");
out.delete();
}
diff --git a/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java b/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java
index 440f91cbd85..bf9e74c8ab0 100644
--- a/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java
+++ b/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java
@@ -22,55 +22,35 @@
*/
import java.util.List;
-import java.lang.management.ManagementFactory;
-import java.lang.management.MemoryManagerMXBean;
-import java.lang.management.MemoryPoolMXBean;
-import java.lang.management.MemoryUsage;
-
-import java.lang.management.RuntimeMXBean;
-import java.lang.management.ManagementFactory;
+import java.lang.management.*;
+import com.oracle.java.testlibrary.*;
+import static com.oracle.java.testlibrary.Asserts.*;
/* @test TestMetaspaceMemoryPool
* @bug 8000754
* @summary Tests that a MemoryPoolMXBeans is created for metaspace and that a
* MemoryManagerMXBean is created.
+ * @library /testlibrary
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops TestMetaspaceMemoryPool
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:MaxMetaspaceSize=60m TestMetaspaceMemoryPool
- * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers TestMetaspaceMemoryPool
- * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:ClassMetaspaceSize=60m TestMetaspaceMemoryPool
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers TestMetaspaceMemoryPool
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:CompressedClassSpaceSize=60m TestMetaspaceMemoryPool
*/
public class TestMetaspaceMemoryPool {
public static void main(String[] args) {
verifyThatMetaspaceMemoryManagerExists();
- verifyMemoryPool(getMemoryPool("Metaspace"), isFlagDefined("MaxMetaspaceSize"));
- if (runsOn64bit()) {
- if (usesCompressedOops()) {
+ boolean isMetaspaceMaxDefined = InputArguments.containsPrefix("-XX:MaxMetaspaceSize");
+ verifyMemoryPool(getMemoryPool("Metaspace"), isMetaspaceMaxDefined);
+
+ if (Platform.is64bit()) {
+ if (InputArguments.contains("-XX:+UseCompressedOops")) {
MemoryPoolMXBean cksPool = getMemoryPool("Compressed Class Space");
verifyMemoryPool(cksPool, true);
}
}
}
- private static boolean runsOn64bit() {
- return !System.getProperty("sun.arch.data.model").equals("32");
- }
-
- private static boolean usesCompressedOops() {
- return isFlagDefined("+UseCompressedOops");
- }
-
- private static boolean isFlagDefined(String name) {
- RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
- List args = runtimeMxBean.getInputArguments();
- for (String arg : args) {
- if (arg.startsWith("-XX:" + name)) {
- return true;
- }
- }
- return false;
- }
-
private static void verifyThatMetaspaceMemoryManagerExists() {
List managers = ManagementFactory.getMemoryManagerMXBeans();
for (MemoryManagerMXBean manager : managers) {
@@ -95,32 +75,19 @@ public class TestMetaspaceMemoryPool {
private static void verifyMemoryPool(MemoryPoolMXBean pool, boolean isMaxDefined) {
MemoryUsage mu = pool.getUsage();
- assertDefined(mu.getInit(), "init");
- assertDefined(mu.getUsed(), "used");
- assertDefined(mu.getCommitted(), "committed");
+ long init = mu.getInit();
+ long used = mu.getUsed();
+ long committed = mu.getCommitted();
+ long max = mu.getMax();
+
+ assertGTE(init, 0L);
+ assertGTE(used, init);
+ assertGTE(committed, used);
if (isMaxDefined) {
- assertDefined(mu.getMax(), "max");
+ assertGTE(max, committed);
} else {
- assertUndefined(mu.getMax(), "max");
- }
- }
-
- private static void assertDefined(long value, String name) {
- assertTrue(value != -1, "Expected " + name + " to be defined");
- }
-
- private static void assertUndefined(long value, String name) {
- assertEquals(value, -1, "Expected " + name + " to be undefined");
- }
-
- private static void assertEquals(long actual, long expected, String msg) {
- assertTrue(actual == expected, msg);
- }
-
- private static void assertTrue(boolean condition, String msg) {
- if (!condition) {
- throw new RuntimeException(msg);
+ assertEQ(max, -1L);
}
}
}
diff --git a/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java b/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java
index 26934249a7c..974066cba56 100644
--- a/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java
+++ b/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java
@@ -33,13 +33,13 @@ import static com.oracle.java.testlibrary.Asserts.*;
* @summary Tests that performance counters for metaspace and compressed class
* space exists and works.
*
- * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseSerialGC TestMetaspacePerfCounters
- * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseParallelGC -XX:+UseParallelOldGC TestMetaspacePerfCounters
- * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseG1GC TestMetaspacePerfCounters
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseSerialGC TestMetaspacePerfCounters
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseParallelGC -XX:+UseParallelOldGC TestMetaspacePerfCounters
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseG1GC TestMetaspacePerfCounters
*
- * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseSerialGC TestMetaspacePerfCounters
- * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseParallelGC -XX:+UseParallelOldGC TestMetaspacePerfCounters
- * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseG1GC TestMetaspacePerfCounters
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:+UsePerfData -XX:+UseSerialGC TestMetaspacePerfCounters
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:+UsePerfData -XX:+UseParallelGC -XX:+UseParallelOldGC TestMetaspacePerfCounters
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:+UsePerfData -XX:+UseG1GC TestMetaspacePerfCounters
*/
public class TestMetaspacePerfCounters {
public static Class fooClass = null;
@@ -61,10 +61,15 @@ public class TestMetaspacePerfCounters {
}
private static void checkPerfCounters(String ns) throws Exception {
- for (PerfCounter counter : countersInNamespace(ns)) {
- String msg = "Expected " + counter.getName() + " to be larger than 0";
- assertGT(counter.longValue(), 0L, msg);
- }
+ long minCapacity = getMinCapacity(ns);
+ long maxCapacity = getMaxCapacity(ns);
+ long capacity = getCapacity(ns);
+ long used = getUsed(ns);
+
+ assertGTE(minCapacity, 0L);
+ assertGTE(used, minCapacity);
+ assertGTE(capacity, used);
+ assertGTE(maxCapacity, capacity);
}
private static void checkEmptyPerfCounters(String ns) throws Exception {
@@ -75,12 +80,10 @@ public class TestMetaspacePerfCounters {
}
private static void checkUsedIncreasesWhenLoadingClass(String ns) throws Exception {
- PerfCounter used = PerfCounters.findByName(ns + ".used");
-
- long before = used.longValue();
+ long before = getUsed(ns);
fooClass = compileAndLoad("Foo", "public class Foo { }");
System.gc();
- long after = used.longValue();
+ long after = getUsed(ns);
assertGT(after, before);
}
@@ -99,6 +102,22 @@ public class TestMetaspacePerfCounters {
}
private static boolean isUsingCompressedClassPointers() {
- return Platform.is64bit() && InputArguments.contains("-XX:+UseCompressedKlassPointers");
+ return Platform.is64bit() && InputArguments.contains("-XX:+UseCompressedClassPointers");
+ }
+
+ private static long getMinCapacity(String ns) throws Exception {
+ return PerfCounters.findByName(ns + ".minCapacity").longValue();
+ }
+
+ private static long getCapacity(String ns) throws Exception {
+ return PerfCounters.findByName(ns + ".capacity").longValue();
+ }
+
+ private static long getMaxCapacity(String ns) throws Exception {
+ return PerfCounters.findByName(ns + ".maxCapacity").longValue();
+ }
+
+ private static long getUsed(String ns) throws Exception {
+ return PerfCounters.findByName(ns + ".used").longValue();
}
}
diff --git a/hotspot/test/gc/metaspace/TestMetaspaceSizeFlags.java b/hotspot/test/gc/metaspace/TestMetaspaceSizeFlags.java
new file mode 100644
index 00000000000..c67b8dc5ce9
--- /dev/null
+++ b/hotspot/test/gc/metaspace/TestMetaspaceSizeFlags.java
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+import com.oracle.java.testlibrary.Asserts;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+/*
+ * @test TestMetaspaceSizeFlags
+ * @key gc
+ * @bug 8024650
+ * @summary Test that metaspace size flags can be set correctly
+ * @library /testlibrary
+ */
+public class TestMetaspaceSizeFlags {
+ public static final long K = 1024L;
+ public static final long M = 1024L * K;
+
+ // HotSpot uses a number of different values to align memory size flags.
+ // This is currently the largest alignment (unless huge large pages are used).
+ public static final long MAX_ALIGNMENT = 32 * M;
+
+ public static void main(String [] args) throws Exception {
+ testMaxMetaspaceSizeEQMetaspaceSize(MAX_ALIGNMENT, MAX_ALIGNMENT);
+ // 8024650: MaxMetaspaceSize was adjusted instead of MetaspaceSize.
+ testMaxMetaspaceSizeLTMetaspaceSize(MAX_ALIGNMENT, MAX_ALIGNMENT * 2);
+ testMaxMetaspaceSizeGTMetaspaceSize(MAX_ALIGNMENT * 2, MAX_ALIGNMENT);
+ testTooSmallInitialMetaspace(0, 0);
+ testTooSmallInitialMetaspace(0, MAX_ALIGNMENT);
+ testTooSmallInitialMetaspace(MAX_ALIGNMENT, 0);
+ }
+
+ private static void testMaxMetaspaceSizeEQMetaspaceSize(long maxMetaspaceSize, long metaspaceSize) throws Exception {
+ MetaspaceFlags mf = runAndGetValue(maxMetaspaceSize, metaspaceSize);
+ Asserts.assertEQ(maxMetaspaceSize, metaspaceSize);
+ Asserts.assertEQ(mf.maxMetaspaceSize, maxMetaspaceSize);
+ Asserts.assertEQ(mf.metaspaceSize, metaspaceSize);
+ }
+
+ private static void testMaxMetaspaceSizeLTMetaspaceSize(long maxMetaspaceSize, long metaspaceSize) throws Exception {
+ MetaspaceFlags mf = runAndGetValue(maxMetaspaceSize, metaspaceSize);
+ Asserts.assertEQ(mf.maxMetaspaceSize, maxMetaspaceSize);
+ Asserts.assertEQ(mf.metaspaceSize, maxMetaspaceSize);
+ }
+
+ private static void testMaxMetaspaceSizeGTMetaspaceSize(long maxMetaspaceSize, long metaspaceSize) throws Exception {
+ MetaspaceFlags mf = runAndGetValue(maxMetaspaceSize, metaspaceSize);
+ Asserts.assertGT(maxMetaspaceSize, metaspaceSize);
+ Asserts.assertGT(mf.maxMetaspaceSize, mf.metaspaceSize);
+ Asserts.assertEQ(mf.maxMetaspaceSize, maxMetaspaceSize);
+ Asserts.assertEQ(mf.metaspaceSize, metaspaceSize);
+ }
+
+ private static void testTooSmallInitialMetaspace(long maxMetaspaceSize, long metaspaceSize) throws Exception {
+ OutputAnalyzer output = run(maxMetaspaceSize, metaspaceSize);
+ output.shouldContain("Too small initial Metaspace size");
+ }
+
+ private static MetaspaceFlags runAndGetValue(long maxMetaspaceSize, long metaspaceSize) throws Exception {
+ OutputAnalyzer output = run(maxMetaspaceSize, metaspaceSize);
+ output.shouldNotMatch("Error occurred during initialization of VM\n.*");
+
+ String stringMaxMetaspaceSize = output.firstMatch(".* MaxMetaspaceSize .* := (\\d+).*", 1);
+ String stringMetaspaceSize = output.firstMatch(".* MetaspaceSize .* := (\\d+).*", 1);
+
+ return new MetaspaceFlags(Long.parseLong(stringMaxMetaspaceSize),
+ Long.parseLong(stringMetaspaceSize));
+ }
+
+ private static OutputAnalyzer run(long maxMetaspaceSize, long metaspaceSize) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:MaxMetaspaceSize=" + maxMetaspaceSize,
+ "-XX:MetaspaceSize=" + metaspaceSize,
+ "-XX:-UseLargePages", // Prevent us from using 2GB large pages on solaris + sparc.
+ "-XX:+PrintFlagsFinal",
+ "-version");
+ return new OutputAnalyzer(pb.start());
+ }
+
+ private static class MetaspaceFlags {
+ public long maxMetaspaceSize;
+ public long metaspaceSize;
+ public MetaspaceFlags(long maxMetaspaceSize, long metaspaceSize) {
+ this.maxMetaspaceSize = maxMetaspaceSize;
+ this.metaspaceSize = metaspaceSize;
+ }
+ }
+}
diff --git a/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java b/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java
new file mode 100644
index 00000000000..e26aa6eee57
--- /dev/null
+++ b/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+import java.util.List;
+import java.lang.management.*;
+
+import com.oracle.java.testlibrary.*;
+import static com.oracle.java.testlibrary.Asserts.*;
+
+/* @test TestPerfCountersAndMemoryPools
+ * @bug 8023476
+ * @summary Tests that a MemoryPoolMXBeans and PerfCounters for metaspace
+ * report the same data.
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData TestPerfCountersAndMemoryPools
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData TestPerfCountersAndMemoryPools
+ */
+public class TestPerfCountersAndMemoryPools {
+ public static void main(String[] args) throws Exception {
+ checkMemoryUsage("Metaspace", "sun.gc.metaspace");
+
+ if (InputArguments.contains("-XX:+UseCompressedKlassPointers") && Platform.is64bit()) {
+ checkMemoryUsage("Compressed Class Space", "sun.gc.compressedclassspace");
+ }
+ }
+
+ private static MemoryUsage getMemoryUsage(String memoryPoolName) {
+ List pools = ManagementFactory.getMemoryPoolMXBeans();
+ for (MemoryPoolMXBean pool : pools) {
+ if (pool.getName().equals(memoryPoolName)) {
+ return pool.getUsage();
+ }
+ }
+
+ throw new RuntimeException("Excpted to find a memory pool with name " +
+ memoryPoolName);
+ }
+
+ private static void checkMemoryUsage(String memoryPoolName, String perfNS)
+ throws Exception {
+ // Need to do a gc before each comparison to update the perf counters
+
+ System.gc();
+ MemoryUsage mu = getMemoryUsage(memoryPoolName);
+ assertEQ(getMinCapacity(perfNS), mu.getInit());
+
+ System.gc();
+ mu = getMemoryUsage(memoryPoolName);
+ assertEQ(getUsed(perfNS), mu.getUsed());
+
+ System.gc();
+ mu = getMemoryUsage(memoryPoolName);
+ assertEQ(getCapacity(perfNS), mu.getCommitted());
+ }
+
+ private static long getMinCapacity(String ns) throws Exception {
+ return PerfCounters.findByName(ns + ".minCapacity").longValue();
+ }
+
+ private static long getCapacity(String ns) throws Exception {
+ return PerfCounters.findByName(ns + ".capacity").longValue();
+ }
+
+ private static long getUsed(String ns) throws Exception {
+ return PerfCounters.findByName(ns + ".used").longValue();
+ }
+}
diff --git a/hotspot/test/runtime/6878713/Test6878713.sh b/hotspot/test/runtime/6878713/Test6878713.sh
deleted file mode 100644
index a2b5b2d2eb7..00000000000
--- a/hotspot/test/runtime/6878713/Test6878713.sh
+++ /dev/null
@@ -1,137 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-
-
-##
-## @test
-## @bug 6878713
-## @bug 7030610
-## @bug 7037122
-## @bug 7123945
-## @summary Verifier heap corruption, relating to backward jsrs
-## @run shell Test6878713.sh
-##
-## some tests require path to find test source dir
-if [ "${TESTSRC}" = "" ]
-then
- TESTSRC=${PWD}
- echo "TESTSRC not set. Using "${TESTSRC}" as default"
-fi
-echo "TESTSRC=${TESTSRC}"
-## Adding common setup Variables for running shell tests.
-. ${TESTSRC}/../../test_env.sh
-
-TARGET_CLASS=OOMCrashClass1960_2
-
-echo "INFO: extracting the target class."
-${COMPILEJAVA}${FS}bin${FS}jar xvf \
- ${TESTSRC}${FS}testcase.jar ${TARGET_CLASS}.class
-
-# remove any hs_err_pid that might exist here
-rm -f hs_err_pid*.log
-
-echo "INFO: checking for 32-bit versus 64-bit VM."
-${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version 2>&1 \
- | grep "64-Bit [^ ][^ ]* VM" > /dev/null 2>&1
-status="$?"
-if [ "$status" = 0 ]; then
- echo "INFO: testing a 64-bit VM."
- is_64_bit=true
-else
- echo "INFO: testing a 32-bit VM."
-fi
-
-if [ "$is_64_bit" = true ]; then
- # limit is 768MB in 8-byte words (1024 * 1024 * 768 / 8) == 100663296
- MALLOC_MAX=100663296
-else
- # limit is 768MB in 4-byte words (1024 * 1024 * 768 / 4) == 201326592
- MALLOC_MAX=201326592
-fi
-echo "INFO: MALLOC_MAX=$MALLOC_MAX"
-
-echo "INFO: executing the target class."
-# -XX:+PrintCommandLineFlags for debugging purposes
-# -XX:+IgnoreUnrecognizedVMOptions so test will run on a VM without
-# the new -XX:MallocMaxTestWords option
-# -XX:+UnlockDiagnosticVMOptions so we can use -XX:MallocMaxTestWords
-# -XX:MallocMaxTestWords limits malloc to $MALLOC_MAX
-${TESTJAVA}${FS}bin${FS}java \
- -XX:+PrintCommandLineFlags \
- -XX:+IgnoreUnrecognizedVMOptions \
- -XX:+UnlockDiagnosticVMOptions \
- -XX:MallocMaxTestWords=$MALLOC_MAX \
- ${TESTVMOPTS} ${TARGET_CLASS} > test.out 2>&1
-
-echo "INFO: begin contents of test.out:"
-cat test.out
-echo "INFO: end contents of test.out."
-
-echo "INFO: checking for memory allocation error message."
-# We are looking for this specific memory allocation failure mesg so
-# we know we exercised the right allocation path with the test class:
-MESG1="Native memory allocation (malloc) failed to allocate 25696531[0-9][0-9] bytes"
-grep "$MESG1" test.out
-status="$?"
-if [ "$status" = 0 ]; then
- echo "INFO: found expected memory allocation error message."
-else
- echo "INFO: did not find expected memory allocation error message."
-
- # If we didn't find MESG1 above, then there are several scenarios:
- # 1) -XX:MallocMaxTestWords is not supported by the current VM and we
- # didn't fail TARGET_CLASS's memory allocation attempt; instead
- # we failed to find TARGET_CLASS's main() method. The TARGET_CLASS
- # is designed to provoke a memory allocation failure during class
- # loading; we actually don't care about running the class which is
- # why it doesn't have a main() method.
- # 2) we failed a memory allocation, but not the one we were looking
- # so it might be that TARGET_CLASS no longer tickles the same
- # memory allocation code path
- # 3) TARGET_CLASS reproduces the failure mode (SIGSEGV) fixed by
- # 6878713 because the test is running on a pre-fix VM.
- echo "INFO: checking for no main() method message."
- MESG2="Error: Main method not found in class"
- grep "$MESG2" test.out
- status="$?"
- if [ "$status" = 0 ]; then
- echo "INFO: found no main() method message."
- else
- echo "FAIL: did not find no main() method message."
- # status is non-zero for exit below
-
- if [ -s hs_err_pid*.log ]; then
- echo "INFO: begin contents of hs_err_pid file:"
- cat hs_err_pid*.log
- echo "INFO: end contents of hs_err_pid file."
- fi
- fi
-fi
-
-if [ "$status" = 0 ]; then
- echo "PASS: test found one of the expected messages."
-fi
-exit "$status"
diff --git a/hotspot/test/runtime/7020373/Test7020373.sh b/hotspot/test/runtime/7020373/Test7020373.sh
deleted file mode 100644
index 83b7028c82f..00000000000
--- a/hotspot/test/runtime/7020373/Test7020373.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh
-
-##
-## @test
-## @bug 7020373 7055247 7053586 7185550
-## @key cte_test
-## @summary JSR rewriting can overflow memory address size variables
-## @ignore Ignore it as 7053586 test uses lots of memory. See bug report for detail.
-## @run shell Test7020373.sh
-##
-
-if [ "${TESTSRC}" = "" ]
-then
- TESTSRC=${PWD}
- echo "TESTSRC not set. Using "${TESTSRC}" as default"
-fi
-echo "TESTSRC=${TESTSRC}"
-## Adding common setup Variables for running shell tests.
-. ${TESTSRC}/../../test_env.sh
-
-${COMPILEJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar
-
-${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} OOMCrashClass4000_1 > test.out 2>&1
-
-cat test.out
-
-egrep "SIGSEGV|An unexpected error has been detected" test.out
-
-if [ $? = 0 ]
-then
- echo "Test Failed"
- exit 1
-else
- egrep "java.lang.LinkageError|java.lang.NoSuchMethodError|Main method not found in class OOMCrashClass4000_1|insufficient memory" test.out
- if [ $? = 0 ]
- then
- echo "Test Passed"
- exit 0
- else
- echo "Test Failed"
- exit 1
- fi
-fi
diff --git a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java
index 4ce2e82c771..c32c05ebd27 100644
--- a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java
+++ b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8003424
- * @summary Testing UseCompressedKlassPointers with CDS
+ * @summary Testing UseCompressedClassPointers with CDS
* @library /testlibrary
* @run main CDSCompressedKPtrs
*/
@@ -36,7 +36,7 @@ public class CDSCompressedKPtrs {
ProcessBuilder pb;
if (Platform.is64bit()) {
pb = ProcessTools.createJavaProcessBuilder(
- "-XX:+UseCompressedKlassPointers", "-XX:+UseCompressedOops",
+ "-XX:+UseCompressedClassPointers", "-XX:+UseCompressedOops",
"-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
try {
@@ -44,7 +44,7 @@ public class CDSCompressedKPtrs {
output.shouldHaveExitValue(0);
pb = ProcessTools.createJavaProcessBuilder(
- "-XX:+UseCompressedKlassPointers", "-XX:+UseCompressedOops",
+ "-XX:+UseCompressedClassPointers", "-XX:+UseCompressedOops",
"-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
output = new OutputAnalyzer(pb.start());
output.shouldContain("sharing");
diff --git a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java
index b2cb84ac988..05b4ac9af28 100644
--- a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java
+++ b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8003424
- * @summary Test that cannot use CDS if UseCompressedKlassPointers is turned off.
+ * @summary Test that cannot use CDS if UseCompressedClassPointers is turned off.
* @library /testlibrary
* @run main CDSCompressedKPtrsError
*/
@@ -36,7 +36,7 @@ public class CDSCompressedKPtrsError {
ProcessBuilder pb;
if (Platform.is64bit()) {
pb = ProcessTools.createJavaProcessBuilder(
- "-XX:+UseCompressedOops", "-XX:+UseCompressedKlassPointers", "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+UseCompressedOops", "-XX:+UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
try {
@@ -44,21 +44,21 @@ public class CDSCompressedKPtrsError {
output.shouldHaveExitValue(0);
pb = ProcessTools.createJavaProcessBuilder(
- "-XX:-UseCompressedKlassPointers", "-XX:-UseCompressedOops",
+ "-XX:-UseCompressedClassPointers", "-XX:-UseCompressedOops",
"-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
output = new OutputAnalyzer(pb.start());
output.shouldContain("Unable to use shared archive");
output.shouldHaveExitValue(0);
pb = ProcessTools.createJavaProcessBuilder(
- "-XX:-UseCompressedKlassPointers", "-XX:+UseCompressedOops",
+ "-XX:-UseCompressedClassPointers", "-XX:+UseCompressedOops",
"-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
output = new OutputAnalyzer(pb.start());
output.shouldContain("Unable to use shared archive");
output.shouldHaveExitValue(0);
pb = ProcessTools.createJavaProcessBuilder(
- "-XX:+UseCompressedKlassPointers", "-XX:-UseCompressedOops",
+ "-XX:+UseCompressedClassPointers", "-XX:-UseCompressedOops",
"-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
output = new OutputAnalyzer(pb.start());
output.shouldContain("Unable to use shared archive");
@@ -71,19 +71,19 @@ public class CDSCompressedKPtrsError {
// Test bad options with -Xshare:dump.
pb = ProcessTools.createJavaProcessBuilder(
- "-XX:-UseCompressedOops", "-XX:+UseCompressedKlassPointers", "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:-UseCompressedOops", "-XX:+UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
output = new OutputAnalyzer(pb.start());
output.shouldContain("Cannot dump shared archive");
pb = ProcessTools.createJavaProcessBuilder(
- "-XX:+UseCompressedOops", "-XX:-UseCompressedKlassPointers", "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+UseCompressedOops", "-XX:-UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
output = new OutputAnalyzer(pb.start());
output.shouldContain("Cannot dump shared archive");
pb = ProcessTools.createJavaProcessBuilder(
- "-XX:-UseCompressedOops", "-XX:-UseCompressedKlassPointers", "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:-UseCompressedOops", "-XX:-UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
output = new OutputAnalyzer(pb.start());
output.shouldContain("Cannot dump shared archive");
diff --git a/hotspot/test/runtime/ClassFile/JsrRewriting.java b/hotspot/test/runtime/ClassFile/JsrRewriting.java
new file mode 100644
index 00000000000..856658f9bf3
--- /dev/null
+++ b/hotspot/test/runtime/ClassFile/JsrRewriting.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+
+/*
+ * @test JsrRewriting
+ * @summary JSR (jump local subroutine)
+ * rewriting can overflow memory address size variables
+ * @bug 7020373
+ * @bug 7055247
+ * @bug 7053586
+ * @bug 7185550
+ * @bug 7149464
+ * @key cte_test
+ * @library /testlibrary
+ * @run main JsrRewriting
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.io.File;
+
+public class JsrRewriting {
+
+ public static void main(String[] args) throws Exception {
+
+ // ======= Configure the test
+ String jarFile = System.getProperty("test.src") +
+ File.separator + "JsrRewritingTestCase.jar";
+ String className = "OOMCrashClass4000_1";
+
+ // limit is 768MB in native words
+ int mallocMaxTestWords = (1024 * 1024 * 768 / 4);
+ if (Platform.is64bit())
+ mallocMaxTestWords = (mallocMaxTestWords / 2);
+
+ // ======= extract the test class
+ ProcessBuilder pb = new ProcessBuilder(new String[] {
+ JDKToolFinder.getJDKTool("jar"),
+ "xvf", jarFile } );
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldHaveExitValue(0);
+
+ // ======= execute the test
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-cp", ".",
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:MallocMaxTestWords=" + mallocMaxTestWords,
+ className);
+
+ output = new OutputAnalyzer(pb.start());
+ String[] expectedMsgs = {
+ "java.lang.LinkageError",
+ "java.lang.NoSuchMethodError",
+ "Main method not found in class " + className,
+ "insufficient memory"
+ };
+
+ MultipleOrMatch(output, expectedMsgs);
+ }
+
+ private static void
+ MultipleOrMatch(OutputAnalyzer analyzer, String[] whatToMatch) {
+ String output = analyzer.getOutput();
+
+ for (String expected : whatToMatch)
+ if (output.contains(expected))
+ return;
+
+ String err =
+ " stdout: [" + analyzer.getOutput() + "];\n" +
+ " exitValue = " + analyzer.getExitValue() + "\n";
+ System.err.println(err);
+
+ StringBuilder msg = new StringBuilder("Output did not contain " +
+ "any of the following expected messages: \n");
+ for (String expected : whatToMatch)
+ msg.append(expected).append(System.lineSeparator());
+ throw new RuntimeException(msg.toString());
+ }
+}
+
diff --git a/hotspot/test/runtime/7020373/testcase.jar b/hotspot/test/runtime/ClassFile/JsrRewritingTestCase.jar
similarity index 100%
rename from hotspot/test/runtime/7020373/testcase.jar
rename to hotspot/test/runtime/ClassFile/JsrRewritingTestCase.jar
diff --git a/hotspot/test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java b/hotspot/test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java
new file mode 100644
index 00000000000..ad08b183e59
--- /dev/null
+++ b/hotspot/test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+
+/*
+ * @test OomWhileParsingRepeatedJsr
+ * @summary Testing class file parser; specifically parsing
+ * a file with repeated JSR (jump local subroutine)
+ * bytecode command.
+ * @bug 6878713
+ * @bug 7030610
+ * @bug 7037122
+ * @bug 7123945
+ * @bug 8016029
+ * @library /testlibrary
+ * @run main OomWhileParsingRepeatedJsr
+ */
+
+import com.oracle.java.testlibrary.*;
+
+
+public class OomWhileParsingRepeatedJsr {
+
+ public static void main(String[] args) throws Exception {
+
+ // ======= Configure the test
+ String jarFile = System.getProperty("test.src") + "/testcase.jar";
+ String className = "OOMCrashClass1960_2";
+
+ // limit is 768MB in native words
+ int mallocMaxTestWords = (1024 * 1024 * 768 / 4);
+ if (Platform.is64bit())
+ mallocMaxTestWords = (mallocMaxTestWords / 2);
+
+ // ======= extract the test class
+ ProcessBuilder pb = new ProcessBuilder(new String[] {
+ JDKToolFinder.getJDKTool("jar"),
+ "xvf", jarFile } );
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldHaveExitValue(0);
+
+ // ======= execute the test
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-cp", ".",
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:MallocMaxTestWords=" + mallocMaxTestWords,
+ className );
+
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Cannot reserve enough memory");
+ }
+}
+
diff --git a/hotspot/test/runtime/6878713/testcase.jar b/hotspot/test/runtime/ClassFile/testcase.jar
similarity index 100%
rename from hotspot/test/runtime/6878713/testcase.jar
rename to hotspot/test/runtime/ClassFile/testcase.jar
diff --git a/hotspot/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java b/hotspot/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java
index dd0c26d9f10..228d8cb6a7a 100644
--- a/hotspot/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java
+++ b/hotspot/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java
@@ -25,7 +25,7 @@
* @test
* @bug 8000968
* @key regression
- * @summary NPG: UseCompressedKlassPointers asserts with ObjectAlignmentInBytes=32
+ * @summary NPG: UseCompressedClassPointers asserts with ObjectAlignmentInBytes=32
* @library /testlibrary
*/
@@ -52,7 +52,7 @@ public class CompressedKlassPointerAndOops {
OutputAnalyzer output;
pb = ProcessTools.createJavaProcessBuilder(
- "-XX:+UseCompressedKlassPointers",
+ "-XX:+UseCompressedClassPointers",
"-XX:+UseCompressedOops",
"-XX:ObjectAlignmentInBytes=" + alignment,
"-version");
diff --git a/hotspot/test/runtime/InitialThreadOverflow/testme.sh b/hotspot/test/runtime/InitialThreadOverflow/testme.sh
index 015a6bd43b1..b7154dc2abd 100644
--- a/hotspot/test/runtime/InitialThreadOverflow/testme.sh
+++ b/hotspot/test/runtime/InitialThreadOverflow/testme.sh
@@ -43,9 +43,9 @@ then
exit 0
fi
-gcc_cmd=`which gcc`
-if [ "x$gcc_cmd" == "x" ]; then
- echo "WARNING: gcc not found. Cannot execute test." 2>&1
+gcc_cmd=`which g++`
+if [ "x$gcc_cmd" = "x" ]; then
+ echo "WARNING: g++ not found. Cannot execute test." 2>&1
exit 0;
fi
diff --git a/hotspot/test/testlibrary/OutputAnalyzerTest.java b/hotspot/test/testlibrary/OutputAnalyzerTest.java
index 6117e9000bd..2fd677783a8 100644
--- a/hotspot/test/testlibrary/OutputAnalyzerTest.java
+++ b/hotspot/test/testlibrary/OutputAnalyzerTest.java
@@ -172,5 +172,22 @@ public class OutputAnalyzerTest {
} catch (RuntimeException e) {
// expected
}
+
+ {
+ String aaaa = "aaaa";
+ String result = output.firstMatch(aaaa);
+ if (!aaaa.equals(result)) {
+ throw new Exception("firstMatch(String) faild to match. Expected: " + aaaa + " got: " + result);
+ }
+ }
+
+ {
+ String aa = "aa";
+ String aa_grouped_aa = aa + "(" + aa + ")";
+ String result = output.firstMatch(aa_grouped_aa, 1);
+ if (!aa.equals(result)) {
+ throw new Exception("firstMatch(String, int) failed to match. Expected: " + aa + " got: " + result);
+ }
+ }
}
}
diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/InputArguments.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/InputArguments.java
index 650d6c23390..6f40b4050be 100644
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/InputArguments.java
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/InputArguments.java
@@ -41,6 +41,9 @@ public class InputArguments {
/**
* Returns true if {@code arg} is an input argument to the VM.
*
+ * This is useful for checking boolean flags such as -XX:+UseSerialGC or
+ * -XX:-UsePerfData.
+ *
* @param arg The name of the argument.
* @return {@code true} if the given argument is an input argument,
* otherwise {@code false}.
@@ -48,4 +51,26 @@ public class InputArguments {
public static boolean contains(String arg) {
return args.contains(arg);
}
+
+ /**
+ * Returns true if {@code prefix} is the start of an input argument to the
+ * VM.
+ *
+ * This is useful for checking if flags describing a quantity, such as
+ * -XX:+MaxMetaspaceSize=100m, is set without having to know the quantity.
+ * To check if the flag -XX:MaxMetaspaceSize is set, use
+ * {@code InputArguments.containsPrefix("-XX:MaxMetaspaceSize")}.
+ *
+ * @param prefix The start of the argument.
+ * @return {@code true} if the given argument is the start of an input
+ * argument, otherwise {@code false}.
+ */
+ public static boolean containsPrefix(String prefix) {
+ for (String arg : args) {
+ if (arg.startsWith(prefix)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java
index 91ad6a8c8a9..6434135c108 100644
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java
@@ -23,28 +23,84 @@
package com.oracle.java.testlibrary;
-import java.io.File;
+import java.io.FileNotFoundException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
public final class JDKToolFinder {
- private JDKToolFinder() {
- }
-
- /**
- * Returns the full path to an executable in jdk/bin based on System property
- * test.jdk (set by jtreg test suite)
- *
- * @return Full path to an executable in jdk/bin
- */
- public static String getJDKTool(String tool) {
- String binPath = System.getProperty("test.jdk");
- if (binPath == null) {
- throw new RuntimeException("System property 'test.jdk' not set. This property is normally set by jtreg. "
- + "When running test separately, set this property using '-Dtest.jdk=/path/to/jdk'.");
+ private JDKToolFinder() {
}
- binPath += File.separatorChar + "bin" + File.separatorChar + tool;
+ /**
+ * 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) {
- return binPath;
- }
+ // 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();
+ }
}
diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java
index b9e37128d23..73b65165e91 100644
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java
@@ -211,13 +211,13 @@ public final class OutputAnalyzer {
if (matcher.find()) {
reportDiagnosticSummary();
throw new RuntimeException("'" + pattern
- + "' found in stdout \n");
+ + "' found in stdout: '" + matcher.group() + "' \n");
}
matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
if (matcher.find()) {
reportDiagnosticSummary();
throw new RuntimeException("'" + pattern
- + "' found in stderr \n");
+ + "' found in stderr: '" + matcher.group() + "' \n");
}
}
@@ -253,6 +253,37 @@ public final class OutputAnalyzer {
}
}
+ /**
+ * 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(stderr);
+ Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
+ 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
*
diff --git a/hotspot/test/testlibrary/ctw/Makefile b/hotspot/test/testlibrary/ctw/Makefile
new file mode 100644
index 00000000000..5bca7754c69
--- /dev/null
+++ b/hotspot/test/testlibrary/ctw/Makefile
@@ -0,0 +1,73 @@
+#
+# 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.
+#
+#
+
+ifneq "x$(ALT_BOOTDIR)" "x"
+ BOOTDIR := $(ALT_BOOTDIR)
+endif
+
+ifeq "x$(BOOTDIR)" "x"
+ JDK_HOME := $(shell dirname $(shell which java))/..
+else
+ JDK_HOME := $(BOOTDIR)
+endif
+
+SRC_DIR = src
+BUILD_DIR = build
+OUTPUT_DIR = $(BUILD_DIR)/classes
+WHITEBOX_DIR = ../whitebox
+
+JAVAC = $(JDK_HOME)/bin/javac
+JAR = $(JDK_HOME)/bin/jar
+
+SRC_FILES = $(shell find $(SRC_DIR) -name '*.java')
+
+MAIN_CLASS = sun.hotspot.tools.ctw.CompileTheWorld
+
+.PHONY: clean cleantmp
+
+all: ctw.jar cleantmp
+
+clean: cleantmp
+ @rm -rf ctw.jar wb.jar
+
+cleantmp:
+ @rm -rf filelist manifest.mf
+ @rm -rf $(BUILD_DIR)
+
+ctw.jar: filelist wb.jar manifest.mf
+ @mkdir -p $(OUTPUT_DIR)
+ $(JAVAC) -sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) -cp wb.jar @filelist
+ $(JAR) cfm ctw.jar manifest.mf -C $(OUTPUT_DIR) .
+
+wb.jar:
+ make -C ${WHITEBOX_DIR} wb.jar
+ cp ${WHITEBOX_DIR}/wb.jar ./
+ make -C ${WHITEBOX_DIR} clean
+
+filelist: $(SRC_FILES)
+ @rm -f $@
+ @echo $(SRC_FILES) > $@
+
+manifest.mf:
+ @echo "Main-Class: ${MAIN_CLASS}" > manifest.mf
diff --git a/hotspot/test/testlibrary/ctw/README b/hotspot/test/testlibrary/ctw/README
new file mode 100644
index 00000000000..babb0816229
--- /dev/null
+++ b/hotspot/test/testlibrary/ctw/README
@@ -0,0 +1,93 @@
+#
+# 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.
+#
+#
+
+DESCRIPTION
+
+This is replacement for CompileTheWorld (CTW) written on java. Its purpose is
+to make possible the use of CTW in product builds.
+
+DEPENDENCES
+
+The tool depends on Whitebox API. Assumed, that the sources of whitebox are
+located in '../whitebox' directory.
+
+BUILDING
+
+Simple way to build, just type 'make'.
+
+Makefile uses environment variables 'ALT_BOOTDIR', 'BOOTDIR' as root-dir of jdk
+that will be used for compilation and creating jar.
+
+On successful building 'ctw.jar' will be created.
+
+RUNNING
+
+Since the tool uses WhiteBox API, options 'UnlockDiagnosticVMOptions' and
+'WhiteBoxAPI' should be specified, and 'wb.jar' should be added to
+boot-classpath:
+ $ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar
+
+Arguments can be paths to '.jar, '.zip', '.lst' files or directories with
+classes, that define which classes will be compiled:
+ - '.jar', '.zip' files and directories are interpreted like in classpath
+(including '/*' syntax)
+ - '.lst' files -- files with class names (in java notation) to compile.
+CTW will try to find these classes with default class loader, so they should
+be located in classpath.
+
+Without arguments it would work as old version of CTW: all classes in
+boot-classpath will be compiled, excluding classes in 'rt.jar' if 'rt.jar' isn't
+first in boot-classpath.
+
+Due CTW's flags also are not available in product builds, the tool uses
+properties with the same names:
+ - 'CompileTheWorldPreloadClasses' -- type:boolean, default:true, description:
+Preload all classes used by a class before start loading
+ - 'CompileTheWorldStartAt' -- type:long, default:1, description: First class
+to consider
+ - 'CompileTheWorldStopAt' -- type:long, default:Long.MAX_VALUE, description:
+Last class to consider
+
+Also it uses additional properties:
+ - 'sun.hotspot.tools.ctw.verbose' -- type:boolean, default:false,
+description: Verbose output, adds additional information about compilation
+ - 'sun.hotspot.tools.ctw.logfile' -- type:string, default:null,
+description: Path to logfile, if it's null, cout will be used.
+
+EXAMPLES
+
+compile classes from 'rt.jar':
+ $ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar ${JAVA_HOME}/jre/lib/rt.jar
+
+compile classes from all '.jar' in './testjars' directory:
+ $ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar ./testjars/*
+
+compile classes from './build/classes' directory:
+ $ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar ./build/classes
+
+compile only java.lang.String, java.lang.Object classes:
+ $ echo java.lang.String > classes.lst
+ $ echo java.lang.Object >> classes.lst
+ $ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar classes.lst
+
diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java
new file mode 100644
index 00000000000..3ee3526568d
--- /dev/null
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java
@@ -0,0 +1,117 @@
+/*
+ * 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 sun.hotspot.tools.ctw;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Set;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.concurrent.Executor;
+
+import java.io.*;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+
+/**
+ * * Handler for dirs containing classes to compile.
+ * @author igor.ignatyev@oracle.com
+ */
+public class ClassPathDirEntry extends PathHandler {
+
+ private final int rootLength = root.toString().length();
+
+ public ClassPathDirEntry(Path root, Executor executor) {
+ super(root, executor);
+ try {
+ URL url = root.toUri().toURL();
+ setLoader(new URLClassLoader(new URL[]{url}));
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void process() {
+ System.out.println("# dir: " + root);
+ if (!Files.exists(root)) {
+ return;
+ }
+ try {
+ Files.walkFileTree(root, EnumSet.of(FileVisitOption.FOLLOW_LINKS),
+ Integer.MAX_VALUE, new CompileFileVisitor());
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+
+ private void processFile(Path file) {
+ if (Utils.isClassFile(file.toString())) {
+ processClass(pathToClassName(file));
+ }
+ }
+
+ private String pathToClassName(Path file) {
+ String fileString;
+ if (root == file) {
+ fileString = file.normalize().toString();
+ } else {
+ fileString = file.normalize().toString().substring(rootLength + 1);
+ }
+ return Utils.fileNameToClassName(fileString);
+ }
+
+ private class CompileFileVisitor extends SimpleFileVisitor {
+
+ private final Set ready = new HashSet<>();
+
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir,
+ BasicFileAttributes attrs) throws IOException {
+ if (ready.contains(dir)) {
+ return FileVisitResult.SKIP_SUBTREE;
+ }
+ ready.add(dir);
+ return super.preVisitDirectory(dir, attrs);
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file,
+ BasicFileAttributes attrs) throws IOException {
+ if (!ready.contains(file)) {
+ processFile(file);
+ }
+ return isFinished() ? FileVisitResult.TERMINATE
+ : FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFileFailed(Path file,
+ IOException exc) throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
+ }
+}
+
diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java
new file mode 100644
index 00000000000..3d39f1b2573
--- /dev/null
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java
@@ -0,0 +1,81 @@
+/*
+ * 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 sun.hotspot.tools.ctw;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.*;
+import java.util.jar.*;
+import java.util.concurrent.Executor;
+
+import java.io.*;
+import java.nio.file.*;
+
+/**
+ * Handler for jar-files containing classes to compile.
+ * @author igor.ignatyev@oracle.com
+ */
+public class ClassPathJarEntry extends PathHandler {
+
+ public ClassPathJarEntry(Path root, Executor executor) {
+ super(root, executor);
+ try {
+ URL url = root.toUri().toURL();
+ setLoader(new URLClassLoader(new URL[]{url}));
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void process() {
+ System.out.println("# jar: " + root);
+ if (!Files.exists(root)) {
+ return;
+ }
+ try {
+ JarFile jarFile = new JarFile(root.toFile());
+ JarEntry entry;
+ for (Enumeration e = jarFile.entries();
+ e.hasMoreElements(); ) {
+ entry = e.nextElement();
+ processJarEntry(entry);
+ if (isFinished()) {
+ return;
+ }
+ }
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+
+ private void processJarEntry(JarEntry entry) {
+ String filename = entry.getName();
+ if (Utils.isClassFile(filename)) {
+ processClass(Utils.fileNameToClassName(filename));
+ }
+ }
+}
+
diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java
new file mode 100644
index 00000000000..328280a2d88
--- /dev/null
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java
@@ -0,0 +1,62 @@
+/*
+ * 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 sun.hotspot.tools.ctw;
+
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.concurrent.Executor;
+
+/**
+ * Handler for dirs containing jar-files with classes to compile.
+ *
+ * @author igor.ignatyev@oracle.com
+ */
+public class ClassPathJarInDirEntry extends PathHandler {
+
+ public ClassPathJarInDirEntry(Path root, Executor executor) {
+ super(root, executor);
+ }
+
+ @Override
+ public void process() {
+ System.out.println("# jar_in_dir: " + root);
+ if (!Files.exists(root)) {
+ return;
+ }
+ try (DirectoryStream ds
+ = Files.newDirectoryStream(root, "*.jar")) {
+ for (Path p : ds) {
+ new ClassPathJarEntry(p, executor).process();
+ if (isFinished()) {
+ return;
+ }
+ }
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+}
+
diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java
new file mode 100644
index 00000000000..6f36d8b5c6d
--- /dev/null
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java
@@ -0,0 +1,61 @@
+/*
+ * 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 sun.hotspot.tools.ctw;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.concurrent.Executor;
+
+/**
+ * Handler for files containing a list of classes to compile.
+ *
+ * @author igor.ignatyev@oracle.com
+ */
+public class ClassesListInFile extends PathHandler {
+ public ClassesListInFile(Path root, Executor executor) {
+ super(root, executor);
+ }
+
+ @Override
+ public void process() {
+ System.out.println("# list: " + root);
+ if (!Files.exists(root)) {
+ return;
+ }
+ try {
+ try (BufferedReader reader = Files.newBufferedReader(root,
+ StandardCharsets.UTF_8)) {
+ String line;
+ while (!isFinished() && ((line = reader.readLine()) != null)) {
+ processClass(line);
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java
new file mode 100644
index 00000000000..f1d46526d31
--- /dev/null
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java
@@ -0,0 +1,175 @@
+/*
+ * 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 sun.hotspot.tools.ctw;
+
+import sun.management.ManagementFactoryHelper;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import java.util.List;
+import java.util.concurrent.*;
+
+/**
+ * @author igor.ignatyev@oracle.com
+ */
+public class CompileTheWorld {
+ /**
+ * Entry point. Compiles classes in {@code args}, or all classes in
+ * boot-classpath if args is empty
+ *
+ * @param args paths to jar/zip, dir contains classes, or to .lst file
+ * contains list of classes to compile
+ */
+ public static void main(String[] args) {
+ String logfile = Utils.LOG_FILE;
+ PrintStream os = null;
+ if (logfile != null) {
+ try {
+ os = new PrintStream(Files.newOutputStream(Paths.get(logfile)));
+ } catch (IOException io) {
+ }
+ }
+ if (os != null) {
+ System.setOut(os);
+ }
+
+ try {
+ try {
+ if (ManagementFactoryHelper.getCompilationMXBean() == null) {
+ throw new RuntimeException(
+ "CTW can not work in interpreted mode");
+ }
+ } catch (java.lang.NoClassDefFoundError e) {
+ // compact1, compact2 support
+ }
+ String[] paths = args;
+ boolean skipRtJar = false;
+ if (args.length == 0) {
+ paths = getDefaultPaths();
+ skipRtJar = true;
+ }
+ ExecutorService executor = createExecutor();
+ long start = System.currentTimeMillis();
+ try {
+ String path;
+ for (int i = 0, n = paths.length; i < n
+ && !PathHandler.isFinished(); ++i) {
+ path = paths[i];
+ if (skipRtJar && i > 0 && isRtJar(path)) {
+ // rt.jar is not first, so skip it
+ continue;
+ }
+ PathHandler.create(path, executor).process();
+ }
+ } finally {
+ await(executor);
+ }
+ System.out.printf("Done (%d classes, %d methods, %d ms)%n",
+ Compiler.getClassCount(),
+ Compiler.getMethodCount(),
+ System.currentTimeMillis() - start);
+ } finally {
+ if (os != null) {
+ os.close();
+ }
+ }
+ }
+
+ private static ExecutorService createExecutor() {
+ final int threadsCount = Math.min(
+ Runtime.getRuntime().availableProcessors(),
+ Utils.CI_COMPILER_COUNT);
+ ExecutorService result;
+ if (threadsCount > 1) {
+ result = new ThreadPoolExecutor(threadsCount, threadsCount,
+ /* keepAliveTime */ 0L, TimeUnit.MILLISECONDS,
+ new ArrayBlockingQueue<>(threadsCount),
+ new ThreadPoolExecutor.CallerRunsPolicy());
+ } else {
+ result = new CurrentThreadExecutor();
+ }
+ return result;
+ }
+
+ private static String[] getDefaultPaths() {
+ String property = System.getProperty("sun.boot.class.path");
+ System.out.println(
+ "# use 'sun.boot.class.path' as args: " + property);
+ return Utils.PATH_SEPARATOR.split(property);
+ }
+
+ private static void await(ExecutorService executor) {
+ executor.shutdown();
+ while (!executor.isTerminated()) {
+ try {
+ executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ break;
+ }
+ }
+ }
+
+ private static boolean isRtJar(String path) {
+ return Utils.endsWithIgnoreCase(path, File.separator + "rt.jar");
+ }
+
+ private static class CurrentThreadExecutor extends AbstractExecutorService {
+ private boolean isShutdown;
+
+ @Override
+ public void shutdown() {
+ this.isShutdown = true;
+ }
+
+ @Override
+ public List shutdownNow() {
+ return null;
+ }
+
+ @Override
+ public boolean isShutdown() {
+ return isShutdown;
+ }
+
+ @Override
+ public boolean isTerminated() {
+ return isShutdown;
+ }
+
+ @Override
+ public boolean awaitTermination(long timeout, TimeUnit unit)
+ throws InterruptedException {
+ return isShutdown;
+ }
+
+ @Override
+ public void execute(Runnable command) {
+ command.run();
+ }
+ }
+}
+
diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java
new file mode 100644
index 00000000000..ccb2d3ae53a
--- /dev/null
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java
@@ -0,0 +1,235 @@
+/*
+ * 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 sun.hotspot.tools.ctw;
+
+import sun.hotspot.WhiteBox;
+import sun.misc.SharedSecrets;
+import sun.reflect.ConstantPool;
+
+import java.lang.reflect.Executable;
+
+import java.util.Objects;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Provide method to compile whole class.
+ * Also contains compiled methods and classes counters.
+ *
+ * @author igor.ignatyev@oracle.com
+ */
+public class Compiler {
+ private Compiler() { }
+ private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
+ private static final AtomicLong CLASS_COUNT = new AtomicLong(0L);
+ private static final AtomicLong METHOD_COUNT = new AtomicLong(0L);
+ private static volatile boolean CLASSES_LIMIT_REACHED = false;
+
+ /**
+ * @return count of processed classes
+ */
+ public static long getClassCount() {
+ return CLASS_COUNT.get();
+ }
+
+ /**
+ * @return count of processed methods
+ */
+ public static long getMethodCount() {
+ return METHOD_COUNT.get();
+ }
+
+ /**
+ * @return {@code true} if classes limit is reached
+ */
+ public static boolean isLimitReached() {
+ return CLASSES_LIMIT_REACHED;
+ }
+
+ /**
+ * Compiles all methods and constructors.
+ *
+ * @param aClass class to compile
+ * @param executor executor used for compile task invocation
+ * @throws NullPointerException if {@code class} or {@code executor}
+ * is {@code null}
+ */
+ public static void compileClass(Class aClass, Executor executor) {
+ Objects.requireNonNull(aClass);
+ Objects.requireNonNull(executor);
+ long id = CLASS_COUNT.incrementAndGet();
+ if (id > Utils.COMPILE_THE_WORLD_STOP_AT) {
+ CLASS_COUNT.decrementAndGet();
+ CLASSES_LIMIT_REACHED = true;
+ return;
+ }
+
+ if (id >= Utils.COMPILE_THE_WORLD_START_AT) {
+ String name = aClass.getName();
+ try {
+ System.out.printf("[%d]\t%s%n", id, name);
+ ConstantPool constantPool = SharedSecrets.getJavaLangAccess().
+ getConstantPool(aClass);
+ if (Utils.COMPILE_THE_WORLD_PRELOAD_CLASSES) {
+ preloadClasses(name, id, constantPool);
+ }
+ long methodCount = 0;
+ for (Executable e : aClass.getDeclaredConstructors()) {
+ ++methodCount;
+ executor.execute(new CompileMethodCommand(id, name, e));
+ }
+ for (Executable e : aClass.getDeclaredMethods()) {
+ ++methodCount;
+ executor.execute(new CompileMethodCommand(id, name, e));
+ }
+ METHOD_COUNT.addAndGet(methodCount);
+
+ if (Utils.DEOPTIMIZE_ALL_CLASSES_RATE > 0
+ && (id % Utils.DEOPTIMIZE_ALL_CLASSES_RATE == 0)) {
+ WHITE_BOX.deoptimizeAll();
+ }
+ } catch (Throwable t) {
+ System.out.printf("[%d]\t%s\tskipping %s%n", id, name, t);
+ t.printStackTrace();
+ }
+ }
+ }
+
+ private static void preloadClasses(String className, long id,
+ ConstantPool constantPool) {
+ try {
+ for (int i = 0, n = constantPool.getSize(); i < n; ++i) {
+ try {
+ constantPool.getClassAt(i);
+ } catch (IllegalArgumentException ignore) {
+ }
+ }
+ } catch (Throwable t) {
+ System.out.printf("[%d]\t%s\tpreloading failed : %s%n", id,
+ className, t);
+ }
+ }
+
+
+
+ /**
+ * Compilation of method.
+ * Will compile method on all available comp levels.
+ */
+ private static class CompileMethodCommand implements Runnable {
+ private final long classId;
+ private final String className;
+ private final Executable method;
+
+ /**
+ * @param classId id of class
+ * @param className name of class
+ * @param method compiled for compilation
+ */
+ public CompileMethodCommand(long classId, String className,
+ Executable method) {
+ this.classId = classId;
+ this.className = className;
+ this.method = method;
+ }
+
+ @Override
+ public final void run() {
+ int compLevel = Utils.INITIAL_COMP_LEVEL;
+ if (Utils.TIERED_COMPILATION) {
+ for (int i = compLevel; i <= Utils.TIERED_STOP_AT_LEVEL; ++i) {
+ WHITE_BOX.deoptimizeMethod(method);
+ compileMethod(method, i);
+ }
+ } else {
+ compileMethod(method, compLevel);
+ }
+ }
+
+ private void waitCompilation() {
+ if (!Utils.BACKGROUND_COMPILATION) {
+ return;
+ }
+ final Object obj = new Object();
+ synchronized (obj) {
+ for (int i = 0;
+ i < 10 && WHITE_BOX.isMethodQueuedForCompilation(method);
+ ++i) {
+ try {
+ obj.wait(1000);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+ }
+
+ private void compileMethod(Executable method, int compLevel) {
+ if (WHITE_BOX.isMethodCompilable(method, compLevel)) {
+ try {
+ WHITE_BOX.enqueueMethodForCompilation(method, compLevel);
+ waitCompilation();
+ int tmp = WHITE_BOX.getMethodCompilationLevel(method);
+ if (tmp != compLevel) {
+ logMethod(method, "compilation level = " + tmp
+ + ", but not " + compLevel);
+ } else if (Utils.IS_VERBOSE) {
+ logMethod(method, "compilation level = " + tmp + ". OK");
+ }
+ } catch (Throwable t) {
+ logMethod(method, "error on compile at " + compLevel
+ + " level");
+ t.printStackTrace();
+ }
+ } else if (Utils.IS_VERBOSE) {
+ logMethod(method, "not compilable at " + compLevel);
+ }
+ }
+
+ private void logMethod(Executable method, String message) {
+ StringBuilder builder = new StringBuilder("[");
+ builder.append(classId);
+ builder.append("]\t");
+ builder.append(className);
+ builder.append("::");
+ builder.append(method.getName());
+ builder.append('(');
+ Class[] params = method.getParameterTypes();
+ for (int i = 0, n = params.length - 1; i < n; ++i) {
+ builder.append(params[i].getName());
+ builder.append(", ");
+ }
+ if (params.length != 0) {
+ builder.append(params[params.length - 1].getName());
+ }
+ builder.append(')');
+ if (message != null) {
+ builder.append('\t');
+ builder.append(message);
+ }
+ System.err.println(builder);
+ }
+ }
+
+}
diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java
new file mode 100644
index 00000000000..5c284f896a8
--- /dev/null
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java
@@ -0,0 +1,149 @@
+/*
+ * 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 sun.hotspot.tools.ctw;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.io.File;
+
+import java.util.Objects;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.util.concurrent.Executor;
+
+/**
+ * Abstract handler for path.
+ *
+ * Concrete subclasses should implement method {@link #process()}.
+ *
+ * @author igor.ignatyev@oracle.com
+ */
+public abstract class PathHandler {
+ private static final Pattern JAR_IN_DIR_PATTERN
+ = Pattern.compile("^(.*[/\\\\])?\\*$");
+ protected final Path root;
+ protected final Executor executor;
+ private ClassLoader loader;
+
+ /**
+ * @param root root path to process
+ * @param executor executor used for process task invocation
+ * @throws NullPointerException if {@code root} or {@code executor} is
+ * {@code null}
+ */
+ protected PathHandler(Path root, Executor executor) {
+ Objects.requireNonNull(root);
+ Objects.requireNonNull(executor);
+ this.root = root.normalize();
+ this.executor = executor;
+ this.loader = ClassLoader.getSystemClassLoader();
+ }
+
+ /**
+ * Factory method. Construct concrete handler in depends from {@code path}.
+ *
+ * @param path the path to process
+ * @param executor executor used for compile task invocation
+ * @throws NullPointerException if {@code path} or {@code executor} is
+ * {@code null}
+ */
+ public static PathHandler create(String path, Executor executor) {
+ Objects.requireNonNull(path);
+ Objects.requireNonNull(executor);
+ Matcher matcher = JAR_IN_DIR_PATTERN.matcher(path);
+ if (matcher.matches()) {
+ path = matcher.group(1);
+ path = path.isEmpty() ? "." : path;
+ return new ClassPathJarInDirEntry(Paths.get(path), executor);
+ } else {
+ path = path.isEmpty() ? "." : path;
+ Path p = Paths.get(path);
+ if (isJarFile(p)) {
+ return new ClassPathJarEntry(p, executor);
+ } else if (isListFile(p)) {
+ return new ClassesListInFile(p, executor);
+ } else {
+ return new ClassPathDirEntry(p, executor);
+ }
+ }
+ }
+
+ private static boolean isJarFile(Path path) {
+ if (Files.isRegularFile(path)) {
+ String name = path.toString();
+ return Utils.endsWithIgnoreCase(name, ".zip")
+ || Utils.endsWithIgnoreCase(name, ".jar");
+ }
+ return false;
+ }
+
+ private static boolean isListFile(Path path) {
+ if (Files.isRegularFile(path)) {
+ String name = path.toString();
+ return Utils.endsWithIgnoreCase(name, ".lst");
+ }
+ return false;
+ }
+
+ /**
+ * Processes all classes in specified path.
+ */
+ public abstract void process();
+
+ /**
+ * Sets class loader, that will be used to define class at
+ * {@link #processClass(String)}.
+ *
+ * @param loader class loader
+ * @throws NullPointerException if {@code loader} is {@code null}
+ */
+ protected final void setLoader(ClassLoader loader) {
+ Objects.requireNonNull(loader);
+ this.loader = loader;
+ }
+
+ /**
+ * Processes specificed class.
+ * @param name fully qualified name of class to process
+ */
+ protected final void processClass(String name) {
+ try {
+ Class aClass = Class.forName(name, true, loader);
+ Compiler.compileClass(aClass, executor);
+ } catch (ClassNotFoundException | LinkageError e) {
+ System.out.printf("Class %s loading failed : %s%n", name,
+ e.getMessage());
+ }
+ }
+
+ /**
+ * @return {@code true} if processing should be stopped
+ */
+ public static boolean isFinished() {
+ return Compiler.isLimitReached();
+ }
+
+}
+
diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java
new file mode 100644
index 00000000000..5ffd06cee8b
--- /dev/null
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java
@@ -0,0 +1,215 @@
+/*
+ * 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 sun.hotspot.tools.ctw;
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import sun.management.ManagementFactoryHelper;
+
+import java.io.File;
+import java.util.regex.Pattern;
+
+/**
+ * Auxiliary methods.
+ *
+ * @author igor.ignatyev@oracle.com
+ */
+public class Utils {
+ /**
+ * Value of {@code -XX:CompileThreshold}
+ */
+ public static final boolean TIERED_COMPILATION
+ = Boolean.parseBoolean(getVMOption("TieredCompilation", "false"));
+ /**
+ * Value of {@code -XX:BackgroundCompilation}
+ */
+ public static final boolean BACKGROUND_COMPILATION
+ = Boolean.parseBoolean(getVMOption("BackgroundCompilation",
+ "false"));
+ /**
+ * Value of {@code -XX:TieredStopAtLevel}
+ */
+ public static final int TIERED_STOP_AT_LEVEL;
+ /**
+ * Value of {@code -XX:CICompilerCount}
+ */
+ public static final Integer CI_COMPILER_COUNT
+ = Integer.valueOf(getVMOption("CICompilerCount", "1"));
+ /**
+ * Initial compilation level.
+ */
+ public static final int INITIAL_COMP_LEVEL;
+ /**
+ * Compiled path-separator regexp.
+ */
+ public static final Pattern PATH_SEPARATOR = Pattern.compile(
+ File.pathSeparator, Pattern.LITERAL);
+ /**
+ * Value of {@code -DDeoptimizeAllClassesRate}. Frequency of
+ * {@code WB.deoptimizeAll()} invocation If it less that {@code 0},
+ * {@code WB.deoptimizeAll()} will not be invoked.
+ */
+ public static final int DEOPTIMIZE_ALL_CLASSES_RATE
+ = Integer.getInteger("DeoptimizeAllClassesRate", -1);
+ /**
+ * Value of {@code -DCompileTheWorldStopAt}. Last class to consider.
+ */
+ public static final long COMPILE_THE_WORLD_STOP_AT
+ = Long.getLong("CompileTheWorldStopAt", Long.MAX_VALUE);
+ /**
+ * Value of {@code -DCompileTheWorldStartAt}. First class to consider.
+ */
+ public static final long COMPILE_THE_WORLD_START_AT
+ = Long.getLong("CompileTheWorldStartAt", 1);
+ /**
+ * Value of {@code -DCompileTheWorldPreloadClasses}. Preload all classes
+ * used by a class before start loading.
+ */
+ public static final boolean COMPILE_THE_WORLD_PRELOAD_CLASSES;
+ /**
+ * Value of {@code -Dsun.hotspot.tools.ctw.verbose}. Verbose output,
+ * adds additional information about compilation.
+ */
+ public static final boolean IS_VERBOSE
+ = Boolean.getBoolean("sun.hotspot.tools.ctw.verbose");
+ /**
+ * Value of {@code -Dsun.hotspot.tools.ctw.logfile}.Path to logfile, if
+ * it's null, cout will be used.
+ */
+ public static final String LOG_FILE
+ = System.getProperty("sun.hotspot.tools.ctw.logfile");
+ static {
+ if (Utils.TIERED_COMPILATION) {
+ INITIAL_COMP_LEVEL = 1;
+ } else {
+ String vmName = System.getProperty("java.vm.name");
+ if (Utils.endsWithIgnoreCase(vmName, " Server VM")) {
+ INITIAL_COMP_LEVEL = 4;
+ } else if (Utils.endsWithIgnoreCase(vmName, " Client VM")
+ || Utils.endsWithIgnoreCase(vmName, " Minimal VM")) {
+ INITIAL_COMP_LEVEL = 1;
+ } else {
+ throw new RuntimeException("Unknown VM: " + vmName);
+ }
+ }
+
+ TIERED_STOP_AT_LEVEL = Integer.parseInt(getVMOption("TieredStopAtLevel",
+ String.valueOf(INITIAL_COMP_LEVEL)));
+ }
+
+ static {
+ String tmp = System.getProperty("CompileTheWorldPreloadClasses");
+ if (tmp == null) {
+ COMPILE_THE_WORLD_PRELOAD_CLASSES = true;
+ } else {
+ COMPILE_THE_WORLD_PRELOAD_CLASSES = Boolean.parseBoolean(tmp);
+ }
+ }
+
+ public static final String CLASSFILE_EXT = ".class";
+
+ private Utils() {
+ }
+
+ /**
+ * Tests if the string ends with the suffix, ignoring case
+ * considerations
+ *
+ * @param string the tested string
+ * @param suffix the suffix
+ * @return {@code true} if {@code string} ends with the {@code suffix}
+ * @see String#endsWith(String)
+ */
+ public static boolean endsWithIgnoreCase(String string, String suffix) {
+ if (string == null || suffix == null) {
+ return false;
+ }
+ int length = suffix.length();
+ int toffset = string.length() - length;
+ if (toffset < 0) {
+ return false;
+ }
+ return string.regionMatches(true, toffset, suffix, 0, length);
+ }
+
+ /**
+ * Returns value of VM option.
+ *
+ * @param name option's name
+ * @return value of option or {@code null}, if option doesn't exist
+ * @throws NullPointerException if name is null
+ */
+ public static String getVMOption(String name) {
+ String result;
+ HotSpotDiagnosticMXBean diagnostic
+ = ManagementFactoryHelper.getDiagnosticMXBean();
+ result = diagnostic.getVMOption(name).getValue();
+ return result;
+ }
+
+ /**
+ * Returns value of VM option or default value.
+ *
+ * @param name option's name
+ * @param defaultValue default value
+ * @return value of option or {@code defaultValue}, if option doesn't exist
+ * @throws NullPointerException if name is null
+ * @see #getVMOption(String)
+ */
+ public static String getVMOption(String name, String defaultValue) {
+ String result;
+ try {
+ result = getVMOption(name);
+ } catch (NoClassDefFoundError e) {
+ // compact1, compact2 support
+ result = defaultValue;
+ }
+ return result == null ? defaultValue : result;
+ }
+
+ /**
+ * Tests if the filename is valid filename for class file.
+ *
+ * @param filename tested filename
+ */
+ public static boolean isClassFile(String filename) {
+ // If the filename has a period after removing '.class', it's not valid class file
+ return endsWithIgnoreCase(filename, CLASSFILE_EXT)
+ && (filename.indexOf('.')
+ == (filename.length() - CLASSFILE_EXT.length()));
+ }
+
+ /**
+ * Converts the filename to classname.
+ *
+ * @param filename filename to convert
+ * @return corresponding classname.
+ * @throws AssertionError if filename isn't valid filename for class file -
+ * {@link #isClassFile(String)}
+ */
+ public static String fileNameToClassName(String filename) {
+ assert isClassFile(filename);
+ return filename.substring(0, filename.length() - CLASSFILE_EXT.length())
+ .replace(File.separatorChar, '.');
+ }
+}
diff --git a/hotspot/test/testlibrary/ctw/test/Bar.java b/hotspot/test/testlibrary/ctw/test/Bar.java
new file mode 100644
index 00000000000..9b0324555f8
--- /dev/null
+++ b/hotspot/test/testlibrary/ctw/test/Bar.java
@@ -0,0 +1,5 @@
+public class Bar {
+ private static void staticMethod() { }
+ public void method() { }
+ protected Bar() { }
+}
diff --git a/hotspot/test/testlibrary/ctw/test/ClassesDirTest.java b/hotspot/test/testlibrary/ctw/test/ClassesDirTest.java
new file mode 100644
index 00000000000..ae5eaf0f2e4
--- /dev/null
+++ b/hotspot/test/testlibrary/ctw/test/ClassesDirTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test ClassesDirTest
+ * @bug 8012447
+ * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src
+ * @build sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox ClassesDirTest Foo Bar
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar
+ * @run main ClassesDirTest prepare
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld classes
+ * @run main ClassesDirTest check ctw.log
+ * @summary testing of CompileTheWorld :: classes in directory
+ * @author igor.ignatyev@oracle.com
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+
+public class ClassesDirTest extends CtwTest {
+ private static final String[] SHOULD_CONTAIN
+ = {"# dir: classes", "Done (2 classes, 6 methods, "};
+
+ private ClassesDirTest() {
+ super(SHOULD_CONTAIN);
+ }
+
+ public static void main(String[] args) throws Exception {
+ new ClassesDirTest().run(args);
+ }
+
+ protected void prepare() throws Exception {
+ String path = "classes";
+ Files.createDirectory(Paths.get(path));
+ Files.move(Paths.get("Foo.class"), Paths.get(path, "Foo.class"),
+ StandardCopyOption.REPLACE_EXISTING);
+ Files.move(Paths.get("Bar.class"), Paths.get(path, "Bar.class"),
+ StandardCopyOption.REPLACE_EXISTING);
+ }
+}
diff --git a/hotspot/test/testlibrary/ctw/test/ClassesListTest.java b/hotspot/test/testlibrary/ctw/test/ClassesListTest.java
new file mode 100644
index 00000000000..a98cd53a3f6
--- /dev/null
+++ b/hotspot/test/testlibrary/ctw/test/ClassesListTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test ClassesListTest
+ * @bug 8012447
+ * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src
+ * @build sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox ClassesListTest Foo Bar
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar
+ * @run main ClassesListTest prepare
+ * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld classes.lst
+ * @run main ClassesListTest check ctw.log
+ * @summary testing of CompileTheWorld :: list of classes in file
+ * @author igor.ignatyev@oracle.com
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+
+public class ClassesListTest extends CtwTest {
+ private static final String[] SHOULD_CONTAIN
+ = {"# list: classes.lst", "Done (4 classes, "};
+
+ private ClassesListTest() {
+ super(SHOULD_CONTAIN);
+ }
+
+ public static void main(String[] args) throws Exception {
+ new ClassesListTest().run(args);
+ }
+
+ protected void prepare() throws Exception {
+ String path = "classes.lst";
+ Files.copy(Paths.get(System.getProperty("test.src"), path),
+ Paths.get(path), StandardCopyOption.REPLACE_EXISTING);
+ }
+}
diff --git a/hotspot/test/testlibrary/ctw/test/CtwTest.java b/hotspot/test/testlibrary/ctw/test/CtwTest.java
new file mode 100644
index 00000000000..ecc9c59c13a
--- /dev/null
+++ b/hotspot/test/testlibrary/ctw/test/CtwTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+
+import java.util.List;
+import java.util.Collections;
+import java.util.ArrayList;
+
+import java.io.File;
+import java.io.Writer;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.BufferedReader;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.nio.charset.Charset;
+
+import com.oracle.java.testlibrary.JDKToolFinder;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public abstract class CtwTest {
+ protected final String[] shouldContain;
+ protected CtwTest(String[] shouldContain) {
+ this.shouldContain = shouldContain;
+ }
+
+ public void run(String[] args) throws Exception {
+ if (args.length == 0) {
+ throw new Error("args is empty");
+ }
+ switch (args[0]) {
+ case "prepare":
+ prepare();
+ break;
+ case "check":
+ check(args);
+ break;
+ default:
+ throw new Error("unregonized action -- " + args[0]);
+ }
+ }
+
+ protected void prepare() throws Exception { }
+
+ protected void check(String[] args) throws Exception {
+ if (args.length < 2) {
+ throw new Error("logfile isn't specified");
+ }
+ String logfile = args[1];
+ try (BufferedReader r = Files.newBufferedReader(Paths.get(logfile),
+ Charset.defaultCharset())) {
+ OutputAnalyzer output = readOutput(r);
+ for (String test : shouldContain) {
+ output.shouldContain(test);
+ }
+ }
+ }
+
+ private static OutputAnalyzer readOutput(BufferedReader reader)
+ throws IOException {
+ StringBuilder builder = new StringBuilder();
+ String eol = String.format("%n");
+ String line;
+
+ while ((line = reader.readLine()) != null) {
+ builder.append(line);
+ builder.append(eol);
+ }
+ return new OutputAnalyzer(builder.toString(), "");
+ }
+
+ protected void dump(OutputAnalyzer output, String name) {
+ try (Writer w = new FileWriter(name + ".out")) {
+ String s = output.getStdout();
+ w.write(s, s.length(), 0);
+ } catch (IOException io) {
+ io.printStackTrace();
+ }
+ try (Writer w = new FileWriter(name + ".err")) {
+ String s = output.getStderr();
+ w.write(s, s.length(), 0);
+ } catch (IOException io) {
+ io.printStackTrace();
+ }
+ }
+
+ protected ProcessBuilder createJarProcessBuilder(String... command)
+ throws Exception {
+ String javapath = JDKToolFinder.getJDKTool("jar");
+
+ ArrayList args = new ArrayList<>();
+ args.add(javapath);
+ Collections.addAll(args, command);
+
+ return new ProcessBuilder(args.toArray(new String[args.size()]));
+ }
+}
diff --git a/hotspot/test/testlibrary/ctw/test/Foo.java b/hotspot/test/testlibrary/ctw/test/Foo.java
new file mode 100644
index 00000000000..07d8f4643ce
--- /dev/null
+++ b/hotspot/test/testlibrary/ctw/test/Foo.java
@@ -0,0 +1,5 @@
+public class Foo {
+ private static void staticMethod() { }
+ public void method() { }
+ protected Foo() { }
+}
diff --git a/hotspot/test/testlibrary/ctw/test/JarDirTest.java b/hotspot/test/testlibrary/ctw/test/JarDirTest.java
new file mode 100644
index 00000000000..76f682fd755
--- /dev/null
+++ b/hotspot/test/testlibrary/ctw/test/JarDirTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test JarDirTest
+ * @bug 8012447
+ * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src
+ * @build sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox JarDirTest Foo Bar
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar
+ * @run main JarDirTest prepare
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld jars/*
+ * @run main JarDirTest check ctw.log
+ * @summary testing of CompileTheWorld :: jars in directory
+ * @author igor.ignatyev@oracle.com
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class JarDirTest extends CtwTest {
+ private static final String[] SHOULD_CONTAIN
+ = {"# jar_in_dir: jars",
+ "# jar: jars" + File.separator +"foo.jar",
+ "# jar: jars" + File.separator +"bar.jar",
+ "Done (4 classes, 12 methods, "};
+
+ private JarDirTest() {
+ super(SHOULD_CONTAIN);
+ }
+
+ public static void main(String[] args) throws Exception {
+ new JarDirTest().run(args);
+ }
+
+ protected void prepare() throws Exception {
+ String path = "jars";
+ Files.createDirectory(Paths.get(path));
+
+ ProcessBuilder pb = createJarProcessBuilder("cf", "jars/foo.jar",
+ "Foo.class", "Bar.class");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ dump(output, "ctw-foo.jar");
+ output.shouldHaveExitValue(0);
+
+ pb = createJarProcessBuilder("cf", "jars/bar.jar", "Foo.class",
+ "Bar.class");
+ output = new OutputAnalyzer(pb.start());
+ dump(output, "ctw-bar.jar");
+ output.shouldHaveExitValue(0);
+ }
+
+}
diff --git a/hotspot/test/testlibrary/ctw/test/JarsTest.java b/hotspot/test/testlibrary/ctw/test/JarsTest.java
new file mode 100644
index 00000000000..04792729f4e
--- /dev/null
+++ b/hotspot/test/testlibrary/ctw/test/JarsTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test JarsTest
+ * @bug 8012447
+ * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src
+ * @build sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox JarsTest Foo Bar
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar
+ * @run main JarsTest prepare
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld foo.jar bar.jar
+ * @run main JarsTest check ctw.log
+ * @summary testing of CompileTheWorld :: jars
+ * @author igor.ignatyev@oracle.com
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class JarsTest extends CtwTest {
+ private static final String[] SHOULD_CONTAIN
+ = {"# jar: foo.jar", "# jar: bar.jar",
+ "Done (4 classes, 12 methods, "};
+
+ private JarsTest() {
+ super(SHOULD_CONTAIN);
+ }
+
+ public static void main(String[] args) throws Exception {
+ new JarsTest().run(args);
+ }
+
+ protected void prepare() throws Exception {
+ ProcessBuilder pb = createJarProcessBuilder("cf", "foo.jar",
+ "Foo.class", "Bar.class");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ dump(output, "ctw-foo.jar");
+ output.shouldHaveExitValue(0);
+
+ pb = createJarProcessBuilder("cf", "bar.jar", "Foo.class", "Bar.class");
+ output = new OutputAnalyzer(pb.start());
+ dump(output, "ctw-bar.jar");
+ output.shouldHaveExitValue(0);
+ }
+
+}
diff --git a/hotspot/test/testlibrary/ctw/test/classes.lst b/hotspot/test/testlibrary/ctw/test/classes.lst
new file mode 100644
index 00000000000..044c029e783
--- /dev/null
+++ b/hotspot/test/testlibrary/ctw/test/classes.lst
@@ -0,0 +1,4 @@
+java.lang.String
+java.lang.Object
+Foo
+Bar
diff --git a/hotspot/test/testlibrary/whitebox/Makefile b/hotspot/test/testlibrary/whitebox/Makefile
new file mode 100644
index 00000000000..8a84a0a4492
--- /dev/null
+++ b/hotspot/test/testlibrary/whitebox/Makefile
@@ -0,0 +1,63 @@
+#
+# 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.
+#
+#
+
+ifneq "x$(ALT_BOOTDIR)" "x"
+ BOOTDIR := $(ALT_BOOTDIR)
+endif
+
+ifeq "x$(BOOTDIR)" "x"
+ JDK_HOME := $(shell dirname $(shell which java))/..
+else
+ JDK_HOME := $(BOOTDIR)
+endif
+
+SRC_DIR = ./
+BUILD_DIR = build
+OUTPUT_DIR = $(BUILD_DIR)/classes
+
+JAVAC = $(JDK_HOME)/bin/javac
+JAR = $(JDK_HOME)/bin/jar
+
+SRC_FILES = $(shell find $(SRC_DIR) -name '*.java')
+
+.PHONY: filelist clean cleantmp
+
+all: wb.jar cleantmp
+
+wb.jar: filelist
+ @mkdir -p $(OUTPUT_DIR)
+ $(JAVAC) -sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) -cp $(OUTPUT_DIR) @filelist
+ $(JAR) cf wb.jar -C $(OUTPUT_DIR) .
+ @rm -rf $(OUTPUT_DIR)
+
+filelist: $(SRC_FILES)
+ @rm -f $@
+ @echo $(SRC_FILES) > $@
+
+clean: cleantmp
+ @rm -rf wb.jar
+
+cleantmp:
+ @rm -rf filelist
+ @rm -rf $(BUILD_DIR)
diff --git a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java
index c508b8f121a..091b5f7543b 100644
--- a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java
+++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java
@@ -61,6 +61,8 @@ public class WhiteBox {
registerNatives();
}
+ // Get the maximum heap size supporting COOPs
+ public native long getCompressedOopsMaxHeapSize();
// Arguments
public native void printHeapSizes();
diff --git a/jaxp/.hgtags b/jaxp/.hgtags
index e21e3e57573..f3166e9d9df 100644
--- a/jaxp/.hgtags
+++ b/jaxp/.hgtags
@@ -228,3 +228,5 @@ b1ceab582fc6d795b20aaa8a3fde2eba34af9399 jdk8-b103
a22fe9bd01e6c7e7ddc7995dfc9471711692b8d1 jdk8-b104
09a46ec11f880154886c70be03aff5ab2ddf0ab7 jdk8-b105
d3be8e3b429df917e72c1c23e7920c651219b587 jdk8-b106
+d6a32e3831aab20a9a3bc78cdc0a60aaad725c6c jdk8-b107
+8ade3eed63da87067a7137c111f684a821e9e531 jdk8-b108
diff --git a/jaxp/make/jprt.properties b/jaxp/make/jprt.properties
index 360b6b22dba..b03c53ca656 100644
--- a/jaxp/make/jprt.properties
+++ b/jaxp/make/jprt.properties
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 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
@@ -39,8 +39,8 @@ jprt.build.targets= \
solaris_x64_5.10-{product|fastdebug}, \
linux_i586_2.6-{product|fastdebug}, \
linux_x64_2.6-{product|fastdebug}, \
- windows_i586_5.1-{product|fastdebug}, \
- windows_x64_5.2-{product|fastdebug}
+ windows_i586_6.1-{product|fastdebug}, \
+ windows_x64_6.1-{product|fastdebug}
# Directories to be excluded from the source bundles
jprt.bundle.exclude.src.dirs=build dist webrev
diff --git a/jaxws/.hgtags b/jaxws/.hgtags
index d213728514a..6a23622251b 100644
--- a/jaxws/.hgtags
+++ b/jaxws/.hgtags
@@ -228,3 +228,5 @@ b1fb4612a2caea52b5661b87509e560fa044b194 jdk8-b98
42211ab0ab1cca51a050d184634cf1db7ef81fbf jdk8-b104
88390df7ed2cf128298a02c5e6d978f0a603cd58 jdk8-b105
6908370afe834ff01739e8ec992d4246c74b7e6e jdk8-b106
+e3c9328f75638289a342ce15fbe532f05078946e jdk8-b107
+d1ea68556fd7925a3c7078dd9f77c6ca73d5aa9e jdk8-b108
diff --git a/jaxws/make/jprt.properties b/jaxws/make/jprt.properties
index 91064331043..12ce773022a 100644
--- a/jaxws/make/jprt.properties
+++ b/jaxws/make/jprt.properties
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 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
@@ -40,8 +40,8 @@ jprt.build.targets= \
linux_i586_2.6-{product|fastdebug}, \
linux_x64_2.6-{product|fastdebug}, \
macosx_x64_10.7-{product|fastdebug}, \
- windows_i586_5.1-{product|fastdebug}, \
- windows_x64_5.2-{product|fastdebug}
+ windows_i586_6.1-{product|fastdebug}, \
+ windows_x64_6.1-{product|fastdebug}
# Directories to be excluded from the source bundles
jprt.bundle.exclude.src.dirs=build dist webrev
diff --git a/jdk/.hgtags b/jdk/.hgtags
index c20c5cde8f0..6eef7251ea8 100644
--- a/jdk/.hgtags
+++ b/jdk/.hgtags
@@ -228,3 +228,5 @@ e0f6039c0290b7381042a6fec3100a69a5a67e37 jdk8-b103
f1d8d15bfcb5ada858a942f8a31f6598f23214d1 jdk8-b104
1fe211ae3d2b8cc2dfc4f58d9a6eb96418679672 jdk8-b105
c817276bd870dfe1dcc3a3dbbc092436b6907f75 jdk8-b106
+eea685b9ccaa1980e0a7e07d6a3a84bcc7e9ab82 jdk8-b107
+006aaa5f069e7dd98fccdc696866c9f8582c087c jdk8-b108
diff --git a/jdk/make/Makefile b/jdk/make/Makefile
index c2db5a816a2..e82edd7271f 100644
--- a/jdk/make/Makefile
+++ b/jdk/make/Makefile
@@ -99,7 +99,6 @@ COMPILER_PATH.desc = Compiler install directory
CACERTS_FILE.desc = Location of certificates file
DEVTOOLS_PATH.desc = Directory containing zip and unzip
CUPS_HEADERS_PATH.desc = Include directory location for CUPS header files
-DXSDK_PATH.desc = Root directory of DirectX SDK
# Make variables to print out (description and value)
VARIABLE_PRINTVAL_LIST += \
@@ -128,17 +127,6 @@ VARIABLE_CHECKDIR_LIST += \
VARIABLE_CHECKFIL_LIST += \
CACERTS_FILE
-# Some are windows specific
-ifeq ($(PLATFORM), windows)
-
-VARIABLE_PRINTVAL_LIST += \
- DXSDK_PATH
-
-VARIABLE_CHECKDIR_LIST += \
- DXSDK_PATH
-
-endif
-
# For pattern rules below, so all are treated the same
DO_PRINTVAL_LIST=$(VARIABLE_PRINTVAL_LIST:%=%.printval)
DO_CHECKDIR_LIST=$(VARIABLE_CHECKDIR_LIST:%=%.checkdir)
diff --git a/jdk/make/common/Defs-macosx.gmk b/jdk/make/common/Defs-macosx.gmk
index 1b7aaa8ae20..befd2cfed5b 100644
--- a/jdk/make/common/Defs-macosx.gmk
+++ b/jdk/make/common/Defs-macosx.gmk
@@ -397,12 +397,10 @@ else
INCLUDE_SA = true
endif
-ifdef CROSS_COMPILE_ARCH
- # X11 headers are not under /usr/include
- OTHER_CFLAGS += -I$(OPENWIN_HOME)/include
- OTHER_CXXFLAGS += -I$(OPENWIN_HOME)/include
- OTHER_CPPFLAGS += -I$(OPENWIN_HOME)/include
-endif
+# X11 headers are not under /usr/include
+OTHER_CFLAGS += -I$(OPENWIN_HOME)/include
+OTHER_CXXFLAGS += -I$(OPENWIN_HOME)/include
+OTHER_CPPFLAGS += -I$(OPENWIN_HOME)/include
LIB_LOCATION ?= $(LIBDIR)
diff --git a/jdk/make/common/Defs-windows.gmk b/jdk/make/common/Defs-windows.gmk
index c5c15b3d387..ef2c4aeab6f 100644
--- a/jdk/make/common/Defs-windows.gmk
+++ b/jdk/make/common/Defs-windows.gmk
@@ -78,8 +78,6 @@ ifeq ($(COMPILER_VERSION), VS2010)
MS_RUNTIME_LIBRARIES = $(MSVCRNN_DLL)
endif
-EXTRA_LFLAGS += -LIBPATH:$(DXSDK_LIB_PATH)
-
# Full Debug Symbols has been enabled on Windows since JDK1.4.1.
# The Full Debug Symbols (FDS) default for VARIANT == OPT builds is
# enabled with debug info files ZIP'ed to save space. For VARIANT !=
diff --git a/jdk/make/common/Sanity.gmk b/jdk/make/common/Sanity.gmk
index 25f5fa7bfe8..233abeacabb 100644
--- a/jdk/make/common/Sanity.gmk
+++ b/jdk/make/common/Sanity.gmk
@@ -65,7 +65,6 @@ sanity-base: pre-sanity \
sane-libCrun \
sane-unixccs_path \
sane-msdevtools_path \
- sane-dxsdk \
sane-compiler \
sane-cacerts \
sane-ant_version \
diff --git a/jdk/make/common/shared/Defs-versions.gmk b/jdk/make/common/shared/Defs-versions.gmk
index 8a60563c122..a3a53c5c048 100644
--- a/jdk/make/common/shared/Defs-versions.gmk
+++ b/jdk/make/common/shared/Defs-versions.gmk
@@ -74,9 +74,6 @@ endif
# REQUIRED_CYGWIN_VER
# Windows only: If CYGWIN is used, the minimum CYGWIN version.
#
-# REQUIRED_DXSDK_VER
-# Windows only: The version of DirectX SDK expected.
-#
# REQUIRED_FREETYPE_VERSION
# If we are using freetype, the freetype version expected.
#
@@ -193,7 +190,6 @@ ifeq ($(PLATFORM), windows)
REQUIRED_OS_VARIANT_VERSION = $(REQUIRED_OS_VERSION)
REQUIRED_CYGWIN_VER = 4.0
REQUIRED_MKS_VER = 6.1
- REQUIRED_DXSDK_VER = 0x0900
ifeq ($(CC_VERSION),msvc)
REQUIRED_COMPILER_NAME = Visual Studio 10
REQUIRED_COMPILER_VERSION = VS2010
diff --git a/jdk/make/common/shared/Defs-windows.gmk b/jdk/make/common/shared/Defs-windows.gmk
index 40415547d71..d46d884cc05 100644
--- a/jdk/make/common/shared/Defs-windows.gmk
+++ b/jdk/make/common/shared/Defs-windows.gmk
@@ -79,7 +79,7 @@ override INCREMENTAL_BUILD = false
# The ALT values should never really have spaces or use \.
# Suspect these environment variables to have spaces and/or \ characters:
# SYSTEMROOT, SystemRoot, WINDIR, windir, PROGRAMFILES, ProgramFiles,
-# DXSDK_DIR, MSTOOLS, Mstools, MSSDK, MSSdk, VCnnCOMNTOOLS,
+# MSTOOLS, Mstools, MSSDK, MSSdk, VCnnCOMNTOOLS,
# MSVCDIR, MSVCDir.
# So use $(subst \,/,) on them first adding quotes and placing them in
# their own variable assigned with :=, then use FullPath.
@@ -255,18 +255,6 @@ ifneq ($(word 1,$(_program_files)),$(_program_files))
_program_files:=
endif
-# DirectX SDK
-ifdef ALT_DXSDK_DRIVE
- _dx_sdk_dir =$(ALT_DXSDK_DRIVE):/DXSDK
-else
- ifdef DXSDK_DIR
- xDXSDK_DIR :="$(subst \,/,$(DXSDK_DIR))"
- else
- xDXSDK_DIR :="$(_system_drive)/DXSDK"
- endif
- _dx_sdk_dir :=$(call FullPath,$(xDXSDK_DIR))
-endif
-
# Use of the Visual Studio compilers requires certain env variables be set:
# PATH should include the path to cl.exe
# INCLUDE should be defined
@@ -489,39 +477,6 @@ ifeq ($(_NEEDS_MSVCRNN), true)
MSVCRNN_DLL_PATH:=$(call AltCheckValue,MSVCRNN_DLL_PATH)
endif
-# DXSDK_PATH: path to Microsoft DirectX SDK Include and Lib
-ifdef ALT_DXSDK_PATH
- xALT_DXSDK_PATH :="$(subst \,/,$(ALT_DXSDK_PATH))"
- DXSDK_PATH :=$(call FullPath,$(xALT_DXSDK_PATH))
-else
- _DXSDK_PATH1 :=$(_dx_sdk_dir)
- _DXSDK_PATH2 :=$(JDK_DEVTOOLS_DIR)/windows/dxsdk
- DXSDK_PATH :=$(call DirExists,$(_DXSDK_PATH1),$(_DXSDK_PATH2),$(_dx_sdk_dir))
-endif
-DXSDK_PATH :=$(call AltCheckSpaces,DXSDK_PATH)
-DXSDK_PATH:=$(call AltCheckValue,DXSDK_PATH)
-
-# DXSDK_INCLUDE_PATH: path to Microsoft DirectX SDK Include
-ifdef ALT_DXSDK_INCLUDE_PATH
- xALT_DXSDK_INCLUDE_PATH :="$(subst \,/,$(ALT_DXSDK_INCLUDE_PATH))"
- DXSDK_INCLUDE_PATH :=$(call FullPath,$(xALT_DXSDK_INCLUDE_PATH))
-else
- DXSDK_INCLUDE_PATH =$(subst //,/,$(DXSDK_PATH)/Include)
-endif
-
-# DXSDK_LIB_PATH: path to Microsoft DirectX SDK Lib
-ifdef ALT_DXSDK_LIB_PATH
- xALT_DXSDK_LIB_PATH :="$(subst \,/,$(ALT_DXSDK_LIB_PATH))"
- DXSDK_LIB_PATH :=$(call FullPath,$(xALT_DXSDK_LIB_PATH))
-else
- ifeq ($(ARCH_DATA_MODEL), 64)
- # 64bit libs are located in "Lib/x64" subdir
- DXSDK_LIB_PATH =$(subst //,/,$(DXSDK_PATH)/Lib/x64)
- else
- DXSDK_LIB_PATH =$(subst //,/,$(DXSDK_PATH)/Lib)
- endif
-endif
-
# DEPLOY_MSSDK: Microsoft SDK for this platform (for deploy)
ifdef ALT_DEPLOY_MSSDK
xALT_DEPLOY_MSSDK :="$(subst \,/,$(ALT_DEPLOY_MSSDK))"
diff --git a/jdk/make/common/shared/Sanity-Settings.gmk b/jdk/make/common/shared/Sanity-Settings.gmk
index ea32eeadcaa..2ceef21e13e 100644
--- a/jdk/make/common/shared/Sanity-Settings.gmk
+++ b/jdk/make/common/shared/Sanity-Settings.gmk
@@ -234,10 +234,6 @@ endif
ALL_SETTINGS+=$(call addAltSetting,HOTSPOT_SERVER_PATH)
ifeq ($(PLATFORM),windows)
ALL_SETTINGS+=$(call addAltSetting,HOTSPOT_LIB_PATH)
- ALL_SETTINGS+=$(call addRequiredSetting,DXSDK_VER)
- ALL_SETTINGS+=$(call addAltSetting,DXSDK_PATH)
- ALL_SETTINGS+=$(call addAltSetting,DXSDK_INCLUDE_PATH)
- ALL_SETTINGS+=$(call addAltSetting,DXSDK_LIB_PATH)
ALL_SETTINGS+=$(call addAltSetting,WINDOWSSDKDIR)
ALL_SETTINGS+=$(call addRequiredSetting,RC)
ALL_SETTINGS+=$(call addRequiredSetting,REBASE)
diff --git a/jdk/make/common/shared/Sanity.gmk b/jdk/make/common/shared/Sanity.gmk
index c4a96d73c5f..a9f4692064a 100644
--- a/jdk/make/common/shared/Sanity.gmk
+++ b/jdk/make/common/shared/Sanity.gmk
@@ -143,8 +143,6 @@ ifeq ($(PLATFORM), windows)
_CYGWIN_VER := $(SYSTEM_UNAME)
CYGWIN_VER :=$(call GetVersion,$(_CYGWIN_VER))
endif
- DXSDK_VER := $(shell $(EGREP) DIRECT3D_VERSION $(DXSDK_INCLUDE_PATH)/d3d9.h 2>&1 | \
- $(EGREP) "\#define" | $(NAWK) '{print $$3}')
endif
# Get the version numbers of what we are using
@@ -1300,51 +1298,6 @@ sane-unzip_version:
"" >> $(WARNING_FILE) ; \
fi
-######################################################
-# Check for windows DirectX sdk directory
-######################################################
-sane-dxsdk:
-ifeq ($(PLATFORM), windows)
- @if [ ! -r $(DXSDK_INCLUDE_PATH)/d3d9.h ]; then \
- $(ECHO) "ERROR: You do not have access to a valid DirectX SDK Include dir.\n" \
- " The value of DXSDK_INCLUDE_PATH must point a valid DX SDK dir.\n" \
- " Please check your access to \n" \
- " $(DXSDK_INCLUDE_PATH) \n" \
- " and/or check your value of ALT_DXSDK_PATH or ALT_DXSDK_INCLUDE_PATH.\n" \
- " Microsoft DirectX 9 SDK (Summer 2004 Update or newer) can be downloaded from the following location:\n" \
- " http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp\n" \
- " Or http://www.microsoft.com/directx\n" \
- "" >> $(ERROR_FILE) ; \
- else \
- if [ ! "$(DXSDK_VER)" = "$(REQUIRED_DXSDK_VER)" ]; then \
- $(ECHO) "ERROR: The DirectX SDK must be version $(REQUIRED_DXSDK_VER).\n" \
- " $(YOU_ARE_USING) DirectX SDK version: $(DXSDK_VER)\n" \
- " The DirectX SDK was obtained from the following location: \n" \
- " $(DXSDK_PATH) \n" \
- " Please change your DirectX SDK. \n" \
- " Microsoft DirectX 9 SDK (Summer 2004 Update or newer) can be downloaded from the following location:\n" \
- " http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp\n" \
- " Or http://www.microsoft.com/directx\n" \
- "" >> $(ERROR_FILE) ; \
- else \
- if [ -r $(DXSDK_INCLUDE_PATH)/basetsd.h ]; then \
- if [ `$(EGREP) -c __int3264 $(DXSDK_INCLUDE_PATH)/basetsd.h` -ne 0 ]; then \
- $(ECHO) "WARNING: The DirectX SDK Include directory contains a newer basetsd.h,\n" \
- " which may indicate that you're using an incorrect version of DirectX SDK.\n" \
- " This may result in a build failure.\n" \
- " The DirectX SDK Include dir was obtained from the following location:\n" \
- " $(DXSDK_INCLUDE_PATH) \n" \
- " Please change your DirectX SDK to version 9 (Summer 2004 Update or newer).\n" \
- " Microsoft DirectX 9 SDK can be downloaded from the following location:\n" \
- " http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp\n" \
- " Or http://www.microsoft.com/directx\n" \
- "" >> $(WARNING_FILE) ; \
- fi \
- fi \
- fi \
- fi
-endif
-
######################################################
# Check the linker version(s)
######################################################
diff --git a/jdk/make/java/java/Makefile b/jdk/make/java/java/Makefile
index 829cf933001..d2a663f9ae0 100644
--- a/jdk/make/java/java/Makefile
+++ b/jdk/make/java/java/Makefile
@@ -105,6 +105,7 @@ FILES_java += java/util/prefs/MacOSXPreferences.java \
java/util/prefs/MacOSXPreferencesFactory.java
CFLAGS_$(VARIANT)/java_props_md.o = -Os -x objective-c
+CFLAGS_$(VARIANT)/java_props_macosx.o = -Os -x objective-c
endif
#
diff --git a/jdk/make/java/java/genlocales.gmk b/jdk/make/java/java/genlocales.gmk
index 6d35b8e734d..0d52565c9c5 100644
--- a/jdk/make/java/java/genlocales.gmk
+++ b/jdk/make/java/java/genlocales.gmk
@@ -38,31 +38,31 @@ FILES_compiled_properties_orig := $(FILES_compiled_properties)
# only FILES_java and FILES_compiled_properties variables will be picked up
#
# $(BUILDDIR)/java/util/FILES_java.gmk & $(BUILDDIR)/java/util/FILES_properties.gmk
-# contain "sun.util.resources" for US language support
+# contain "sun.util.resources" for EN language support
include $(BUILDDIR)/java/util/FILES_java.gmk
include $(BUILDDIR)/java/util/FILES_properties.gmk
-US_Resources_java := $(FILES_java)
-US_Resources_properties := $(FILES_compiled_properties)
+EN_Resources_java := $(FILES_java)
+EN_Resources_properties := $(FILES_compiled_properties)
# $(BUILDDIR)/java/text/FILES_java.gmk contains the "sun.text.resources" for
-# US language support
+# EN language support
include $(BUILDDIR)/java/text/base/FILES_java.gmk
-US_Resources_java += $(FILES_java)
+EN_Resources_java += $(FILES_java)
FILES_compiled_properties=
# $(BUILDDIR)/sun/text/FILES_java.gmk & $(BUILDDIR)/sun/text/FILES_properties.gmk
-# contain both resources for Non-US language support
+# contain both resources for Non-EN language support
include $(BUILDDIR)/sun/text/FILES_java.gmk
include $(BUILDDIR)/sun/text/FILES_properties.gmk
-NonUS_Resources_java := $(FILES_java)
-NonUS_Resources_properties := $(FILES_compiled_properties)
+NonEN_Resources_java := $(FILES_java)
+NonEN_Resources_properties := $(FILES_compiled_properties)
# Restore the orignal FILES_java & FILES_compiled_properties variables
FILES_java := $(FILES_java_orig)
@@ -80,30 +80,30 @@ RESOURCE_NAMES="FormatData CollationData TimeZoneNames LocaleNames CurrencyNames
ifeq ($(PLATFORM), macosx)
$(LocaleDataMetaInfo_Dest):$(LocaleDataMetaInfo_Src) $(LOCALEGEN_SH)
- @$(RM) $@.tmp.us $@.tmp.nonus;
+ @$(RM) $@.tmp.en $@.tmp.nonen;
@$(prep-target)
- @$(ECHO) $(US_Resources_properties) | $(NAWK) 'gsub(/.properties/,"\n") {print}' > $@.tmp.us;
- @$(ECHO) $(US_Resources_java) | $(NAWK) 'gsub(/.java/,"\n") {print}' >> $@.tmp.us;
- @$(ECHO) $(NonUS_Resources_properties) | $(NAWK) 'gsub(/.properties/,"\n") {print}' > $@.tmp.nonus;
- @$(ECHO) $(NonUS_Resources_java) | $(NAWK) 'gsub(/.java/,"\n") {print}' >> $@.tmp.nonus;
+ @$(ECHO) $(EN_Resources_properties) | $(NAWK) 'gsub(/.properties/,"\n") {print}' > $@.tmp.en;
+ @$(ECHO) $(EN_Resources_java) | $(NAWK) 'gsub(/.java/,"\n") {print}' >> $@.tmp.en;
+ @$(ECHO) $(NonEN_Resources_properties) | $(NAWK) 'gsub(/.properties/,"\n") {print}' > $@.tmp.nonen;
+ @$(ECHO) $(NonEN_Resources_java) | $(NAWK) 'gsub(/.java/,"\n") {print}' >> $@.tmp.nonen;
NAWK="$(NAWK)" SED="$(SED)" SORT="$(SORT)" \
- $(SH) $(LOCALEGEN_SH) $(RESOURCE_NAMES) $@.tmp.us \
- $@.tmp.nonus $< $@
- @$(RM) $@.tmp.us $@.tmp.nonus;
+ $(SH) $(LOCALEGEN_SH) $(RESOURCE_NAMES) $@.tmp.en \
+ $@.tmp.nonen $< $@
+ @$(RM) $@.tmp.en $@.tmp.nonen;
else
$(LocaleDataMetaInfo_Dest):$(LocaleDataMetaInfo_Src) $(LOCALEGEN_SH)
- @$(RM) $@.tmp.us $@.tmp.nonus;
+ @$(RM) $@.tmp.en $@.tmp.nonen;
@$(prep-target)
- @$(ECHO) $(subst .properties,'\n',$(US_Resources_properties)) > $@.tmp.us;
- @$(ECHO) $(subst .java,'\n',$(US_Resources_java)) >> $@.tmp.us;
- @$(ECHO) $(subst .properties,'\n',$(NonUS_Resources_properties)) > $@.tmp.nonus;
- @$(ECHO) $(subst .java,'\n',$(NonUS_Resources_java)) >> $@.tmp.nonus;
+ @$(ECHO) $(subst .properties,'\n',$(EN_Resources_properties)) > $@.tmp.en;
+ @$(ECHO) $(subst .java,'\n',$(EN_Resources_java)) >> $@.tmp.en;
+ @$(ECHO) $(subst .properties,'\n',$(NonEN_Resources_properties)) > $@.tmp.nonen;
+ @$(ECHO) $(subst .java,'\n',$(NonEN_Resources_java)) >> $@.tmp.nonen;
NAWK="$(NAWK)" SED="$(SED)" SORT="$(SORT)" \
- $(SH) $(LOCALEGEN_SH) $(RESOURCE_NAMES) $@.tmp.us \
- $@.tmp.nonus $< $@
- @$(RM) $@.tmp.us $@.tmp.nonus;
+ $(SH) $(LOCALEGEN_SH) $(RESOURCE_NAMES) $@.tmp.en \
+ $@.tmp.nonen $< $@
+ @$(RM) $@.tmp.en $@.tmp.nonen;
endif
genlocales : $(LocaleDataMetaInfo_Dest)
diff --git a/jdk/make/java/java/localegen.sh b/jdk/make/java/java/localegen.sh
index 8fad25ef534..78493d31f95 100644
--- a/jdk/make/java/java/localegen.sh
+++ b/jdk/make/java/java/localegen.sh
@@ -35,11 +35,11 @@
# A list of resource base name list;
RESOURCE_NAMES=$1
-# A list of US resources;
-US_FILES_LIST=$2
+# A list of EN resources;
+EN_FILES_LIST=$2
-# A list of non-US resources;
-NONUS_FILES_LIST=$3
+# A list of non-EN resources;
+NONEN_FILES_LIST=$3
INPUT_FILE=$4
OUTPUT_FILE=$5
@@ -53,23 +53,23 @@ getlocalelist() {
sed_script="$SED -e \"s@^#warn .*@// -- This file was mechanically generated: Do not edit! -- //@\" "
# ja-JP-JP and th-TH-TH need to be manually added, as they don't have any resource files.
-nonusall=" ja-JP-JP th-TH-TH "
+nonenall=" ja-JP-JP th-TH-TH "
for FILE in $RESOURCE_NAMES
do
- getlocalelist $FILE $US_FILES_LIST
- sed_script=$sed_script"-e \"s@#"$FILE"_USLocales#@$localelist@g\" "
- usall=$usall" "$localelist
- getlocalelist $FILE $NONUS_FILES_LIST
- sed_script=$sed_script"-e \"s@#"$FILE"_NonUSLocales#@$localelist@g\" "
- nonusall=$nonusall" "$localelist
+ getlocalelist $FILE $EN_FILES_LIST
+ sed_script=$sed_script"-e \"s@#"$FILE"_ENLocales#@$localelist@g\" "
+ enall=$enall" "$localelist
+ getlocalelist $FILE $NONEN_FILES_LIST
+ sed_script=$sed_script"-e \"s@#"$FILE"_NonENLocales#@$localelist@g\" "
+ nonenall=$nonenall" "$localelist
done
-usall=`(for LOC in $usall; do echo $LOC;done) |$SORT -u`
-nonusall=`(for LOC in $nonusall; do echo $LOC;done) |$SORT -u`
+enall=`(for LOC in $enall; do echo $LOC;done) |$SORT -u`
+nonenall=`(for LOC in $nonenall; do echo $LOC;done) |$SORT -u`
-sed_script=$sed_script"-e \"s@#AvailableLocales_USLocales#@$usall@g\" "
-sed_script=$sed_script"-e \"s@#AvailableLocales_NonUSLocales#@$nonusall@g\" "
+sed_script=$sed_script"-e \"s@#AvailableLocales_ENLocales#@$enall@g\" "
+sed_script=$sed_script"-e \"s@#AvailableLocales_NonENLocales#@$nonenall@g\" "
sed_script=$sed_script"$INPUT_FILE > $OUTPUT_FILE"
eval $sed_script
diff --git a/jdk/make/java/text/base/FILES_java.gmk b/jdk/make/java/text/base/FILES_java.gmk
index c2e0f479c6b..47abc6ff095 100644
--- a/jdk/make/java/text/base/FILES_java.gmk
+++ b/jdk/make/java/text/base/FILES_java.gmk
@@ -107,5 +107,17 @@ FILES_java = \
sun/text/resources/FormatData.java \
sun/text/resources/JavaTimeSupplementary.java \
sun/text/resources/en/FormatData_en.java \
+ sun/text/resources/en/FormatData_en_AU.java \
+ sun/text/resources/en/FormatData_en_CA.java \
+ sun/text/resources/en/FormatData_en_GB.java \
+ sun/text/resources/en/FormatData_en_IE.java \
+ sun/text/resources/en/FormatData_en_IN.java \
+ sun/text/resources/en/FormatData_en_MT.java \
+ sun/text/resources/en/FormatData_en_NZ.java \
+ sun/text/resources/en/FormatData_en_PH.java \
+ sun/text/resources/en/FormatData_en_SG.java \
sun/text/resources/en/FormatData_en_US.java \
+ sun/text/resources/en/FormatData_en_ZA.java \
sun/text/resources/en/JavaTimeSupplementary_en.java \
+ sun/text/resources/en/JavaTimeSupplementary_en_GB.java \
+ sun/text/resources/en/JavaTimeSupplementary_en_SG.java
diff --git a/jdk/make/java/util/FILES_java.gmk b/jdk/make/java/util/FILES_java.gmk
index 677a97c52cb..75bbe38031c 100644
--- a/jdk/make/java/util/FILES_java.gmk
+++ b/jdk/make/java/util/FILES_java.gmk
@@ -30,4 +30,7 @@ FILES_java = \
sun/util/resources/LocaleNamesBundle.java \
sun/util/resources/TimeZoneNamesBundle.java \
sun/util/resources/TimeZoneNames.java \
- sun/util/resources/en/TimeZoneNames_en.java
+ sun/util/resources/en/TimeZoneNames_en.java \
+ sun/util/resources/en/TimeZoneNames_en_CA.java \
+ sun/util/resources/en/TimeZoneNames_en_GB.java \
+ sun/util/resources/en/TimeZoneNames_en_IE.java
diff --git a/jdk/make/java/util/FILES_properties.gmk b/jdk/make/java/util/FILES_properties.gmk
index 4b777c5f2d8..e2fc3cb118b 100644
--- a/jdk/make/java/util/FILES_properties.gmk
+++ b/jdk/make/java/util/FILES_properties.gmk
@@ -26,9 +26,25 @@
FILES_compiled_properties = \
sun/util/resources/LocaleNames.properties \
sun/util/resources/en/LocaleNames_en.properties \
+ sun/util/resources/en/LocaleNames_en_MT.properties \
+ sun/util/resources/en/LocaleNames_en_PH.properties \
+ sun/util/resources/en/LocaleNames_en_SG.properties \
\
sun/util/resources/CalendarData.properties \
sun/util/resources/en/CalendarData_en.properties \
+ sun/util/resources/en/CalendarData_en_GB.properties \
+ sun/util/resources/en/CalendarData_en_IE.properties \
+ sun/util/resources/en/CalendarData_en_MT.properties \
\
sun/util/resources/CurrencyNames.properties \
- sun/util/resources/en/CurrencyNames_en_US.properties
+ sun/util/resources/en/CurrencyNames_en_AU.properties \
+ sun/util/resources/en/CurrencyNames_en_CA.properties \
+ sun/util/resources/en/CurrencyNames_en_GB.properties \
+ sun/util/resources/en/CurrencyNames_en_IE.properties \
+ sun/util/resources/en/CurrencyNames_en_IN.properties \
+ sun/util/resources/en/CurrencyNames_en_MT.properties \
+ sun/util/resources/en/CurrencyNames_en_NZ.properties \
+ sun/util/resources/en/CurrencyNames_en_PH.properties \
+ sun/util/resources/en/CurrencyNames_en_SG.properties \
+ sun/util/resources/en/CurrencyNames_en_US.properties \
+ sun/util/resources/en/CurrencyNames_en_ZA.properties
diff --git a/jdk/make/javax/sound/jsoundds/Makefile b/jdk/make/javax/sound/jsoundds/Makefile
index f476b39811a..a747d699a0a 100644
--- a/jdk/make/javax/sound/jsoundds/Makefile
+++ b/jdk/make/javax/sound/jsoundds/Makefile
@@ -55,8 +55,7 @@ FILES_export = \
LDLIBS += dsound.lib winmm.lib user32.lib ole32.lib
CPPFLAGS += \
-DUSE_DAUDIO=TRUE \
- -I$(SHARE_SRC)/native/com/sun/media/sound \
- -I$(DXSDK_INCLUDE_PATH)
+ -I$(SHARE_SRC)/native/com/sun/media/sound
#
# Add to the ambient VPATH.
diff --git a/jdk/make/jdk_generic_profile.sh b/jdk/make/jdk_generic_profile.sh
index 28705393a33..1103a56aa52 100644
--- a/jdk/make/jdk_generic_profile.sh
+++ b/jdk/make/jdk_generic_profile.sh
@@ -80,7 +80,6 @@
# ALT_BOOTDIR
# Windows Only:
# ALT_UNIXCOMMAND_PATH
-# ALT_DXSDK_PATH
# ALT_MSVCRNN_DLL_PATH
#
#############################################################################
diff --git a/jdk/make/jprt.properties b/jdk/make/jprt.properties
index 8f7038e1f3b..eb6ff3ff2f0 100644
--- a/jdk/make/jprt.properties
+++ b/jdk/make/jprt.properties
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 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
@@ -40,8 +40,8 @@ jprt.build.targets= \
linux_i586_2.6-{product|fastdebug}, \
linux_x64_2.6-{product|fastdebug}, \
macosx_x64_10.7-{product|fastdebug}, \
- windows_i586_5.1-{product|fastdebug}, \
- windows_x64_5.2-{product|fastdebug}
+ windows_i586_6.1-{product|fastdebug}, \
+ windows_x64_6.1-{product|fastdebug}
# User can select the test set with jprt submit "-testset name" option
jprt.my.test.set=${jprt.test.set}
@@ -55,8 +55,8 @@ jprt.my.test.target.set= \
linux_i586_2.6-product-{c1|c2}-TESTNAME, \
linux_x64_2.6-product-c2-TESTNAME, \
macosx_x64_10.7-product-c2-TESTNAME, \
- windows_i586_5.1-product-c1-TESTNAME, \
- windows_x64_5.2-product-c2-TESTNAME
+ windows_i586_6.1-product-c1-TESTNAME, \
+ windows_x64_6.1-product-c2-TESTNAME
# Default vm test targets (testset=default)
jprt.vm.default.test.targets= \
diff --git a/jdk/make/netbeans/awt2d/README b/jdk/make/netbeans/awt2d/README
index 040c9e76919..4df566dd157 100644
--- a/jdk/make/netbeans/awt2d/README
+++ b/jdk/make/netbeans/awt2d/README
@@ -39,7 +39,6 @@ Here are the steps:
(on Windows):
#>env | grep ALT
ALT_JDK_IMPORT_PATH=c:/devtools/java/jdk1.7.0
- ALT_DXSDK_PATH=c:/devtools/DirectX/DXSDK_Dec06
ALT_BOOTDIR=c:/DevTools/java/jdk1.6.0
If your build is a FASTDEBUG build, don't forget
@@ -50,7 +49,6 @@ Here are the steps:
accordingly:
make.options=\
ALT_JDK_IMPORT_PATH=c:/devtools/java/jdk1.7.0 \
- ALT_DXSDK_PATH=c:/devtools/DirectX/DXSDK_Dec06 \
ALT_BOOTDIR=c:/DevTools/java/jdk1.6.0 \
FASTDEBUG=true
make=c:/devtools/cygwin/bin/make
@@ -175,7 +173,6 @@ Notes on using CND (C/C++ pack) with this project and NetBeans.
../../build/windows-i586/tmp/sun/sun.awt/splashscreen/CClassHeaders;
../../build/windows-i586/tmp/sun/sun.font/fontmanager/CClassHeaders;
../../build/windows-i586/tmp/sun/sun.font/t2k/CClassHeaders;
- C:/DevTools/DirectX/DXSDK_Dec06/Include;
C:/devtools/VS2003/SDK/v1.1/include;
C:/devtools/VS2003/VC7/ATLMFC/INCLUDE;
C:/devtools/VS2003/VC7/INCLUDE;
@@ -188,7 +185,7 @@ Notes on using CND (C/C++ pack) with this project and NetBeans.
Note that most paths are relative to the native project directory -
this helps if you decide to relocate the workspace later. The ones that
aren't relative are paths to external include directories, like those
- of the Platform SDK, DirectX SDK.
+ of the Platform SDK.
On Unix platforms these may be directories like /usr/include.
The parser must know some defines to correctly parse the source files,
diff --git a/jdk/make/sun/awt/Makefile b/jdk/make/sun/awt/Makefile
index dc4c250cf74..8b7612e416a 100644
--- a/jdk/make/sun/awt/Makefile
+++ b/jdk/make/sun/awt/Makefile
@@ -564,7 +564,6 @@ OTHER_INCLUDES += -I$(CLASSHDRDIR)/../../java/jvm \
-I$(OBJDIR) \
-I$(SHARE_SRC)/native/common \
-I$(WINAWT_native) \
- -I$(DXSDK_INCLUDE_PATH) \
-I$(SHARE_SRC)/native/sun/awt/image/cvutils \
-I$(SHARE_SRC)/native/sun/awt/image \
-I$(SHARE_SRC)/native/sun/java2d/loops \
diff --git a/jdk/make/sun/cmm/lcms/mapfile-vers b/jdk/make/sun/cmm/lcms/mapfile-vers
index 3d9074f746d..949ff9b5787 100644
--- a/jdk/make/sun/cmm/lcms/mapfile-vers
+++ b/jdk/make/sun/cmm/lcms/mapfile-vers
@@ -28,9 +28,8 @@
SUNWprivate_1.1 {
global:
Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative;
- Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative;
- Java_sun_java2d_cmm_lcms_LCMS_getProfileSize;
- Java_sun_java2d_cmm_lcms_LCMS_getProfileData;
+ Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative;
+ Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative;
Java_sun_java2d_cmm_lcms_LCMS_getTagNative;
Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative;
Java_sun_java2d_cmm_lcms_LCMS_colorConvert;
diff --git a/jdk/make/sun/jawt/Makefile b/jdk/make/sun/jawt/Makefile
index 718fb33c499..0520fc17bf1 100644
--- a/jdk/make/sun/jawt/Makefile
+++ b/jdk/make/sun/jawt/Makefile
@@ -69,7 +69,6 @@ OTHER_CXXFLAGS += $(GX_OPTION) -DUNICODE -D_UNICODE
# Other extra flags needed for compiling.
#
CPPFLAGS += -I$(SHARE_SRC)/native/common \
- -I$(DXSDK_INCLUDE_PATH) \
-I$(PLATFORM_SRC)/native/sun/windows \
-I$(CLASSHDRDIR)/../../awt/CClassHeaders \
-I$(SHARE_SRC)/native/sun/awt/debug \
diff --git a/jdk/make/sun/text/FILES_java.gmk b/jdk/make/sun/text/FILES_java.gmk
index 2f15ec33612..dbb4856c673 100644
--- a/jdk/make/sun/text/FILES_java.gmk
+++ b/jdk/make/sun/text/FILES_java.gmk
@@ -96,16 +96,6 @@ FILES_java = \
sun/text/resources/el/FormatData_el.java \
sun/text/resources/el/FormatData_el_CY.java \
sun/text/resources/el/FormatData_el_GR.java \
- sun/text/resources/en/FormatData_en_AU.java \
- sun/text/resources/en/FormatData_en_CA.java \
- sun/text/resources/en/FormatData_en_GB.java \
- sun/text/resources/en/FormatData_en_IE.java \
- sun/text/resources/en/FormatData_en_IN.java \
- sun/text/resources/en/FormatData_en_MT.java \
- sun/text/resources/en/FormatData_en_NZ.java \
- sun/text/resources/en/FormatData_en_PH.java \
- sun/text/resources/en/FormatData_en_SG.java \
- sun/text/resources/en/FormatData_en_ZA.java \
sun/text/resources/es/FormatData_es.java \
sun/text/resources/es/FormatData_es_BO.java \
sun/text/resources/es/FormatData_es_AR.java \
@@ -214,9 +204,6 @@ FILES_java = \
sun/util/resources/zh/CurrencyNames_zh_SG.java \
sun/util/resources/zh/LocaleNames_zh_HK.java \
sun/util/resources/de/TimeZoneNames_de.java \
- sun/util/resources/en/TimeZoneNames_en_CA.java \
- sun/util/resources/en/TimeZoneNames_en_GB.java \
- sun/util/resources/en/TimeZoneNames_en_IE.java \
sun/util/resources/es/TimeZoneNames_es.java \
sun/util/resources/fr/TimeZoneNames_fr.java \
sun/util/resources/hi/TimeZoneNames_hi.java \
@@ -237,8 +224,6 @@ FILES_java = \
sun/text/resources/da/JavaTimeSupplementary_da.java \
sun/text/resources/de/JavaTimeSupplementary_de.java \
sun/text/resources/el/JavaTimeSupplementary_el.java \
- sun/text/resources/en/JavaTimeSupplementary_en_GB.java \
- sun/text/resources/en/JavaTimeSupplementary_en_SG.java \
sun/text/resources/es/JavaTimeSupplementary_es.java \
sun/text/resources/et/JavaTimeSupplementary_et.java \
sun/text/resources/fi/JavaTimeSupplementary_fi.java \
diff --git a/jdk/make/sun/text/FILES_properties.gmk b/jdk/make/sun/text/FILES_properties.gmk
index a3a1321cfb9..494d6cc4b19 100644
--- a/jdk/make/sun/text/FILES_properties.gmk
+++ b/jdk/make/sun/text/FILES_properties.gmk
@@ -33,9 +33,6 @@ FILES_compiled_properties = \
sun/util/resources/de/LocaleNames_de.properties \
sun/util/resources/el/LocaleNames_el.properties \
sun/util/resources/el/LocaleNames_el_CY.properties \
- sun/util/resources/en/LocaleNames_en_MT.properties \
- sun/util/resources/en/LocaleNames_en_PH.properties \
- sun/util/resources/en/LocaleNames_en_SG.properties \
sun/util/resources/es/LocaleNames_es.properties \
sun/util/resources/es/LocaleNames_es_US.properties \
sun/util/resources/et/LocaleNames_et.properties \
@@ -88,9 +85,6 @@ FILES_compiled_properties = \
sun/util/resources/de/CalendarData_de.properties \
sun/util/resources/el/CalendarData_el.properties \
sun/util/resources/el/CalendarData_el_CY.properties \
- sun/util/resources/en/CalendarData_en_GB.properties \
- sun/util/resources/en/CalendarData_en_IE.properties \
- sun/util/resources/en/CalendarData_en_MT.properties \
sun/util/resources/es/CalendarData_es.properties \
sun/util/resources/es/CalendarData_es_ES.properties \
sun/util/resources/es/CalendarData_es_US.properties \
@@ -164,16 +158,6 @@ FILES_compiled_properties = \
sun/util/resources/de/CurrencyNames_de_LU.properties \
sun/util/resources/el/CurrencyNames_el_CY.properties \
sun/util/resources/el/CurrencyNames_el_GR.properties \
- sun/util/resources/en/CurrencyNames_en_AU.properties \
- sun/util/resources/en/CurrencyNames_en_CA.properties \
- sun/util/resources/en/CurrencyNames_en_GB.properties \
- sun/util/resources/en/CurrencyNames_en_IE.properties \
- sun/util/resources/en/CurrencyNames_en_IN.properties \
- sun/util/resources/en/CurrencyNames_en_MT.properties \
- sun/util/resources/en/CurrencyNames_en_NZ.properties \
- sun/util/resources/en/CurrencyNames_en_PH.properties \
- sun/util/resources/en/CurrencyNames_en_SG.properties \
- sun/util/resources/en/CurrencyNames_en_ZA.properties \
sun/util/resources/es/CurrencyNames_es.properties \
sun/util/resources/es/CurrencyNames_es_AR.properties \
sun/util/resources/es/CurrencyNames_es_BO.properties \
diff --git a/jdk/make/tools/src/build/tools/generatecharacter/CharacterName.java b/jdk/make/tools/src/build/tools/generatecharacter/CharacterName.java
index 0872100b7db..833a835c0ce 100644
--- a/jdk/make/tools/src/build/tools/generatecharacter/CharacterName.java
+++ b/jdk/make/tools/src/build/tools/generatecharacter/CharacterName.java
@@ -11,7 +11,7 @@ public class CharacterName {
FileReader reader = null;
try {
if (args.length != 2) {
- System.err.println("Usage: java CharacterName UniocdeData.txt uniName.dat");
+ System.err.println("Usage: java CharacterName UnicodeData.txt uniName.dat");
System.exit(1);
}
diff --git a/jdk/makefiles/CompileNativeLibraries.gmk b/jdk/makefiles/CompileNativeLibraries.gmk
index 656ee3c4841..8c59cecc4f7 100644
--- a/jdk/makefiles/CompileNativeLibraries.gmk
+++ b/jdk/makefiles/CompileNativeLibraries.gmk
@@ -211,6 +211,7 @@ ifneq ($(OPENJDK_TARGET_OS),macosx)
LIBJAVA_EXCLUDE_FILES += java_props_macosx.c
else
BUILD_LIBJAVA_java_props_md.c_CFLAGS:=-x objective-c
+ BUILD_LIBJAVA_java_props_macosx.c_CFLAGS:=-x objective-c
endif
ifeq ($(OPENJDK_TARGET_OS),windows)
@@ -252,6 +253,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAVA,\
LDFLAGS_SUFFIX_linux:=$(LIBDL) $(BUILD_LIBFDLIBM),\
LDFLAGS_SUFFIX_macosx:=-L$(JDK_OUTPUTDIR)/objs/ -lfdlibm \
-framework CoreFoundation \
+ -framework Foundation \
-framework Security -framework SystemConfiguration, \
LDFLAGS_SUFFIX_windows:=-export:winFileHandleOpen -export:handleLseek \
jvm.lib $(BUILD_LIBFDLIBM) $(WIN_VERIFY_LIB) \
@@ -472,7 +474,6 @@ ifeq ($(OPENJDK_TARGET_OS),windows)
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/windows \
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows \
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/d3d
- LIBAWT_CFLAGS+=-I$(DXSDK_INCLUDE_PATH)
else
LIBAWT_DIRS+=\
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/x11
@@ -1482,8 +1483,7 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
-I$(JDK_TOPDIR)/src/share/native/sun/awt/debug \
-I$(JDK_TOPDIR)/src/share/native/sun/java2d \
-I$(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \
- -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows \
- -I$(DXSDK_INCLUDE_PATH), \
+ -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows, \
LDFLAGS:=$(LDFLAGS_JDKLIB) $(KERNEL32_LIB) $(LDFLAGS_CXX_JDK) \
advapi32.lib $(WIN_AWT_LIB),\
LDFLAGS_SUFFIX:=$(LDFLAGS_JDKLIB_SUFFIX),\
@@ -2961,8 +2961,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJSOUNDDS,\
OPTIMIZATION:=LOW, \
CFLAGS:=$(CFLAGS_JDKLIB) \
$(LIBJSOUND_CFLAGS) \
- -DUSE_DAUDIO=TRUE \
- -I$(DXSDK_INCLUDE_PATH), \
+ -DUSE_DAUDIO=TRUE, \
LDFLAGS:=$(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \
$(call SET_SHARED_LIBRARY_ORIGIN),\
LDFLAGS_SUFFIX:=$(LDFLAGS_JDKLIB_SUFFIX) dsound.lib winmm.lib user32.lib ole32.lib,\
diff --git a/jdk/makefiles/CreateJars.gmk b/jdk/makefiles/CreateJars.gmk
index 54531f19ef5..e1d0a5d311b 100644
--- a/jdk/makefiles/CreateJars.gmk
+++ b/jdk/makefiles/CreateJars.gmk
@@ -80,39 +80,6 @@ LOCALEDATA_INCLUDE_LOCALES := ar be bg ca cs da de el es et fi fr ga hi hr hu in
LOCALEDATA_INCLUDES := $(addprefix sun/text/resources/,$(LOCALEDATA_INCLUDE_LOCALES)) \
$(addprefix sun/util/resources/,$(LOCALEDATA_INCLUDE_LOCALES))
-# For non-US English locale data
-
-LOCALEDATA_INCLUDES += \
- sun/text/resources/en/FormatData_en_AU.class \
- sun/text/resources/en/FormatData_en_CA.class \
- sun/text/resources/en/FormatData_en_GB.class \
- sun/text/resources/en/FormatData_en_IE.class \
- sun/text/resources/en/FormatData_en_IN.class \
- sun/text/resources/en/FormatData_en_MT.class \
- sun/text/resources/en/FormatData_en_NZ.class \
- sun/text/resources/en/FormatData_en_PH.class \
- sun/text/resources/en/FormatData_en_SG.class \
- sun/text/resources/en/FormatData_en_ZA.class \
- sun/util/resources/en/CalendarData_en_GB.class \
- sun/util/resources/en/CalendarData_en_IE.class \
- sun/util/resources/en/CalendarData_en_MT.class \
- sun/util/resources/en/CurrencyNames_en_AU.class \
- sun/util/resources/en/CurrencyNames_en_CA.class \
- sun/util/resources/en/CurrencyNames_en_GB.class \
- sun/util/resources/en/CurrencyNames_en_IE.class \
- sun/util/resources/en/CurrencyNames_en_IN.class \
- sun/util/resources/en/CurrencyNames_en_MT.class \
- sun/util/resources/en/CurrencyNames_en_NZ.class \
- sun/util/resources/en/CurrencyNames_en_PH.class \
- sun/util/resources/en/CurrencyNames_en_SG.class \
- sun/util/resources/en/CurrencyNames_en_ZA.class \
- sun/util/resources/en/LocaleNames_en_MT.class \
- sun/util/resources/en/LocaleNames_en_PH.class \
- sun/util/resources/en/LocaleNames_en_SG.class \
- sun/util/resources/en/TimeZoneNames_en_CA.class \
- sun/util/resources/en/TimeZoneNames_en_GB.class \
- sun/util/resources/en/TimeZoneNames_en_IE.class
-
$(eval $(call SetupArchive,BUILD_LOCALEDATA_JAR,,\
SRCS:=$(JDK_OUTPUTDIR)/classes,\
SUFFIXES:=.class _dict _th,\
diff --git a/jdk/makefiles/GensrcLocaleDataMetaInfo.gmk b/jdk/makefiles/GensrcLocaleDataMetaInfo.gmk
index 306276adf59..1577017b7f2 100644
--- a/jdk/makefiles/GensrcLocaleDataMetaInfo.gmk
+++ b/jdk/makefiles/GensrcLocaleDataMetaInfo.gmk
@@ -50,27 +50,27 @@ ifneq (,$(MISSING_RESOURCES)$(NEW_RESOURCES))
$(shell $(RM) $(JDK_OUTPUTDIR)/gensrc/sun/util/locale/provider/LocaleDataMetaInfo.java)
endif
-# The US locales
-US_LOCALES:=en en-US
+# The EN locales
+EN_LOCALES:=en%
# ja-JP-JP and th-TH-TH need to be manually added, as they don't have any resource files.
-ALL_NON_US_LOCALES:=ja-JP-JP th-TH-TH
+ALL_NON_EN_LOCALES:=ja-JP-JP th-TH-TH
SED_ARGS:=-e 's|$(HASH)warn This file is preprocessed before being compiled|// -- This file was mechanically generated: Do not edit! -- //|g'
# This macro creates a sed expression that substitues for example:
-# #FormatData_USLocales# with: en and/or en_US.
+# #FormatData_ENLocales# with: en% locales.
define CaptureLocale
$1_LOCALES := $$(subst _,-,$$(filter-out $1,$$(subst $1_,,$$(filter $1_%,$(LOCALE_RESOURCES)))))
- $1_US_LOCALES := $$(filter $(US_LOCALES),$$($1_LOCALES))
- $1_NON_US_LOCALES := $$(filter-out $(US_LOCALES),$$($1_LOCALES))
+ $1_EN_LOCALES := $$(filter $(EN_LOCALES),$$($1_LOCALES))
+ $1_NON_EN_LOCALES := $$(filter-out $(EN_LOCALES),$$($1_LOCALES))
- ALL_US_LOCALES += $$($1_US_LOCALES)
- ALL_NON_US_LOCALES += $$($1_NON_US_LOCALES)
+ ALL_EN_LOCALES += $$($1_EN_LOCALES)
+ ALL_NON_EN_LOCALES += $$($1_NON_EN_LOCALES)
# Don't sed in a space if there are no locales.
- SED_ARGS+= -e 's/$$(HASH)$1_USLocales$$(HASH)/$$(if $$($1_US_LOCALES),$$(SPACE)$$($1_US_LOCALES),)/g'
- SED_ARGS+= -e 's/$$(HASH)$1_NonUSLocales$$(HASH)/$$(if $$($1_NON_US_LOCALES),$$(SPACE)$$($1_NON_US_LOCALES),)/g'
+ SED_ARGS+= -e 's/$$(HASH)$1_ENLocales$$(HASH)/$$(if $$($1_EN_LOCALES),$$(SPACE)$$($1_EN_LOCALES),)/g'
+ SED_ARGS+= -e 's/$$(HASH)$1_NonENLocales$$(HASH)/$$(if $$($1_NON_EN_LOCALES),$$(SPACE)$$($1_NON_EN_LOCALES),)/g'
endef
#sun.text.resources.FormatData
@@ -91,8 +91,8 @@ $(eval $(call CaptureLocale,CurrencyNames))
#sun.util.resources.CalendarData
$(eval $(call CaptureLocale,CalendarData))
-SED_ARGS+= -e 's/$(HASH)AvailableLocales_USLocales$(HASH)/$(sort $(ALL_US_LOCALES))/g'
-SED_ARGS+= -e 's/$(HASH)AvailableLocales_NonUSLocales$(HASH)/$(sort $(ALL_NON_US_LOCALES))/g'
+SED_ARGS+= -e 's/$(HASH)AvailableLocales_ENLocales$(HASH)/$(sort $(ALL_EN_LOCALES))/g'
+SED_ARGS+= -e 's/$(HASH)AvailableLocales_NonENLocales$(HASH)/$(sort $(ALL_NON_EN_LOCALES))/g'
$(JDK_OUTPUTDIR)/gensrc/sun/util/locale/provider/LocaleDataMetaInfo.java: \
$(JDK_TOPDIR)/src/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template
diff --git a/jdk/makefiles/Setup.gmk b/jdk/makefiles/Setup.gmk
index 8012e547b55..4da575fed1a 100644
--- a/jdk/makefiles/Setup.gmk
+++ b/jdk/makefiles/Setup.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
@@ -25,6 +25,10 @@
DISABLE_WARNINGS:=-Xlint:all,-deprecation,-unchecked,-rawtypes,-cast,-serial,-dep-ann,-static,-fallthrough,-try,-varargs,-empty,-finally
+# To build with all warnings enabled, do the following:
+# make JAVAC_WARNINGS="-Xlint:all -Xmaxwarns 10000"
+JAVAC_WARNINGS:=-Xlint:-unchecked,-deprecation,-overrides,classfile,dep-ann,divzero,varargs -Werror
+
# The generate old bytecode javac setup uses the new compiler to compile for the
# boot jdk to generate tools that need to be run with the boot jdk.
# Thus we force the target bytecode to 7.
@@ -41,7 +45,7 @@ $(eval $(call SetupJavaCompiler,GENERATE_JDKBYTECODE,\
JVM:=$(JAVA),\
JAVAC:=$(NEW_JAVAC),\
FLAGS:=-bootclasspath $(JDK_OUTPUTDIR)/classes -source 8 -target 8 \
- -encoding ascii -XDignore.symbol.file=true $(DISABLE_WARNINGS) \
+ -encoding ascii -XDignore.symbol.file=true $(JAVAC_WARNINGS) \
$(GENERATE_JDKBYTECODE_EXTRA_FLAGS),\
SERVER_DIR:=$(SJAVAC_SERVER_DIR),\
SERVER_JVM:=$(SJAVAC_SERVER_JAVA)))
diff --git a/jdk/makefiles/jprt.properties b/jdk/makefiles/jprt.properties
index a4a077226e8..1051bb34bb7 100644
--- a/jdk/makefiles/jprt.properties
+++ b/jdk/makefiles/jprt.properties
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 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
@@ -39,8 +39,8 @@ jprt.build.targets= \
solaris_x64_5.10-{product|fastdebug}, \
linux_i586_2.6-{product|fastdebug}, \
linux_x64_2.6-{product|fastdebug}, \
- windows_i586_5.1-{product|fastdebug}, \
- windows_x64_5.2-{product|fastdebug}
+ windows_i586_6.1-{product|fastdebug}, \
+ windows_x64_6.1-{product|fastdebug}
# User can select the test set with jprt submit "-testset name" option
jprt.my.test.set=${jprt.test.set}
@@ -53,8 +53,8 @@ jprt.vm.default.test.targets= \
solaris_x64_5.10-product-c2-jvm98, \
linux_i586_2.6-product-{c1|c2}-jvm98, \
linux_x64_2.6-product-c2-jvm98, \
- windows_i586_5.1-product-c1-jvm98, \
- windows_x64_5.2-product-c2-jvm98
+ windows_i586_6.1-product-c1-jvm98, \
+ windows_x64_6.1-product-c2-jvm98
# Select vm testlist to use (allow for testset to be empty too)
jprt.vm.all.test.targets=${jprt.vm.default.test.targets}
@@ -70,8 +70,8 @@ jprt.make.rule.default.test.targets= \
solaris_x64_5.10-product-c2-jdk_beans1, \
linux_i586_2.6-product-{c1|c2}-jdk_beans1, \
linux_x64_2.6-product-c2-jdk_beans1, \
- windows_i586_5.1-product-c1-jdk_beans1, \
- windows_x64_5.2-product-c2-jdk_beans1, \
+ windows_i586_6.1-product-c1-jdk_beans1, \
+ windows_x64_6.1-product-c2-jdk_beans1, \
\
solaris_sparc_5.10-product-c1-jdk_io, \
solaris_sparcv9_5.10-product-c2-jdk_io, \
@@ -79,8 +79,8 @@ jprt.make.rule.default.test.targets= \
solaris_x64_5.10-product-c2-jdk_io, \
linux_i586_2.6-product-{c1|c2}-jdk_io, \
linux_x64_2.6-product-c2-jdk_io, \
- windows_i586_5.1-product-c1-jdk_io, \
- windows_x64_5.2-product-c2-jdk_io, \
+ windows_i586_6.1-product-c1-jdk_io, \
+ windows_x64_6.1-product-c2-jdk_io, \
\
solaris_sparc_5.10-product-c1-jdk_lang, \
solaris_sparcv9_5.10-product-c2-jdk_lang, \
@@ -88,8 +88,8 @@ jprt.make.rule.default.test.targets= \
solaris_x64_5.10-product-c2-jdk_lang, \
linux_i586_2.6-product-{c1|c2}-jdk_lang, \
linux_x64_2.6-product-c2-jdk_lang, \
- windows_i586_5.1-product-c1-jdk_lang, \
- windows_x64_5.2-product-c2-jdk_lang, \
+ windows_i586_6.1-product-c1-jdk_lang, \
+ windows_x64_6.1-product-c2-jdk_lang, \
\
solaris_sparc_5.10-product-c1-jdk_math, \
solaris_sparcv9_5.10-product-c2-jdk_math, \
@@ -97,8 +97,8 @@ jprt.make.rule.default.test.targets= \
solaris_x64_5.10-product-c2-jdk_math, \
linux_i586_2.6-product-{c1|c2}-jdk_math, \
linux_x64_2.6-product-c2-jdk_math, \
- windows_i586_5.1-product-c1-jdk_math, \
- windows_x64_5.2-product-c2-jdk_math, \
+ windows_i586_6.1-product-c1-jdk_math, \
+ windows_x64_6.1-product-c2-jdk_math, \
\
solaris_sparc_5.10-product-c1-jdk_misc, \
solaris_sparcv9_5.10-product-c2-jdk_misc, \
@@ -106,8 +106,8 @@ jprt.make.rule.default.test.targets= \
solaris_x64_5.10-product-c2-jdk_misc, \
linux_i586_2.6-product-{c1|c2}-jdk_misc, \
linux_x64_2.6-product-c2-jdk_misc, \
- windows_i586_5.1-product-c1-jdk_misc, \
- windows_x64_5.2-product-c2-jdk_misc, \
+ windows_i586_6.1-product-c1-jdk_misc, \
+ windows_x64_6.1-product-c2-jdk_misc, \
\
solaris_sparc_5.10-product-c1-jdk_net, \
solaris_sparcv9_5.10-product-c2-jdk_net, \
@@ -115,8 +115,8 @@ jprt.make.rule.default.test.targets= \
solaris_x64_5.10-product-c2-jdk_net, \
linux_i586_2.6-product-{c1|c2}-jdk_net, \
linux_x64_2.6-product-c2-jdk_net, \
- windows_i586_5.1-product-c1-jdk_net, \
- windows_x64_5.2-product-c2-jdk_net, \
+ windows_i586_6.1-product-c1-jdk_net, \
+ windows_x64_6.1-product-c2-jdk_net, \
\
solaris_sparc_5.10-product-c1-jdk_nio1, \
solaris_sparcv9_5.10-product-c2-jdk_nio1, \
@@ -124,8 +124,8 @@ jprt.make.rule.default.test.targets= \
solaris_x64_5.10-product-c2-jdk_nio1, \
linux_i586_2.6-product-{c1|c2}-jdk_nio1, \
linux_x64_2.6-product-c2-jdk_nio1, \
- windows_i586_5.1-product-c1-jdk_nio1, \
- windows_x64_5.2-product-c2-jdk_nio1, \
+ windows_i586_6.1-product-c1-jdk_nio1, \
+ windows_x64_6.1-product-c2-jdk_nio1, \
\
solaris_sparc_5.10-product-c1-jdk_nio2, \
solaris_sparcv9_5.10-product-c2-jdk_nio2, \
@@ -133,8 +133,8 @@ jprt.make.rule.default.test.targets= \
solaris_x64_5.10-product-c2-jdk_nio2, \
linux_i586_2.6-product-{c1|c2}-jdk_nio2, \
linux_x64_2.6-product-c2-jdk_nio2, \
- windows_i586_5.1-product-c1-jdk_nio2, \
- windows_x64_5.2-product-c2-jdk_nio2, \
+ windows_i586_6.1-product-c1-jdk_nio2, \
+ windows_x64_6.1-product-c2-jdk_nio2, \
\
solaris_sparc_5.10-product-c1-jdk_nio3, \
solaris_sparcv9_5.10-product-c2-jdk_nio3, \
@@ -142,8 +142,8 @@ jprt.make.rule.default.test.targets= \
solaris_x64_5.10-product-c2-jdk_nio3, \
linux_i586_2.6-product-{c1|c2}-jdk_nio3, \
linux_x64_2.6-product-c2-jdk_nio3, \
- windows_i586_5.1-product-c1-jdk_nio3, \
- windows_x64_5.2-product-c2-jdk_nio3, \
+ windows_i586_6.1-product-c1-jdk_nio3, \
+ windows_x64_6.1-product-c2-jdk_nio3, \
\
solaris_sparc_5.10-product-c1-jdk_security1, \
solaris_sparcv9_5.10-product-c2-jdk_security1, \
@@ -151,8 +151,8 @@ jprt.make.rule.default.test.targets= \
solaris_x64_5.10-product-c2-jdk_security1, \
linux_i586_2.6-product-{c1|c2}-jdk_security1, \
linux_x64_2.6-product-c2-jdk_security1, \
- windows_i586_5.1-product-c1-jdk_security1, \
- windows_x64_5.2-product-c2-jdk_security1, \
+ windows_i586_6.1-product-c1-jdk_security1, \
+ windows_x64_6.1-product-c2-jdk_security1, \
\
solaris_sparc_5.10-product-c1-jdk_text, \
solaris_sparcv9_5.10-product-c2-jdk_text, \
@@ -160,8 +160,8 @@ jprt.make.rule.default.test.targets= \
solaris_x64_5.10-product-c2-jdk_text, \
linux_i586_2.6-product-{c1|c2}-jdk_text, \
linux_x64_2.6-product-c2-jdk_text, \
- windows_i586_5.1-product-c1-jdk_text, \
- windows_x64_5.2-product-c2-jdk_text, \
+ windows_i586_6.1-product-c1-jdk_text, \
+ windows_x64_6.1-product-c2-jdk_text, \
\
solaris_sparc_5.10-product-c1-jdk_tools1, \
solaris_sparcv9_5.10-product-c2-jdk_tools1, \
@@ -169,8 +169,8 @@ jprt.make.rule.default.test.targets= \
solaris_x64_5.10-product-c2-jdk_tools1, \
linux_i586_2.6-product-{c1|c2}-jdk_tools1, \
linux_x64_2.6-product-c2-jdk_tools1, \
- windows_i586_5.1-product-c1-jdk_tools1, \
- windows_x64_5.2-product-c2-jdk_tools1, \
+ windows_i586_6.1-product-c1-jdk_tools1, \
+ windows_x64_6.1-product-c2-jdk_tools1, \
\
solaris_sparc_5.10-product-c1-jdk_util, \
solaris_sparcv9_5.10-product-c2-jdk_util, \
@@ -178,8 +178,8 @@ jprt.make.rule.default.test.targets= \
solaris_x64_5.10-product-c2-jdk_util, \
linux_i586_2.6-product-{c1|c2}-jdk_util, \
linux_x64_2.6-product-c2-jdk_util, \
- windows_i586_5.1-product-c1-jdk_util, \
- windows_x64_5.2-product-c2-jdk_util
+ windows_i586_6.1-product-c1-jdk_util, \
+ windows_x64_6.1-product-c2-jdk_util
# All jdk test targets in test/Makefile (still no fastdebug & limited c2)
jprt.make.rule.all.test.targets= \
@@ -192,8 +192,8 @@ jprt.make.rule.all.test.targets= \
solaris_x64_5.10-product-c2-jdk_awt, \
linux_i586_2.6-product-{c1|c2}-jdk_awt, \
linux_x64_2.6-product-c2-jdk_awt, \
- windows_i586_5.1-product-c1-jdk_awt, \
- windows_x64_5.2-product-c2-jdk_awt, \
+ windows_i586_6.1-product-c1-jdk_awt, \
+ windows_x64_6.1-product-c2-jdk_awt, \
\
solaris_sparc_5.10-product-c1-jdk_beans2, \
solaris_sparcv9_5.10-product-c2-jdk_beans2, \
@@ -201,8 +201,8 @@ jprt.make.rule.all.test.targets= \
solaris_x64_5.10-product-c2-jdk_beans2, \
linux_i586_2.6-product-{c1|c2}-jdk_beans2, \
linux_x64_2.6-product-c2-jdk_beans2, \
- windows_i586_5.1-product-c1-jdk_beans2, \
- windows_x64_5.2-product-c2-jdk_beans2, \
+ windows_i586_6.1-product-c1-jdk_beans2, \
+ windows_x64_6.1-product-c2-jdk_beans2, \
\
solaris_sparc_5.10-product-c1-jdk_beans3, \
solaris_sparcv9_5.10-product-c2-jdk_beans3, \
@@ -210,8 +210,8 @@ jprt.make.rule.all.test.targets= \
solaris_x64_5.10-product-c2-jdk_beans3, \
linux_i586_2.6-product-{c1|c2}-jdk_beans3, \
linux_x64_2.6-product-c2-jdk_beans3, \
- windows_i586_5.1-product-c1-jdk_beans3, \
- windows_x64_5.2-product-c2-jdk_beans3, \
+ windows_i586_6.1-product-c1-jdk_beans3, \
+ windows_x64_6.1-product-c2-jdk_beans3, \
\
solaris_sparc_5.10-product-c1-jdk_management1, \
solaris_sparcv9_5.10-product-c2-jdk_management1, \
@@ -219,8 +219,8 @@ jprt.make.rule.all.test.targets= \
solaris_x64_5.10-product-c2-jdk_management1, \
linux_i586_2.6-product-{c1|c2}-jdk_management1, \
linux_x64_2.6-product-c2-jdk_management1, \
- windows_i586_5.1-product-c1-jdk_management1, \
- windows_x64_5.2-product-c2-jdk_management1, \
+ windows_i586_6.1-product-c1-jdk_management1, \
+ windows_x64_6.1-product-c2-jdk_management1, \
\
solaris_sparc_5.10-product-c1-jdk_management2, \
solaris_sparcv9_5.10-product-c2-jdk_management2, \
@@ -228,8 +228,8 @@ jprt.make.rule.all.test.targets= \
solaris_x64_5.10-product-c2-jdk_management2, \
linux_i586_2.6-product-{c1|c2}-jdk_management2, \
linux_x64_2.6-product-c2-jdk_management2, \
- windows_i586_5.1-product-c1-jdk_management2, \
- windows_x64_5.2-product-c2-jdk_management2, \
+ windows_i586_6.1-product-c1-jdk_management2, \
+ windows_x64_6.1-product-c2-jdk_management2, \
\
solaris_sparc_5.10-product-c1-jdk_rmi, \
solaris_sparcv9_5.10-product-c2-jdk_rmi, \
@@ -237,8 +237,8 @@ jprt.make.rule.all.test.targets= \
solaris_x64_5.10-product-c2-jdk_rmi, \
linux_i586_2.6-product-{c1|c2}-jdk_rmi, \
linux_x64_2.6-product-c2-jdk_rmi, \
- windows_i586_5.1-product-c1-jdk_rmi, \
- windows_x64_5.2-product-c2-jdk_rmi, \
+ windows_i586_6.1-product-c1-jdk_rmi, \
+ windows_x64_6.1-product-c2-jdk_rmi, \
\
solaris_sparc_5.10-product-c1-jdk_security2, \
solaris_sparcv9_5.10-product-c2-jdk_security2, \
@@ -246,8 +246,8 @@ jprt.make.rule.all.test.targets= \
solaris_x64_5.10-product-c2-jdk_security2, \
linux_i586_2.6-product-{c1|c2}-jdk_security2, \
linux_x64_2.6-product-c2-jdk_security2, \
- windows_i586_5.1-product-c1-jdk_security2, \
- windows_x64_5.2-product-c2-jdk_security2, \
+ windows_i586_6.1-product-c1-jdk_security2, \
+ windows_x64_6.1-product-c2-jdk_security2, \
\
solaris_sparc_5.10-product-c1-jdk_security3, \
solaris_sparcv9_5.10-product-c2-jdk_security3, \
@@ -255,8 +255,8 @@ jprt.make.rule.all.test.targets= \
solaris_x64_5.10-product-c2-jdk_security3, \
linux_i586_2.6-product-{c1|c2}-jdk_security3, \
linux_x64_2.6-product-c2-jdk_security3, \
- windows_i586_5.1-product-c1-jdk_security3, \
- windows_x64_5.2-product-c2-jdk_security3, \
+ windows_i586_6.1-product-c1-jdk_security3, \
+ windows_x64_6.1-product-c2-jdk_security3, \
\
solaris_sparc_5.10-product-c1-jdk_sound, \
solaris_sparcv9_5.10-product-c2-jdk_sound, \
@@ -264,8 +264,8 @@ jprt.make.rule.all.test.targets= \
solaris_x64_5.10-product-c2-jdk_sound, \
linux_i586_2.6-product-{c1|c2}-jdk_sound, \
linux_x64_2.6-product-c2-jdk_sound, \
- windows_i586_5.1-product-c1-jdk_sound, \
- windows_x64_5.2-product-c2-jdk_sound, \
+ windows_i586_6.1-product-c1-jdk_sound, \
+ windows_x64_6.1-product-c2-jdk_sound, \
\
solaris_sparc_5.10-product-c1-jdk_swing, \
solaris_sparcv9_5.10-product-c2-jdk_swing, \
@@ -273,8 +273,8 @@ jprt.make.rule.all.test.targets= \
solaris_x64_5.10-product-c2-jdk_swing, \
linux_i586_2.6-product-{c1|c2}-jdk_swing, \
linux_x64_2.6-product-c2-jdk_swing, \
- windows_i586_5.1-product-c1-jdk_swing, \
- windows_x64_5.2-product-c2-jdk_swing, \
+ windows_i586_6.1-product-c1-jdk_swing, \
+ windows_x64_6.1-product-c2-jdk_swing, \
\
solaris_sparc_5.10-product-c1-jdk_tools2, \
solaris_sparcv9_5.10-product-c2-jdk_tools2, \
@@ -282,8 +282,8 @@ jprt.make.rule.all.test.targets= \
solaris_x64_5.10-product-c2-jdk_tools2, \
linux_i586_2.6-product-{c1|c2}-jdk_tools2, \
linux_x64_2.6-product-c2-jdk_tools2, \
- windows_i586_5.1-product-c1-jdk_tools2, \
- windows_x64_5.2-product-c2-jdk_tools2
+ windows_i586_6.1-product-c1-jdk_tools2, \
+ windows_x64_6.1-product-c2-jdk_tools2
# JCK test targets in test/Makefile (no fastdebug & limited c2, windows broken)
jprt.my.jck.test.target.set= \
diff --git a/jdk/makefiles/mapfiles/liblcms/mapfile-vers b/jdk/makefiles/mapfiles/liblcms/mapfile-vers
index 024511423d3..2e63d68e5d4 100644
--- a/jdk/makefiles/mapfiles/liblcms/mapfile-vers
+++ b/jdk/makefiles/mapfiles/liblcms/mapfile-vers
@@ -28,9 +28,8 @@
SUNWprivate_1.1 {
global:
Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative;
- Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative;
- Java_sun_java2d_cmm_lcms_LCMS_getProfileSize;
- Java_sun_java2d_cmm_lcms_LCMS_getProfileData;
+ Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative;
+ Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative;
Java_sun_java2d_cmm_lcms_LCMS_getTagNative;
Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative;
Java_sun_java2d_cmm_lcms_LCMS_colorConvert;
diff --git a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java
index fb7032f0b74..9765066d9d2 100644
--- a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java
+++ b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java
@@ -38,6 +38,7 @@ import java.util.*;
import sun.awt.*;
import sun.lwawt.macosx.*;
import sun.print.*;
+import sun.security.util.SecurityConstants;
public abstract class LWToolkit extends SunToolkit implements Runnable {
@@ -502,7 +503,7 @@ public abstract class LWToolkit extends SunToolkit implements Runnable {
public Clipboard getSystemClipboard() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
- security.checkSystemClipboardAccess();
+ security.checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION);
}
synchronized (this) {
diff --git a/jdk/src/macosx/native/sun/awt/CTextPipe.m b/jdk/src/macosx/native/sun/awt/CTextPipe.m
index d9bf48afd92..f6510f204ae 100644
--- a/jdk/src/macosx/native/sun/awt/CTextPipe.m
+++ b/jdk/src/macosx/native/sun/awt/CTextPipe.m
@@ -145,11 +145,6 @@ void JavaCT_DrawGlyphVector
BOOL saved = false;
- /* Save and restore of graphics context is done before the iteration.
- This seems to work using our test case (see bug ID 7158350) so we are restoring it at
- the end of the for loop. If we find out that save/restore outside the loop
- doesn't work on all cases then we will move the Save/Restore inside the loop.*/
- CGContextSaveGState(cgRef);
CGAffineTransform invTx = CGAffineTransformInvert(strike->fTx);
NSUInteger i;
@@ -226,7 +221,9 @@ void JavaCT_DrawGlyphVector
}
// reset the font on the context after striking a unicode with CoreText
- CGContextRestoreGState(cgRef);
+ if (saved) {
+ CGContextRestoreGState(cgRef);
+ }
}
// Using the Quartz Surface Data context, draw a hot-substituted character run
diff --git a/jdk/src/share/classes/com/sun/nio/sctp/Association.java b/jdk/src/share/classes/com/sun/nio/sctp/Association.java
index b367412b83f..965feae3418 100644
--- a/jdk/src/share/classes/com/sun/nio/sctp/Association.java
+++ b/jdk/src/share/classes/com/sun/nio/sctp/Association.java
@@ -58,6 +58,13 @@ public class Association {
/**
* Initializes a new instance of this class.
+ *
+ * @param associationID
+ * The association ID
+ * @param maxInStreams
+ * The maximum number of inbound streams
+ * @param maxOutStreams
+ * The maximum number of outbound streams
*/
protected Association(int associationID,
int maxInStreams,
diff --git a/jdk/src/share/classes/com/sun/nio/sctp/IllegalReceiveException.java b/jdk/src/share/classes/com/sun/nio/sctp/IllegalReceiveException.java
index 0dc063bd55c..b5a4137054d 100644
--- a/jdk/src/share/classes/com/sun/nio/sctp/IllegalReceiveException.java
+++ b/jdk/src/share/classes/com/sun/nio/sctp/IllegalReceiveException.java
@@ -41,6 +41,9 @@ public class IllegalReceiveException extends IllegalStateException {
/**
* Constructs an instance of this class with the specified message.
+ *
+ * @param msg
+ * The String that contains a detailed message
*/
public IllegalReceiveException(String msg) {
super(msg);
diff --git a/jdk/src/share/classes/com/sun/nio/sctp/IllegalUnbindException.java b/jdk/src/share/classes/com/sun/nio/sctp/IllegalUnbindException.java
index b48ef56b1b5..4088df34687 100644
--- a/jdk/src/share/classes/com/sun/nio/sctp/IllegalUnbindException.java
+++ b/jdk/src/share/classes/com/sun/nio/sctp/IllegalUnbindException.java
@@ -41,6 +41,9 @@ public class IllegalUnbindException extends IllegalStateException {
/**
* Constructs an instance of this class with the specified detailed message.
+ *
+ * @param msg
+ * The String that contains a detailed message
*/
public IllegalUnbindException(String msg) {
super(msg);
diff --git a/jdk/src/share/classes/com/sun/nio/sctp/InvalidStreamException.java b/jdk/src/share/classes/com/sun/nio/sctp/InvalidStreamException.java
index 40a818fe5bd..abe49f24593 100644
--- a/jdk/src/share/classes/com/sun/nio/sctp/InvalidStreamException.java
+++ b/jdk/src/share/classes/com/sun/nio/sctp/InvalidStreamException.java
@@ -40,6 +40,9 @@ public class InvalidStreamException extends IllegalArgumentException {
/**
* Constructs an instance of this class with the specified detailed message.
+ *
+ * @param msg
+ * The String that contains a detailed message
*/
public InvalidStreamException(String msg) {
super(msg);
diff --git a/jdk/src/share/classes/com/sun/nio/sctp/MessageInfo.java b/jdk/src/share/classes/com/sun/nio/sctp/MessageInfo.java
index d7a2ee81563..997c6253834 100644
--- a/jdk/src/share/classes/com/sun/nio/sctp/MessageInfo.java
+++ b/jdk/src/share/classes/com/sun/nio/sctp/MessageInfo.java
@@ -48,7 +48,7 @@ import java.net.SocketAddress;
* longer required to be sent after the time period expires. It is not a hard
* timeout and may be influenced by whether the association supports the partial
* reliability extension, RFC 3758
- *
+ * .
*
* {@code MessageInfo} instances are not safe for use by multiple concurrent
* threads. If a MessageInfo is to be used by more than one thread then access
diff --git a/jdk/src/share/classes/com/sun/nio/sctp/Notification.java b/jdk/src/share/classes/com/sun/nio/sctp/Notification.java
index cc23b8f2e47..2436fae7ba7 100644
--- a/jdk/src/share/classes/com/sun/nio/sctp/Notification.java
+++ b/jdk/src/share/classes/com/sun/nio/sctp/Notification.java
@@ -40,6 +40,8 @@ package com.sun.nio.sctp;
public interface Notification {
/**
* Returns the association that this notification is applicable to.
+ *
+ * @return The association
*/
public Association association();
}
diff --git a/jdk/src/share/classes/com/sun/nio/sctp/SctpChannel.java b/jdk/src/share/classes/com/sun/nio/sctp/SctpChannel.java
index 0b351a4ca3f..22cf07650f4 100644
--- a/jdk/src/share/classes/com/sun/nio/sctp/SctpChannel.java
+++ b/jdk/src/share/classes/com/sun/nio/sctp/SctpChannel.java
@@ -59,7 +59,7 @@ import java.nio.channels.SelectionKey;
* {@link #setOption(SctpSocketOption,Object) setOption} method. An SCTP
* channel support the following options:
*
- *
+ *
*
* Option Name |
* Description |
@@ -636,6 +636,9 @@ public abstract class SctpChannel
/**
* Returns the value of a socket option.
*
+ * @param
+ * The type of the socket option value
+ *
* @param name
* The socket option
*
@@ -659,6 +662,9 @@ public abstract class SctpChannel
/**
* Sets the value of a socket option.
*
+ * @param
+ * The type of the socket option value
+ *
* @param name
* The socket option
*
@@ -752,6 +758,9 @@ public abstract class SctpChannel
* the {@code receive} method of this channel, if it does an
* {@link IllegalReceiveException} will be thrown.
*
+ * @param
+ * The type of the attachment
+ *
* @param dst
* The buffer into which message bytes are to be transferred
*
@@ -831,7 +840,7 @@ public abstract class SctpChannel
* there was insufficient room for the message in the underlying
* output buffer
*
- * @throws InvalidStreamExcepton
+ * @throws InvalidStreamException
* If {@code streamNumner} is negative or greater than or equal to
* the maximum number of outgoing streams
*
diff --git a/jdk/src/share/classes/com/sun/nio/sctp/SctpMultiChannel.java b/jdk/src/share/classes/com/sun/nio/sctp/SctpMultiChannel.java
index f8745dba41e..42e56591e43 100644
--- a/jdk/src/share/classes/com/sun/nio/sctp/SctpMultiChannel.java
+++ b/jdk/src/share/classes/com/sun/nio/sctp/SctpMultiChannel.java
@@ -63,7 +63,7 @@ import java.nio.channels.SelectionKey;
* {@link #setOption(SctpSocketOption,Object,Association) setOption} method. An
* {@code SctpMultiChannel} supports the following options:
*
- *
+ *
*
* Option Name |
* Description |
@@ -394,6 +394,9 @@ public abstract class SctpMultiChannel
* Returns all of the remote addresses to which the given association on
* this channel's socket is connected.
*
+ * @param association
+ * The association
+ *
* @return All of the remote addresses for the given association, or
* an empty {@code Set} if the association has been shutdown
*
@@ -431,6 +434,9 @@ public abstract class SctpMultiChannel
* ignored if given. However, if the option is association specific then the
* association must be given.
*
+ * @param
+ * The type of the socket option value
+ *
* @param name
* The socket option
*
@@ -464,6 +470,9 @@ public abstract class SctpMultiChannel
* ignored if given. However, if the option is association specific then the
* association must be given.
*
+ * @param
+ * The type of the socket option value
+ *
* @param name
* The socket option
*
@@ -567,6 +576,9 @@ public abstract class SctpMultiChannel
* the {@code receive} method of this channel, if it does an
* {@link IllegalReceiveException} will be thrown.
*
+ * @param
+ * The type of the attachment
+ *
* @param buffer
* The buffer into which bytes are to be transferred
*
@@ -673,7 +685,7 @@ public abstract class SctpMultiChannel
* there was insufficient room for the message in the underlying
* output buffer
*
- * @throws InvalidStreamExcepton
+ * @throws InvalidStreamException
* If {@code streamNumber} is negative, or if an association already
* exists and {@code streamNumber} is greater than the maximum number
* of outgoing streams
diff --git a/jdk/src/share/classes/com/sun/nio/sctp/SctpServerChannel.java b/jdk/src/share/classes/com/sun/nio/sctp/SctpServerChannel.java
index 637df72d394..c96e516ca4d 100644
--- a/jdk/src/share/classes/com/sun/nio/sctp/SctpServerChannel.java
+++ b/jdk/src/share/classes/com/sun/nio/sctp/SctpServerChannel.java
@@ -47,7 +47,7 @@ import java.nio.channels.spi.AbstractSelectableChannel;
* {@link #setOption(SctpSocketOption,Object) setOption} method. SCTP server socket
* channels support the following options:
*
- *
+ *
*
* Option Name |
* Description |
@@ -345,6 +345,9 @@ public abstract class SctpServerChannel
/**
* Returns the value of a socket option.
*
+ * @param
+ * The type of the socket option value
+ *
* @param name
* The socket option
*
@@ -367,6 +370,9 @@ public abstract class SctpServerChannel
/**
* Sets the value of a socket option.
*
+ * @param
+ * The type of the socket option value
+ *
* @param name
* The socket option
*
diff --git a/jdk/src/share/classes/java/awt/TextComponent.java b/jdk/src/share/classes/java/awt/TextComponent.java
index 7a6cd26bbf3..483657fd4ce 100644
--- a/jdk/src/share/classes/java/awt/TextComponent.java
+++ b/jdk/src/share/classes/java/awt/TextComponent.java
@@ -35,6 +35,7 @@ import java.text.BreakIterator;
import javax.swing.text.AttributeSet;
import javax.accessibility.*;
import java.awt.im.InputMethodRequests;
+import sun.security.util.SecurityConstants;
/**
* The TextComponent class is the superclass of
@@ -728,7 +729,7 @@ public class TextComponent extends Component implements Accessible {
SecurityManager sm = System.getSecurityManager();
if (sm == null) return true;
try {
- sm.checkSystemClipboardAccess();
+ sm.checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION);
return true;
} catch (SecurityException e) {}
return false;
diff --git a/jdk/src/share/classes/java/awt/Toolkit.java b/jdk/src/share/classes/java/awt/Toolkit.java
index 92bedb7580b..32f0adab3bc 100644
--- a/jdk/src/share/classes/java/awt/Toolkit.java
+++ b/jdk/src/share/classes/java/awt/Toolkit.java
@@ -1270,12 +1270,8 @@ public abstract class Toolkit {
*
* Each actual implementation of this method should first check if there
* is a security manager installed. If there is, the method should call
- * the security manager's checkSystemClipboardAccess method
- * to ensure it's ok to to access the system clipboard. If the default
- * implementation of checkSystemClipboardAccess is used (that
- * is, that method is not overriden), then this results in a call to the
- * security manager's checkPermission method with an
- * AWTPermission("accessClipboard") permission.
+ * the security manager's {@link SecurityManager#checkPermission
+ * checkPermission} method to check {@code AWTPermission("accessClipboard")}.
*
* @return the system Clipboard
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
@@ -1318,14 +1314,9 @@ public abstract class Toolkit {
* system selection Clipboard as described above.
*
* Each actual implementation of this method should first check if there
- * is a SecurityManager installed. If there is, the method
- * should call the SecurityManager 's
- * checkSystemClipboardAccess method to ensure that client
- * code has access the system selection. If the default implementation of
- * checkSystemClipboardAccess is used (that is, if the method
- * is not overridden), then this results in a call to the
- * SecurityManager 's checkPermission method with
- * an AWTPermission("accessClipboard") permission.
+ * is a security manager installed. If there is, the method should call
+ * the security manager's {@link SecurityManager#checkPermission
+ * checkPermission} method to check {@code AWTPermission("accessClipboard")}.
*
* @return the system selection as a Clipboard , or
* null if the native platform does not support a
@@ -1699,25 +1690,20 @@ public abstract class Toolkit {
* therefore not assume that the EventQueue instance returned
* by this method will be shared by other applets or the system.
*
- * First, if there is a security manager, its
- * checkAwtEventQueueAccess
- * method is called.
- * If the default implementation of checkAwtEventQueueAccess
- * is used (that is, that method is not overriden), then this results in
- * a call to the security manager's checkPermission method
- * with an AWTPermission("accessEventQueue") permission.
+ * If there is a security manager then its
+ * {@link SecurityManager#checkPermission checkPermission} method
+ * is called to check {@code AWTPermission("accessEventQueue")}.
*
* @return the EventQueue object
* @throws SecurityException
- * if a security manager exists and its {@link
- * java.lang.SecurityManager#checkAwtEventQueueAccess}
- * method denies access to the EventQueue
+ * if a security manager is set and it denies access to
+ * the {@code EventQueue}
* @see java.awt.AWTPermission
*/
public final EventQueue getSystemEventQueue() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
- security.checkAwtEventQueueAccess();
+ security.checkPermission(SecurityConstants.AWT.CHECK_AWT_EVENTQUEUE_PERMISSION);
}
return getSystemEventQueueImpl();
}
diff --git a/jdk/src/share/classes/java/awt/Window.java b/jdk/src/share/classes/java/awt/Window.java
index 4076939c7f0..c10a3b277a8 100644
--- a/jdk/src/share/classes/java/awt/Window.java
+++ b/jdk/src/share/classes/java/awt/Window.java
@@ -195,10 +195,9 @@ public class Window extends Container implements Accessible {
/**
* This represents the warning message that is
* to be displayed in a non secure window. ie :
- * a window that has a security manager installed for
- * which calling SecurityManager.checkTopLevelWindow()
- * is false. This message can be displayed anywhere in
- * the window.
+ * a window that has a security manager installed that denies
+ * {@code AWTPermission("showWindowWithoutWarningBanner")}.
+ * This message can be displayed anywhere in the window.
*
* @serial
* @see #getWarningString
@@ -417,11 +416,10 @@ public class Window extends Container implements Accessible {
* Constructs a new, initially invisible window in default size with the
* specified {@code GraphicsConfiguration}.
*
- * If there is a security manager, this method first calls
- * the security manager's {@code checkTopLevelWindow}
- * method with {@code this}
- * as its argument to determine whether or not the window
- * must be displayed with a warning banner.
+ * If there is a security manager, then it is invoked to check
+ * {@code AWTPermission("showWindowWithoutWarningBanner")}
+ * to determine whether or not the window must be displayed with
+ * a warning banner.
*
* @param gc the {@code GraphicsConfiguration} of the target screen
* device. If {@code gc} is {@code null}, the system default
@@ -432,7 +430,6 @@ public class Window extends Container implements Accessible {
* {@code GraphicsEnvironment.isHeadless()} returns {@code true}
*
* @see java.awt.GraphicsEnvironment#isHeadless
- * @see java.lang.SecurityManager#checkTopLevelWindow
*/
Window(GraphicsConfiguration gc) {
init(gc);
@@ -511,25 +508,16 @@ public class Window extends Container implements Accessible {
/**
* Constructs a new, initially invisible window in the default size.
- *
- * First, if there is a security manager, its
- * {@code checkTopLevelWindow}
- * method is called with {@code this}
- * as its argument
- * to see if it's ok to display the window without a warning banner.
- * If the default implementation of {@code checkTopLevelWindow}
- * is used (that is, that method is not overriden), then this results in
- * a call to the security manager's {@code checkPermission} method
- * with an {@code AWTPermission("showWindowWithoutWarningBanner")}
- * permission. It that method raises a SecurityException,
- * {@code checkTopLevelWindow} returns false, otherwise it
- * returns true. If it returns false, a warning banner is created.
+ *
+ * If there is a security manager set, it is invoked to check
+ * {@code AWTPermission("showWindowWithoutWarningBanner")}.
+ * If that check fails with a {@code SecurityException} then a warning
+ * banner is created.
*
* @exception HeadlessException when
* {@code GraphicsEnvironment.isHeadless()} returns {@code true}
*
* @see java.awt.GraphicsEnvironment#isHeadless
- * @see java.lang.SecurityManager#checkTopLevelWindow
*/
Window() throws HeadlessException {
GraphicsEnvironment.checkHeadless();
@@ -541,11 +529,10 @@ public class Window extends Container implements Accessible {
* {@code Frame} as its owner. The window will not be focusable
* unless its owner is showing on the screen.
*
- * If there is a security manager, this method first calls
- * the security manager's {@code checkTopLevelWindow}
- * method with {@code this}
- * as its argument to determine whether or not the window
- * must be displayed with a warning banner.
+ * If there is a security manager set, it is invoked to check
+ * {@code AWTPermission("showWindowWithoutWarningBanner")}.
+ * If that check fails with a {@code SecurityException} then a warning
+ * banner is created.
*
* @param owner the {@code Frame} to act as owner or {@code null}
* if this window has no owner
@@ -555,7 +542,6 @@ public class Window extends Container implements Accessible {
* {@code GraphicsEnvironment.isHeadless} returns {@code true}
*
* @see java.awt.GraphicsEnvironment#isHeadless
- * @see java.lang.SecurityManager#checkTopLevelWindow
* @see #isShowing
*/
public Window(Frame owner) {
@@ -570,11 +556,10 @@ public class Window extends Container implements Accessible {
* unless its nearest owning {@code Frame} or {@code Dialog}
* is showing on the screen.
*
- * If there is a security manager, this method first calls
- * the security manager's {@code checkTopLevelWindow}
- * method with {@code this}
- * as its argument to determine whether or not the window
- * must be displayed with a warning banner.
+ * If there is a security manager set, it is invoked to check
+ * {@code AWTPermission("showWindowWithoutWarningBanner")}.
+ * If that check fails with a {@code SecurityException} then a
+ * warning banner is created.
*
* @param owner the {@code Window} to act as owner or
* {@code null} if this window has no owner
@@ -585,7 +570,6 @@ public class Window extends Container implements Accessible {
* {@code true}
*
* @see java.awt.GraphicsEnvironment#isHeadless
- * @see java.lang.SecurityManager#checkTopLevelWindow
* @see #isShowing
*
* @since 1.2
@@ -603,11 +587,10 @@ public class Window extends Container implements Accessible {
* its nearest owning {@code Frame} or {@code Dialog}
* is showing on the screen.
*
- * If there is a security manager, this method first calls
- * the security manager's {@code checkTopLevelWindow}
- * method with {@code this}
- * as its argument to determine whether or not the window
- * must be displayed with a warning banner.
+ * If there is a security manager set, it is invoked to check
+ * {@code AWTPermission("showWindowWithoutWarningBanner")}. If that
+ * check fails with a {@code SecurityException} then a warning banner
+ * is created.
*
* @param owner the window to act as owner or {@code null}
* if this window has no owner
@@ -621,7 +604,6 @@ public class Window extends Container implements Accessible {
* {@code true}
*
* @see java.awt.GraphicsEnvironment#isHeadless
- * @see java.lang.SecurityManager#checkTopLevelWindow
* @see GraphicsConfiguration#getBounds
* @see #isShowing
* @since 1.3
@@ -1362,10 +1344,9 @@ public class Window extends Container implements Accessible {
* Gets the warning string that is displayed with this window.
* If this window is insecure, the warning string is displayed
* somewhere in the visible area of the window. A window is
- * insecure if there is a security manager, and the security
- * manager's {@code checkTopLevelWindow} method returns
- * {@code false} when this window is passed to it as an
- * argument.
+ * insecure if there is a security manager and the security
+ * manager denies
+ * {@code AWTPermission("showWindowWithoutWarningBanner")}.
*
* If the window is secure, then {@code getWarningString}
* returns {@code null}. If the window is insecure, this
@@ -1373,7 +1354,6 @@ public class Window extends Container implements Accessible {
* {@code awt.appletWarning}
* and returns the string value of that property.
* @return the warning string for this window.
- * @see java.lang.SecurityManager#checkTopLevelWindow(java.lang.Object)
*/
public final String getWarningString() {
return warningString;
@@ -1383,10 +1363,12 @@ public class Window extends Container implements Accessible {
warningString = null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- if (!sm.checkTopLevelWindow(this)) {
+ try {
+ sm.checkPermission(SecurityConstants.AWT.TOPLEVEL_WINDOW_PERMISSION);
+ } catch (SecurityException se) {
// make sure the privileged action is only
// for getting the property! We don't want the
- // above checkTopLevelWindow call to always succeed!
+ // above checkPermission call to always succeed!
warningString = AccessController.doPrivileged(
new GetPropertyAction("awt.appletWarning",
"Java Applet Window"));
diff --git a/jdk/src/share/classes/java/awt/color/ICC_Profile.java b/jdk/src/share/classes/java/awt/color/ICC_Profile.java
index c1534249f39..7e44947477d 100644
--- a/jdk/src/share/classes/java/awt/color/ICC_Profile.java
+++ b/jdk/src/share/classes/java/awt/color/ICC_Profile.java
@@ -37,6 +37,7 @@ package java.awt.color;
import sun.java2d.cmm.PCMM;
import sun.java2d.cmm.CMSManager;
+import sun.java2d.cmm.Profile;
import sun.java2d.cmm.ProfileDataVerifier;
import sun.java2d.cmm.ProfileDeferralMgr;
import sun.java2d.cmm.ProfileDeferralInfo;
@@ -94,7 +95,7 @@ public class ICC_Profile implements Serializable {
private static final long serialVersionUID = -3938515861990936766L;
- transient long ID;
+ private transient Profile cmmProfile;
private transient ProfileDeferralInfo deferralInfo;
private transient ProfileActivator profileActivator;
@@ -727,8 +728,8 @@ public class ICC_Profile implements Serializable {
/**
* Constructs an ICC_Profile object with a given ID.
*/
- ICC_Profile(long ID) {
- this.ID = ID;
+ ICC_Profile(Profile p) {
+ this.cmmProfile = p;
}
@@ -751,8 +752,8 @@ public class ICC_Profile implements Serializable {
* Frees the resources associated with an ICC_Profile object.
*/
protected void finalize () {
- if (ID != 0) {
- CMSManager.getModule().freeProfile(ID);
+ if (cmmProfile != null) {
+ CMSManager.getModule().freeProfile(cmmProfile);
} else if (profileActivator != null) {
ProfileDeferralMgr.unregisterDeferral(profileActivator);
}
@@ -770,7 +771,7 @@ public class ICC_Profile implements Serializable {
public static ICC_Profile getInstance(byte[] data) {
ICC_Profile thisProfile;
- long theID;
+ Profile p = null;
if (ProfileDeferralMgr.deferring) {
ProfileDeferralMgr.activateProfiles();
@@ -779,32 +780,32 @@ public class ICC_Profile implements Serializable {
ProfileDataVerifier.verify(data);
try {
- theID = CMSManager.getModule().loadProfile(data);
+ p = CMSManager.getModule().loadProfile(data);
} catch (CMMException c) {
throw new IllegalArgumentException("Invalid ICC Profile Data");
}
try {
- if ((getColorSpaceType (theID) == ColorSpace.TYPE_GRAY) &&
- (getData (theID, icSigMediaWhitePointTag) != null) &&
- (getData (theID, icSigGrayTRCTag) != null)) {
- thisProfile = new ICC_ProfileGray (theID);
+ if ((getColorSpaceType (p) == ColorSpace.TYPE_GRAY) &&
+ (getData (p, icSigMediaWhitePointTag) != null) &&
+ (getData (p, icSigGrayTRCTag) != null)) {
+ thisProfile = new ICC_ProfileGray (p);
}
- else if ((getColorSpaceType (theID) == ColorSpace.TYPE_RGB) &&
- (getData (theID, icSigMediaWhitePointTag) != null) &&
- (getData (theID, icSigRedColorantTag) != null) &&
- (getData (theID, icSigGreenColorantTag) != null) &&
- (getData (theID, icSigBlueColorantTag) != null) &&
- (getData (theID, icSigRedTRCTag) != null) &&
- (getData (theID, icSigGreenTRCTag) != null) &&
- (getData (theID, icSigBlueTRCTag) != null)) {
- thisProfile = new ICC_ProfileRGB (theID);
+ else if ((getColorSpaceType (p) == ColorSpace.TYPE_RGB) &&
+ (getData (p, icSigMediaWhitePointTag) != null) &&
+ (getData (p, icSigRedColorantTag) != null) &&
+ (getData (p, icSigGreenColorantTag) != null) &&
+ (getData (p, icSigBlueColorantTag) != null) &&
+ (getData (p, icSigRedTRCTag) != null) &&
+ (getData (p, icSigGreenTRCTag) != null) &&
+ (getData (p, icSigBlueTRCTag) != null)) {
+ thisProfile = new ICC_ProfileRGB (p);
}
else {
- thisProfile = new ICC_Profile (theID);
+ thisProfile = new ICC_Profile (p);
}
} catch (CMMException c) {
- thisProfile = new ICC_Profile (theID);
+ thisProfile = new ICC_Profile (p);
}
return thisProfile;
}
@@ -1119,7 +1120,7 @@ public class ICC_Profile implements Serializable {
fileName);
}
try {
- ID = CMSManager.getModule().loadProfile(profileData);
+ cmmProfile = CMSManager.getModule().loadProfile(profileData);
} catch (CMMException c) {
ProfileDataException pde = new
ProfileDataException("Invalid ICC Profile Data" + fileName);
@@ -1229,14 +1230,14 @@ public class ICC_Profile implements Serializable {
causing a deferred profile
to be loaded */
}
- return getColorSpaceType(ID);
+ return getColorSpaceType(cmmProfile);
}
- static int getColorSpaceType(long profileID) {
+ static int getColorSpaceType(Profile p) {
byte[] theHeader;
int theColorSpaceSig, theColorSpace;
- theHeader = getData(profileID, icSigHead);
+ theHeader = getData(p, icSigHead);
theColorSpaceSig = intFromBigEndian(theHeader, icHdrColorSpace);
theColorSpace = iccCStoJCS (theColorSpaceSig);
return theColorSpace;
@@ -1258,15 +1259,15 @@ public class ICC_Profile implements Serializable {
if (ProfileDeferralMgr.deferring) {
ProfileDeferralMgr.activateProfiles();
}
- return getPCSType(ID);
+ return getPCSType(cmmProfile);
}
- static int getPCSType(long profileID) {
+ static int getPCSType(Profile p) {
byte[] theHeader;
int thePCSSig, thePCS;
- theHeader = getData(profileID, icSigHead);
+ theHeader = getData(p, icSigHead);
thePCSSig = intFromBigEndian(theHeader, icHdrPcs);
thePCS = iccCStoJCS(thePCSSig);
return thePCS;
@@ -1326,12 +1327,12 @@ public class ICC_Profile implements Serializable {
PCMM mdl = CMSManager.getModule();
/* get the number of bytes needed for this profile */
- profileSize = mdl.getProfileSize(ID);
+ profileSize = mdl.getProfileSize(cmmProfile);
profileData = new byte [profileSize];
/* get the data for the profile */
- mdl.getProfileData(ID, profileData);
+ mdl.getProfileData(cmmProfile, profileData);
return profileData;
}
@@ -1358,11 +1359,11 @@ public class ICC_Profile implements Serializable {
ProfileDeferralMgr.activateProfiles();
}
- return getData(ID, tagSignature);
+ return getData(cmmProfile, tagSignature);
}
- static byte[] getData(long profileID, int tagSignature) {
+ static byte[] getData(Profile p, int tagSignature) {
int tagSize;
byte[] tagData;
@@ -1370,12 +1371,12 @@ public class ICC_Profile implements Serializable {
PCMM mdl = CMSManager.getModule();
/* get the number of bytes needed for this tag */
- tagSize = mdl.getTagSize(profileID, tagSignature);
+ tagSize = mdl.getTagSize(p, tagSignature);
tagData = new byte[tagSize]; /* get an array for the tag */
/* get the tag's data */
- mdl.getTagData(profileID, tagSignature, tagData);
+ mdl.getTagData(p, tagSignature, tagData);
} catch(CMMException c) {
tagData = null;
}
@@ -1406,7 +1407,7 @@ public class ICC_Profile implements Serializable {
ProfileDeferralMgr.activateProfiles();
}
- CMSManager.getModule().setTagData(ID, tagSignature, tagData);
+ CMSManager.getModule().setTagData(cmmProfile, tagSignature, tagData);
}
/**
diff --git a/jdk/src/share/classes/java/awt/color/ICC_ProfileGray.java b/jdk/src/share/classes/java/awt/color/ICC_ProfileGray.java
index d9042266663..a868a6f50fc 100644
--- a/jdk/src/share/classes/java/awt/color/ICC_ProfileGray.java
+++ b/jdk/src/share/classes/java/awt/color/ICC_ProfileGray.java
@@ -35,7 +35,7 @@
package java.awt.color;
-import java.awt.image.LookupTable;
+import sun.java2d.cmm.Profile;
import sun.java2d.cmm.ProfileDeferralInfo;
/**
@@ -76,8 +76,8 @@ extends ICC_Profile {
/**
* Constructs a new ICC_ProfileGray from a CMM ID.
*/
- ICC_ProfileGray(long ID) {
- super(ID);
+ ICC_ProfileGray(Profile p) {
+ super(p);
}
/**
diff --git a/jdk/src/share/classes/java/awt/color/ICC_ProfileRGB.java b/jdk/src/share/classes/java/awt/color/ICC_ProfileRGB.java
index b0bad4d9a91..dcf65828650 100644
--- a/jdk/src/share/classes/java/awt/color/ICC_ProfileRGB.java
+++ b/jdk/src/share/classes/java/awt/color/ICC_ProfileRGB.java
@@ -35,7 +35,7 @@
package java.awt.color;
-import java.awt.image.LookupTable;
+import sun.java2d.cmm.Profile;
import sun.java2d.cmm.ProfileDeferralInfo;
/**
@@ -114,8 +114,8 @@ extends ICC_Profile {
* @param ID The CMM ID for the profile.
*
*/
- ICC_ProfileRGB(long ID) {
- super(ID);
+ ICC_ProfileRGB(Profile p) {
+ super(p);
}
/**
diff --git a/jdk/src/share/classes/java/awt/event/InputEvent.java b/jdk/src/share/classes/java/awt/event/InputEvent.java
index 078b1a16d6a..24965d20caf 100644
--- a/jdk/src/share/classes/java/awt/event/InputEvent.java
+++ b/jdk/src/share/classes/java/awt/event/InputEvent.java
@@ -33,6 +33,7 @@ import java.util.Arrays;
import sun.awt.AWTAccessor;
import sun.util.logging.PlatformLogger;
+import sun.security.util.SecurityConstants;
/**
* The root event class for all component-level input events.
@@ -350,7 +351,7 @@ public abstract class InputEvent extends ComponentEvent {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
try {
- sm.checkSystemClipboardAccess();
+ sm.checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION);
b = true;
} catch (SecurityException se) {
if (logger.isLoggable(PlatformLogger.Level.FINE)) {
diff --git a/jdk/src/share/classes/java/io/Console.java b/jdk/src/share/classes/java/io/Console.java
index c100f8a0ccd..292e42eec7c 100644
--- a/jdk/src/share/classes/java/io/Console.java
+++ b/jdk/src/share/classes/java/io/Console.java
@@ -124,9 +124,11 @@ public final class Console implements Flushable
* {@link java.io.Reader#read(java.nio.CharBuffer) read(java.nio.CharBuffer)}
* on the returned object will not read in characters beyond the line
* bound for each invocation, even if the destination buffer has space for
- * more characters. A line bound is considered to be any one of a line feed
- * ('\n'), a carriage return ('\r'), a carriage return
- * followed immediately by a linefeed, or an end of stream.
+ * more characters. The {@code Reader}'s {@code read} methods may block if a
+ * line bound has not been entered or reached on the console's input device.
+ * A line bound is considered to be any one of a line feed ('\n'),
+ * a carriage return ('\r'), a carriage return followed immediately
+ * by a linefeed, or an end of stream.
*
* @return The reader associated with this console
*/
diff --git a/jdk/src/share/classes/java/lang/AutoCloseable.java b/jdk/src/share/classes/java/lang/AutoCloseable.java
index ce0fffe5939..be47cd0835f 100644
--- a/jdk/src/share/classes/java/lang/AutoCloseable.java
+++ b/jdk/src/share/classes/java/lang/AutoCloseable.java
@@ -26,7 +26,24 @@
package java.lang;
/**
- * A resource that must be closed when it is no longer needed.
+ * An object that may hold resources (such as file or socket handles)
+ * until it is closed. The {@link #close()} method of an {@code AutoCloseable}
+ * object is called automatically when exiting a {@code
+ * try}-with-resources block for which the object has been declared in
+ * the resource specification header. This construction ensures prompt
+ * release, avoiding resource exhaustion exceptions and errors that
+ * may otherwise occur.
+ *
+ * @apiNote
+ * It is possible, and in fact common, for a base class to
+ * implement AutoCloseable even though not all of its subclasses or
+ * instances will hold releasable resources. For code that must operate
+ * in complete generality, or when it is known that the {@code AutoCloseable}
+ * instance requires resource release, it is recommended to use {@code
+ * try}-with-resources constructions. However, when using facilities such as
+ * {@link java.util.stream.Stream} that support both I/O-based and
+ * non-I/O-based forms, {@code try}-with-resources blocks are in
+ * general unnecessary when using non-I/O-based forms.
*
* @author Josh Bloch
* @since 1.7
diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java
index a3c962e0838..f884f2efe03 100644
--- a/jdk/src/share/classes/java/lang/Class.java
+++ b/jdk/src/share/classes/java/lang/Class.java
@@ -821,6 +821,10 @@ public final class Class implements java.io.Serializable,
* If this object represents a primitive type or void, the method
* returns an array of length 0.
*
+ * If this {@code Class} object represents an array type, the
+ * interfaces {@code Cloneable} and {@code java.io.Serializable} are
+ * returned in that order.
+ *
* @return an array of interfaces implemented by this class.
*/
public Class>[] getInterfaces() {
@@ -1484,22 +1488,24 @@ public final class Class implements java.io.Serializable,
/**
* Returns an array containing {@code Field} objects reflecting all
* the accessible public fields of the class or interface represented by
- * this {@code Class} object. The elements in the array returned are
- * not sorted and are not in any particular order. This method returns an
- * array of length 0 if the class or interface has no accessible public
- * fields, or if it represents an array class, a primitive type, or void.
+ * this {@code Class} object.
*
- * Specifically, if this {@code Class} object represents a class,
- * this method returns the public fields of this class and of all its
- * superclasses. If this {@code Class} object represents an
- * interface, this method returns the fields of this interface and of all
- * its superinterfaces.
+ * If this {@code Class} object represents a class or interface with no
+ * no accessible public fields, then this method returns an array of length
+ * 0.
*
- * The implicit length field for array class is not reflected by this
- * method. User code should use the methods of class {@code Array} to
- * manipulate arrays.
+ * If this {@code Class} object represents a class, then this method
+ * returns the public fields of the class and of all its superclasses.
*
- * See The Java Language Specification, sections 8.2 and 8.3.
+ * If this {@code Class} object represents an interface, then this
+ * method returns the fields of the interface and of all its
+ * superinterfaces.
+ *
+ * If this {@code Class} object represents an array type, a primitive
+ * type, or void, then this method returns an array of length 0.
+ *
+ * The elements in the returned array are not sorted and are not in any
+ * particular order.
*
* @return the array of {@code Field} objects representing the
* public fields
@@ -1512,6 +1518,8 @@ public final class Class implements java.io.Serializable,
* of this class.
*
* @since JDK1.1
+ * @jls 8.2 Class Members
+ * @jls 8.3 Field Declarations
*/
@CallerSensitive
public Field[] getFields() throws SecurityException {
@@ -1521,23 +1529,33 @@ public final class Class implements java.io.Serializable,
/**
- * Returns an array containing {@code Method} objects reflecting all
- * the public member methods of the class or interface represented
- * by this {@code Class} object, including those declared by the class
- * or interface and those inherited from superclasses and
- * superinterfaces. Array classes return all the (public) member methods
- * inherited from the {@code Object} class. The elements in the array
- * returned are not sorted and are not in any particular order. This
- * method returns an array of length 0 if this {@code Class} object
- * represents a class or interface that has no public member methods, or if
- * this {@code Class} object represents a primitive type or void.
+ * Returns an array containing {@code Method} objects reflecting all the
+ * public methods of the class or interface represented by this {@code
+ * Class} object, including those declared by the class or interface and
+ * those inherited from superclasses and superinterfaces.
*
- * The class initialization method {@code } is not
- * included in the returned array. If the class declares multiple public
- * member methods with the same parameter types, they are all included in
- * the returned array.
+ * If this {@code Class} object represents a type that has multiple
+ * public methods with the same name and parameter types, but different
+ * return types, then the returned array has a {@code Method} object for
+ * each such method.
*
- * See The Java Language Specification, sections 8.2 and 8.4.
+ * If this {@code Class} object represents a type with a class
+ * initialization method {@code }, then the returned array does
+ * not have a corresponding {@code Method} object.
+ *
+ * If this {@code Class} object represents an array type, then the
+ * returned array has a {@code Method} object for each of the public
+ * methods inherited by the array type from {@code Object}. It does not
+ * contain a {@code Method} object for {@code clone()}.
+ *
+ * If this {@code Class} object represents a class or interface with no
+ * public methods, then the returned array has length 0.
+ *
+ * If this {@code Class} object represents a primitive type or void,
+ * then the returned array has length 0.
+ *
+ * The elements in the returned array are not sorted and are not in any
+ * particular order.
*
* @return the array of {@code Method} objects representing the
* public methods of this class
@@ -1549,6 +1567,8 @@ public final class Class implements java.io.Serializable,
* s.checkPackageAccess()} denies access to the package
* of this class.
*
+ * @jls 8.2 Class Members
+ * @jls 8.4 Method Declarations
* @since JDK1.1
*/
@CallerSensitive
@@ -1595,13 +1615,14 @@ public final class Class implements java.io.Serializable,
/**
- * Returns a {@code Field} object that reflects the specified public
- * member field of the class or interface represented by this
- * {@code Class} object. The {@code name} parameter is a
- * {@code String} specifying the simple name of the desired field.
+ * Returns a {@code Field} object that reflects the specified public member
+ * field of the class or interface represented by this {@code Class}
+ * object. The {@code name} parameter is a {@code String} specifying the
+ * simple name of the desired field.
*
* The field to be reflected is determined by the algorithm that
- * follows. Let C be the class represented by this object:
+ * follows. Let C be the class or interface represented by this object:
+ *
*
* - If C declares a public field with the name specified, that is the
* field to be reflected.
@@ -1614,7 +1635,8 @@ public final class Class implements java.io.Serializable,
* is thrown.
*
*
- * See The Java Language Specification, sections 8.2 and 8.3.
+ * If this {@code Class} object represents an array type, then this
+ * method does not find the {@code length} field of the array type.
*
* @param name the field name
* @return the {@code Field} object of this class specified by
@@ -1631,6 +1653,8 @@ public final class Class implements java.io.Serializable,
* of this class.
*
* @since JDK1.1
+ * @jls 8.2 Class Members
+ * @jls 8.3 Field Declarations
*/
@CallerSensitive
public Field getField(String name)
@@ -1685,7 +1709,8 @@ public final class Class implements java.io.Serializable,
* method and the method being overridden would have the same
* signature but different return types.
*
- * See The Java Language Specification, sections 8.2 and 8.4.
+ * If this {@code Class} object represents an array type, then this
+ * method does not find the {@code clone()} method.
*
* @param name the name of the method
* @param parameterTypes the list of parameters
@@ -1702,6 +1727,8 @@ public final class Class implements java.io.Serializable,
* s.checkPackageAccess()} denies access to the package
* of this class.
*
+ * @jls 8.2 Class Members
+ * @jls 8.4 Method Declarations
* @since JDK1.1
*/
@CallerSensitive
@@ -1800,12 +1827,15 @@ public final class Class implements java.io.Serializable,
* declared by the class or interface represented by this
* {@code Class} object. This includes public, protected, default
* (package) access, and private fields, but excludes inherited fields.
- * The elements in the array returned are not sorted and are not in any
- * particular order. This method returns an array of length 0 if the class
- * or interface declares no fields, or if this {@code Class} object
- * represents a primitive type, an array class, or void.
*
- * See The Java Language Specification, sections 8.2 and 8.3.
+ * If this {@code Class} object represents a class or interface with no
+ * declared fields, then this method returns an array of length 0.
+ *
+ * If this {@code Class} object represents an array type, a primitive
+ * type, or void, then this method returns an array of length 0.
+ *
+ * The elements in the returned array are not sorted and are not in any
+ * particular order.
*
* @return the array of {@code Field} objects representing all the
* declared fields of this class
@@ -1831,6 +1861,8 @@ public final class Class implements java.io.Serializable,
*
*
* @since JDK1.1
+ * @jls 8.2 Class Members
+ * @jls 8.3 Field Declarations
*/
@CallerSensitive
public Field[] getDeclaredFields() throws SecurityException {
@@ -1840,20 +1872,29 @@ public final class Class implements java.io.Serializable,
/**
- * Returns an array of {@code Method} objects reflecting all the
- * methods declared by the class or interface represented by this
- * {@code Class} object. This includes public, protected, default
- * (package) access, and private methods, but excludes inherited methods.
- * The elements in the array returned are not sorted and are not in any
- * particular order. This method returns an array of length 0 if the class
- * or interface declares no methods, or if this {@code Class} object
- * represents a primitive type, an array class, or void. The class
- * initialization method {@code } is not included in the
- * returned array. If the class declares multiple public member methods
- * with the same parameter types, they are all included in the returned
- * array.
*
- * See The Java Language Specification, section 8.2.
+ * Returns an array containing {@code Method} objects reflecting all the
+ * declared methods of the class or interface represented by this {@code
+ * Class} object, including public, protected, default (package)
+ * access, and private methods, but excluding inherited methods.
+ *
+ * If this {@code Class} object represents a type that has multiple
+ * declared methods with the same name and parameter types, but different
+ * return types, then the returned array has a {@code Method} object for
+ * each such method.
+ *
+ * If this {@code Class} object represents a type that has a class
+ * initialization method {@code }, then the returned array does
+ * not have a corresponding {@code Method} object.
+ *
+ * If this {@code Class} object represents a class or interface with no
+ * declared methods, then the returned array has length 0.
+ *
+ * If this {@code Class} object represents an array type, a primitive
+ * type, or void, then the returned array has length 0.
+ *
+ * The elements in the returned array are not sorted and are not in any
+ * particular order.
*
* @return the array of {@code Method} objects representing all the
* declared methods of this class
@@ -1878,6 +1919,8 @@ public final class Class implements java.io.Serializable,
*
*
*
+ * @jls 8.2 Class Members
+ * @jls 8.4 Method Declarations
* @since JDK1.1
*/
@CallerSensitive
@@ -1935,9 +1978,11 @@ public final class Class implements java.io.Serializable,
/**
* Returns a {@code Field} object that reflects the specified declared
* field of the class or interface represented by this {@code Class}
- * object. The {@code name} parameter is a {@code String} that
- * specifies the simple name of the desired field. Note that this method
- * will not reflect the {@code length} field of an array class.
+ * object. The {@code name} parameter is a {@code String} that specifies
+ * the simple name of the desired field.
+ *
+ * If this {@code Class} object represents an array type, then this
+ * method does not find the {@code length} field of the array type.
*
* @param name the name of the field
* @return the {@code Field} object for the specified field in this
@@ -1967,6 +2012,8 @@ public final class Class implements java.io.Serializable,
*
*
* @since JDK1.1
+ * @jls 8.2 Class Members
+ * @jls 8.3 Field Declarations
*/
@CallerSensitive
public Field getDeclaredField(String name)
@@ -1994,6 +2041,9 @@ public final class Class implements java.io.Serializable,
* name is "<init>"or "<clinit>" a {@code NoSuchMethodException}
* is raised.
*
+ * If this {@code Class} object represents an array type, then this
+ * method does not find the {@code clone()} method.
+ *
* @param name the name of the method
* @param parameterTypes the parameter array
* @return the {@code Method} object for the method of this class
@@ -2021,6 +2071,8 @@ public final class Class implements java.io.Serializable,
*
*
*
+ * @jls 8.2 Class Members
+ * @jls 8.4 Method Declarations
* @since JDK1.1
*/
@CallerSensitive
diff --git a/jdk/src/share/classes/java/lang/Math.java b/jdk/src/share/classes/java/lang/Math.java
index ae83e4265ad..98e901ac942 100644
--- a/jdk/src/share/classes/java/lang/Math.java
+++ b/jdk/src/share/classes/java/lang/Math.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -646,7 +646,7 @@ public final class Math {
/**
* Returns the closest {@code int} to the argument, with ties
- * rounding up.
+ * rounding to positive infinity.
*
*
* Special cases:
@@ -665,15 +665,37 @@ public final class Math {
* @see java.lang.Integer#MIN_VALUE
*/
public static int round(float a) {
- if (a != 0x1.fffffep-2f) // greatest float value less than 0.5
- return (int)floor(a + 0.5f);
- else
- return 0;
+ int intBits = Float.floatToRawIntBits(a);
+ int biasedExp = (intBits & FloatConsts.EXP_BIT_MASK)
+ >> (FloatConsts.SIGNIFICAND_WIDTH - 1);
+ int shift = (FloatConsts.SIGNIFICAND_WIDTH - 2
+ + FloatConsts.EXP_BIAS) - biasedExp;
+ if ((shift & -32) == 0) { // shift >= 0 && shift < 32
+ // a is a finite number such that pow(2,-32) <= ulp(a) < 1
+ int r = ((intBits & FloatConsts.SIGNIF_BIT_MASK)
+ | (FloatConsts.SIGNIF_BIT_MASK + 1));
+ if (intBits < 0) {
+ r = -r;
+ }
+ // In the comments below each Java expression evaluates to the value
+ // the corresponding mathematical expression:
+ // (r) evaluates to a / ulp(a)
+ // (r >> shift) evaluates to floor(a * 2)
+ // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2)
+ // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2)
+ return ((r >> shift) + 1) >> 1;
+ } else {
+ // a is either
+ // - a finite number with abs(a) < exp(2,FloatConsts.SIGNIFICAND_WIDTH-32) < 1/2
+ // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer
+ // - an infinity or NaN
+ return (int) a;
+ }
}
/**
* Returns the closest {@code long} to the argument, with ties
- * rounding up.
+ * rounding to positive infinity.
*
* Special cases:
* - If the argument is NaN, the result is 0.
@@ -692,10 +714,32 @@ public final class Math {
* @see java.lang.Long#MIN_VALUE
*/
public static long round(double a) {
- if (a != 0x1.fffffffffffffp-2) // greatest double value less than 0.5
- return (long)floor(a + 0.5d);
- else
- return 0;
+ long longBits = Double.doubleToRawLongBits(a);
+ long biasedExp = (longBits & DoubleConsts.EXP_BIT_MASK)
+ >> (DoubleConsts.SIGNIFICAND_WIDTH - 1);
+ long shift = (DoubleConsts.SIGNIFICAND_WIDTH - 2
+ + DoubleConsts.EXP_BIAS) - biasedExp;
+ if ((shift & -64) == 0) { // shift >= 0 && shift < 64
+ // a is a finite number such that pow(2,-64) <= ulp(a) < 1
+ long r = ((longBits & DoubleConsts.SIGNIF_BIT_MASK)
+ | (DoubleConsts.SIGNIF_BIT_MASK + 1));
+ if (longBits < 0) {
+ r = -r;
+ }
+ // In the comments below each Java expression evaluates to the value
+ // the corresponding mathematical expression:
+ // (r) evaluates to a / ulp(a)
+ // (r >> shift) evaluates to floor(a * 2)
+ // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2)
+ // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2)
+ return ((r >> shift) + 1) >> 1;
+ } else {
+ // a is either
+ // - a finite number with abs(a) < exp(2,DoubleConsts.SIGNIFICAND_WIDTH-64) < 1/2
+ // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer
+ // - an infinity or NaN
+ return (long) a;
+ }
}
private static final class RandomNumberGeneratorHolder {
diff --git a/jdk/src/share/classes/java/lang/SecurityManager.java b/jdk/src/share/classes/java/lang/SecurityManager.java
index 34be905bd02..3565082033c 100644
--- a/jdk/src/share/classes/java/lang/SecurityManager.java
+++ b/jdk/src/share/classes/java/lang/SecurityManager.java
@@ -1336,9 +1336,16 @@ class SecurityManager {
* top-level windows;
false otherwise.
* @exception NullPointerException if the window argument is
* null .
+ * @deprecated The dependency on {@code AWTPermission} creates an
+ * impediment to future modularization of the Java platform.
+ * Users of this method should instead invoke
+ * {@link #checkPermission} directly.
+ * This method will be changed in a future release to check
+ * the permission {@code java.security.AllPermission}.
* @see java.awt.Window
* @see #checkPermission(java.security.Permission) checkPermission
*/
+ @Deprecated
public boolean checkTopLevelWindow(Object window) {
if (window == null) {
throw new NullPointerException("window can't be null");
@@ -1398,8 +1405,15 @@ class SecurityManager {
* @since JDK1.1
* @exception SecurityException if the calling thread does not have
* permission to access the system clipboard.
+ * @deprecated The dependency on {@code AWTPermission} creates an
+ * impediment to future modularization of the Java platform.
+ * Users of this method should instead invoke
+ * {@link #checkPermission} directly.
+ * This method will be changed in a future release to check
+ * the permission {@code java.security.AllPermission}.
* @see #checkPermission(java.security.Permission) checkPermission
*/
+ @Deprecated
public void checkSystemClipboardAccess() {
Permission perm = SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION;
if (perm == null) {
@@ -1427,8 +1441,15 @@ class SecurityManager {
* @since JDK1.1
* @exception SecurityException if the calling thread does not have
* permission to access the AWT event queue.
+ * @deprecated The dependency on {@code AWTPermission} creates an
+ * impediment to future modularization of the Java platform.
+ * Users of this method should instead invoke
+ * {@link #checkPermission} directly.
+ * This method will be changed in a future release to check
+ * the permission {@code java.security.AllPermission}.
* @see #checkPermission(java.security.Permission) checkPermission
*/
+ @Deprecated
public void checkAwtEventQueueAccess() {
Permission perm = SecurityConstants.AWT.CHECK_AWT_EVENTQUEUE_PERMISSION;
if (perm == null) {
diff --git a/jdk/src/share/classes/java/lang/StrictMath.java b/jdk/src/share/classes/java/lang/StrictMath.java
index 52336484e75..ae4af2bcac8 100644
--- a/jdk/src/share/classes/java/lang/StrictMath.java
+++ b/jdk/src/share/classes/java/lang/StrictMath.java
@@ -633,7 +633,7 @@ public final class StrictMath {
/**
* Returns the closest {@code int} to the argument, with ties
- * rounding up.
+ * rounding to positive infinity.
*
* Special cases:
* - If the argument is NaN, the result is 0.
@@ -656,7 +656,7 @@ public final class StrictMath {
/**
* Returns the closest {@code long} to the argument, with ties
- * rounding up.
+ * rounding to positive infinity.
*
*
Special cases:
* - If the argument is NaN, the result is 0.
diff --git a/jdk/src/share/classes/java/lang/String.java b/jdk/src/share/classes/java/lang/String.java
index 651a85017ed..2231aa3bb71 100644
--- a/jdk/src/share/classes/java/lang/String.java
+++ b/jdk/src/share/classes/java/lang/String.java
@@ -2457,8 +2457,8 @@ public final class String
* String message = String.join(" ", strings);
* //message returned is: "Java is cool"
*
- * Set strings = new HashSet<>();
- * Strings.add("Java"); strings.add("is");
+ * Set strings = new LinkedHashSet<>();
+ * strings.add("Java"); strings.add("is");
* strings.add("very"); strings.add("cool");
* String message = String.join("-", strings);
* //message returned is: "Java-is-very-cool"
@@ -2652,7 +2652,7 @@ public final class String
* returns {@code "t\u005Cu0131tle"}, where '\u005Cu0131' is the
* LATIN SMALL LETTER DOTLESS I character.
* To obtain correct results for locale insensitive strings, use
- * {@code toLowerCase(Locale.ENGLISH)}.
+ * {@code toLowerCase(Locale.ROOT)}.
*
* @return the {@code String}, converted to lowercase.
* @see java.lang.String#toLowerCase(Locale)
@@ -2815,7 +2815,7 @@ public final class String
* returns {@code "T\u005Cu0130TLE"}, where '\u005Cu0130' is the
* LATIN CAPITAL LETTER I WITH DOT ABOVE character.
* To obtain correct results for locale insensitive strings, use
- * {@code toUpperCase(Locale.ENGLISH)}.
+ * {@code toUpperCase(Locale.ROOT)}.
*
* @return the {@code String}, converted to uppercase.
* @see java.lang.String#toUpperCase(Locale)
diff --git a/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java b/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java
index 79b3b69fcf3..92a44a048f3 100644
--- a/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java
+++ b/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java
@@ -124,7 +124,7 @@ import static sun.invoke.util.Wrapper.isWrapperType;
this.samMethodType = samMethodType;
this.implMethod = implMethod;
- this.implInfo = new MethodHandleInfo(implMethod);
+ this.implInfo = caller.revealDirect(implMethod);
// @@@ Temporary work-around pending resolution of 8005119
this.implKind = (implInfo.getReferenceKind() == MethodHandleInfo.REF_invokeSpecial)
? MethodHandleInfo.REF_invokeVirtual
diff --git a/jdk/src/share/classes/java/lang/invoke/InfoFromMemberName.java b/jdk/src/share/classes/java/lang/invoke/InfoFromMemberName.java
new file mode 100644
index 00000000000..0ecd005a8d3
--- /dev/null
+++ b/jdk/src/share/classes/java/lang/invoke/InfoFromMemberName.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.invoke;
+
+import java.security.*;
+import java.lang.reflect.*;
+import java.lang.invoke.MethodHandleNatives.Constants;
+import java.lang.invoke.MethodHandles.Lookup;
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/*
+ * Auxiliary to MethodHandleInfo, wants to nest in MethodHandleInfo but must be non-public.
+ */
+/*non-public*/
+final
+class InfoFromMemberName implements MethodHandleInfo {
+ private final MemberName member;
+ private final int referenceKind;
+
+ InfoFromMemberName(Lookup lookup, MemberName member, byte referenceKind) {
+ assert(member.isResolved() || member.isMethodHandleInvoke());
+ assert(member.referenceKindIsConsistentWith(referenceKind));
+ this.member = member;
+ this.referenceKind = referenceKind;
+ }
+
+ @Override
+ public Class> getDeclaringClass() {
+ return member.getDeclaringClass();
+ }
+
+ @Override
+ public String getName() {
+ return member.getName();
+ }
+
+ @Override
+ public MethodType getMethodType() {
+ return member.getMethodOrFieldType();
+ }
+
+ @Override
+ public int getModifiers() {
+ return member.getModifiers();
+ }
+
+ @Override
+ public int getReferenceKind() {
+ return referenceKind;
+ }
+
+ @Override
+ public String toString() {
+ return MethodHandleInfo.toString(getReferenceKind(), getDeclaringClass(), getName(), getMethodType());
+ }
+
+ @Override
+ public T reflectAs(Class expected, Lookup lookup) {
+ if (member.isMethodHandleInvoke() && !member.isVarargs()) {
+ // This member is an instance of a signature-polymorphic method, which cannot be reflected
+ // A method handle invoker can come in either of two forms:
+ // A generic placeholder (present in the source code, and varargs)
+ // and a signature-polymorphic instance (synthetic and not varargs).
+ // For more information see comments on {@link MethodHandleNatives#linkMethod}.
+ throw new IllegalArgumentException("cannot reflect signature polymorphic method");
+ }
+ Member mem = AccessController.doPrivileged(new PrivilegedAction() {
+ public Member run() {
+ try {
+ return reflectUnchecked();
+ } catch (ReflectiveOperationException ex) {
+ throw new IllegalArgumentException(ex);
+ }
+ }
+ });
+ try {
+ Class> defc = getDeclaringClass();
+ byte refKind = (byte) getReferenceKind();
+ lookup.checkAccess(refKind, defc, convertToMemberName(refKind, mem));
+ } catch (IllegalAccessException ex) {
+ throw new IllegalArgumentException(ex);
+ }
+ return expected.cast(mem);
+ }
+
+ private Member reflectUnchecked() throws ReflectiveOperationException {
+ byte refKind = (byte) getReferenceKind();
+ Class> defc = getDeclaringClass();
+ boolean isPublic = Modifier.isPublic(getModifiers());
+ if (MethodHandleNatives.refKindIsMethod(refKind)) {
+ if (isPublic)
+ return defc.getMethod(getName(), getMethodType().parameterArray());
+ else
+ return defc.getDeclaredMethod(getName(), getMethodType().parameterArray());
+ } else if (MethodHandleNatives.refKindIsConstructor(refKind)) {
+ if (isPublic)
+ return defc.getConstructor(getMethodType().parameterArray());
+ else
+ return defc.getDeclaredConstructor(getMethodType().parameterArray());
+ } else if (MethodHandleNatives.refKindIsField(refKind)) {
+ if (isPublic)
+ return defc.getField(getName());
+ else
+ return defc.getDeclaredField(getName());
+ } else {
+ throw new IllegalArgumentException("referenceKind="+refKind);
+ }
+ }
+
+ private static MemberName convertToMemberName(byte refKind, Member mem) throws IllegalAccessException {
+ if (mem instanceof Method) {
+ boolean wantSpecial = (refKind == REF_invokeSpecial);
+ return new MemberName((Method) mem, wantSpecial);
+ } else if (mem instanceof Constructor) {
+ return new MemberName((Constructor) mem);
+ } else if (mem instanceof Field) {
+ boolean isSetter = (refKind == REF_putField || refKind == REF_putStatic);
+ return new MemberName((Field) mem, isSetter);
+ }
+ throw new InternalError(mem.getClass().getName());
+ }
+}
diff --git a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
index 3ddf5d4c1c5..6228c07b7b0 100644
--- a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
+++ b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
@@ -612,6 +612,12 @@ class InvokerBytecodeGenerator {
return false; // inner class of some sort
if (cls.getClassLoader() != MethodHandle.class.getClassLoader())
return false; // not on BCP
+ MethodType mtype = member.getMethodOrFieldType();
+ if (!isStaticallyNameable(mtype.returnType()))
+ return false;
+ for (Class> ptype : mtype.parameterArray())
+ if (!isStaticallyNameable(ptype))
+ return false;
if (!member.isPrivate() && VerifyAccess.isSamePackage(MethodHandle.class, cls))
return true; // in java.lang.invoke package
if (member.isPublic() && isStaticallyNameable(cls))
diff --git a/jdk/src/share/classes/java/lang/invoke/Invokers.java b/jdk/src/share/classes/java/lang/invoke/Invokers.java
index 8d8e019d722..0ef6078b6b5 100644
--- a/jdk/src/share/classes/java/lang/invoke/Invokers.java
+++ b/jdk/src/share/classes/java/lang/invoke/Invokers.java
@@ -87,6 +87,7 @@ class Invokers {
lform = invokeForm(mtype, true, MethodTypeForm.LF_EX_INVOKER);
invoker = SimpleMethodHandle.make(invokerType, lform);
}
+ invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke("invokeExact", mtype));
assert(checkInvoker(invoker));
exactInvoker = invoker;
return invoker;
@@ -110,6 +111,7 @@ class Invokers {
lform = invokeForm(mtype, true, MethodTypeForm.LF_GEN_INVOKER);
invoker = SimpleMethodHandle.make(invokerType, lform);
}
+ invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke("invoke", mtype));
assert(checkInvoker(invoker));
generalInvoker = invoker;
return invoker;
diff --git a/jdk/src/share/classes/java/lang/invoke/MemberName.java b/jdk/src/share/classes/java/lang/invoke/MemberName.java
index dfb468417d6..910574befe7 100644
--- a/jdk/src/share/classes/java/lang/invoke/MemberName.java
+++ b/jdk/src/share/classes/java/lang/invoke/MemberName.java
@@ -320,14 +320,18 @@ import java.util.Objects;
/** Utility method to query if this member is a method handle invocation (invoke or invokeExact). */
public boolean isMethodHandleInvoke() {
- final int bits = Modifier.NATIVE | Modifier.FINAL;
+ final int bits = MH_INVOKE_MODS;
final int negs = Modifier.STATIC;
if (testFlags(bits | negs, bits) &&
clazz == MethodHandle.class) {
- return name.equals("invoke") || name.equals("invokeExact");
+ return isMethodHandleInvokeName(name);
}
return false;
}
+ public static boolean isMethodHandleInvokeName(String name) {
+ return name.equals("invoke") || name.equals("invokeExact");
+ }
+ private static final int MH_INVOKE_MODS = Modifier.NATIVE | Modifier.FINAL | Modifier.PUBLIC;
/** Utility method to query the modifier flags of this member. */
public boolean isStatic() {
@@ -482,12 +486,27 @@ import java.util.Objects;
m.getClass(); // NPE check
// fill in vmtarget, vmindex while we have m in hand:
MethodHandleNatives.init(this, m);
+ if (clazz == null) { // MHN.init failed
+ if (m.getDeclaringClass() == MethodHandle.class &&
+ isMethodHandleInvokeName(m.getName())) {
+ // The JVM did not reify this signature-polymorphic instance.
+ // Need a special case here.
+ // See comments on MethodHandleNatives.linkMethod.
+ MethodType type = MethodType.methodType(m.getReturnType(), m.getParameterTypes());
+ int flags = flagsMods(IS_METHOD, m.getModifiers(), REF_invokeVirtual);
+ init(MethodHandle.class, m.getName(), type, flags);
+ if (isMethodHandleInvoke())
+ return;
+ }
+ throw new LinkageError(m.toString());
+ }
assert(isResolved() && this.clazz != null);
this.name = m.getName();
if (this.type == null)
this.type = new Object[] { m.getReturnType(), m.getParameterTypes() };
if (wantSpecial) {
- assert(!isAbstract()) : this;
+ if (isAbstract())
+ throw new AbstractMethodError(this.toString());
if (getReferenceKind() == REF_invokeVirtual)
changeReferenceKind(REF_invokeSpecial, REF_invokeVirtual);
else if (getReferenceKind() == REF_invokeInterface)
@@ -562,6 +581,22 @@ import java.util.Objects;
initResolved(true);
}
+ /**
+ * Create a name for a signature-polymorphic invoker.
+ * This is a placeholder for a signature-polymorphic instance
+ * (of MH.invokeExact, etc.) that the JVM does not reify.
+ * See comments on {@link MethodHandleNatives#linkMethod}.
+ */
+ static MemberName makeMethodHandleInvoke(String name, MethodType type) {
+ return makeMethodHandleInvoke(name, type, MH_INVOKE_MODS | SYNTHETIC);
+ }
+ static MemberName makeMethodHandleInvoke(String name, MethodType type, int mods) {
+ MemberName mem = new MemberName(MethodHandle.class, name, type, REF_invokeVirtual);
+ mem.flags |= mods; // it's not resolved, but add these modifiers anyway
+ assert(mem.isMethodHandleInvoke()) : mem;
+ return mem;
+ }
+
// bare-bones constructor; the JVM will fill it in
MemberName() { }
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java
index df784d35e5b..613d223fe2a 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java
@@ -1284,6 +1284,21 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
return null; // DMH returns DMH.member
}
+ /*non-public*/
+ MethodHandle withInternalMemberName(MemberName member) {
+ if (member != null) {
+ return MethodHandleImpl.makeWrappedMember(this, member);
+ } else if (internalMemberName() == null) {
+ // The required internaMemberName is null, and this MH (like most) doesn't have one.
+ return this;
+ } else {
+ // The following case is rare. Mask the internalMemberName by wrapping the MH in a BMH.
+ MethodHandle result = rebind();
+ assert (result.internalMemberName() == null);
+ return result;
+ }
+ }
+
/*non-public*/
boolean isInvokeSpecial() {
return false; // DMH.Special returns true
@@ -1356,7 +1371,7 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
MethodHandle rebind() {
// Bind 'this' into a new invoker, of the known class BMH.
MethodType type2 = type();
- LambdaForm form2 = reinvokerForm(type2.basicType());
+ LambdaForm form2 = reinvokerForm(this);
// form2 = lambda (bmh, arg*) { thismh = bmh[0]; invokeBasic(thismh, arg*) }
return BoundMethodHandle.bindSingle(type2, form2, this);
}
@@ -1369,23 +1384,38 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
/** Create a LF which simply reinvokes a target of the given basic type.
* The target MH must override {@link #reinvokerTarget} to provide the target.
*/
- static LambdaForm reinvokerForm(MethodType mtype) {
- mtype = mtype.basicType();
+ static LambdaForm reinvokerForm(MethodHandle target) {
+ MethodType mtype = target.type().basicType();
LambdaForm reinvoker = mtype.form().cachedLambdaForm(MethodTypeForm.LF_REINVOKE);
if (reinvoker != null) return reinvoker;
- MethodHandle MH_invokeBasic = MethodHandles.basicInvoker(mtype);
+ if (mtype.parameterSlotCount() >= MethodType.MAX_MH_ARITY)
+ return makeReinvokerForm(target.type(), target); // cannot cache this
+ reinvoker = makeReinvokerForm(mtype, null);
+ return mtype.form().setCachedLambdaForm(MethodTypeForm.LF_REINVOKE, reinvoker);
+ }
+ private static LambdaForm makeReinvokerForm(MethodType mtype, MethodHandle customTargetOrNull) {
+ boolean customized = (customTargetOrNull != null);
+ MethodHandle MH_invokeBasic = customized ? null : MethodHandles.basicInvoker(mtype);
final int THIS_BMH = 0;
final int ARG_BASE = 1;
final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
int nameCursor = ARG_LIMIT;
- final int NEXT_MH = nameCursor++;
+ final int NEXT_MH = customized ? -1 : nameCursor++;
final int REINVOKE = nameCursor++;
LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
- names[NEXT_MH] = new LambdaForm.Name(NF_reinvokerTarget, names[THIS_BMH]);
- Object[] targetArgs = Arrays.copyOfRange(names, THIS_BMH, ARG_LIMIT, Object[].class);
- targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH
- names[REINVOKE] = new LambdaForm.Name(MH_invokeBasic, targetArgs);
- return mtype.form().setCachedLambdaForm(MethodTypeForm.LF_REINVOKE, new LambdaForm("BMH.reinvoke", ARG_LIMIT, names));
+ Object[] targetArgs;
+ MethodHandle targetMH;
+ if (customized) {
+ targetArgs = Arrays.copyOfRange(names, ARG_BASE, ARG_LIMIT, Object[].class);
+ targetMH = customTargetOrNull;
+ } else {
+ names[NEXT_MH] = new LambdaForm.Name(NF_reinvokerTarget, names[THIS_BMH]);
+ targetArgs = Arrays.copyOfRange(names, THIS_BMH, ARG_LIMIT, Object[].class);
+ targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH
+ targetMH = MethodHandles.basicInvoker(mtype);
+ }
+ names[REINVOKE] = new LambdaForm.Name(targetMH, targetArgs);
+ return new LambdaForm("BMH.reinvoke", ARG_LIMIT, names);
}
private static final LambdaForm.NamedFunction NF_reinvokerTarget;
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java
index 04eda964966..5ab7f7adb7b 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java
@@ -317,7 +317,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
private MethodHandle cache;
AsVarargsCollector(MethodHandle target, MethodType type, Class> arrayType) {
- super(type, reinvokerForm(type));
+ super(type, reinvokerForm(target));
this.target = target;
this.arrayType = arrayType;
this.cache = target.asCollector(arrayType, 0);
@@ -778,16 +778,27 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
}
static Empty throwException(T t) throws T { throw t; }
- static MethodHandle FAKE_METHOD_HANDLE_INVOKE;
- static
- MethodHandle fakeMethodHandleInvoke(MemberName method) {
- MethodType type = method.getInvocationType();
- assert(type.equals(MethodType.methodType(Object.class, Object[].class)));
- MethodHandle mh = FAKE_METHOD_HANDLE_INVOKE;
+ static MethodHandle[] FAKE_METHOD_HANDLE_INVOKE = new MethodHandle[2];
+ static MethodHandle fakeMethodHandleInvoke(MemberName method) {
+ int idx;
+ assert(method.isMethodHandleInvoke());
+ switch (method.getName()) {
+ case "invoke": idx = 0; break;
+ case "invokeExact": idx = 1; break;
+ default: throw new InternalError(method.getName());
+ }
+ MethodHandle mh = FAKE_METHOD_HANDLE_INVOKE[idx];
if (mh != null) return mh;
- mh = throwException(type.insertParameterTypes(0, UnsupportedOperationException.class));
+ MethodType type = MethodType.methodType(Object.class, UnsupportedOperationException.class,
+ MethodHandle.class, Object[].class);
+ mh = throwException(type);
mh = mh.bindTo(new UnsupportedOperationException("cannot reflectively invoke MethodHandle"));
- FAKE_METHOD_HANDLE_INVOKE = mh;
+ if (!method.getInvocationType().equals(mh.type()))
+ throw new InternalError(method.toString());
+ mh = mh.withInternalMemberName(method);
+ mh = mh.asVarargsCollector(Object[].class);
+ assert(method.isVarargs());
+ FAKE_METHOD_HANDLE_INVOKE[idx] = mh;
return mh;
}
@@ -821,7 +832,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
MethodHandle vamh = prepareForInvoker(mh);
// Cache the result of makeInjectedInvoker once per argument class.
MethodHandle bccInvoker = CV_makeInjectedInvoker.get(hostClass);
- return restoreToType(bccInvoker.bindTo(vamh), mh.type());
+ return restoreToType(bccInvoker.bindTo(vamh), mh.type(), mh.internalMemberName());
}
private static MethodHandle makeInjectedInvoker(Class> hostClass) {
@@ -876,8 +887,11 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
}
// Undo the adapter effect of prepareForInvoker:
- private static MethodHandle restoreToType(MethodHandle vamh, MethodType type) {
- return vamh.asCollector(Object[].class, type.parameterCount()).asType(type);
+ private static MethodHandle restoreToType(MethodHandle vamh, MethodType type, MemberName member) {
+ MethodHandle mh = vamh.asCollector(Object[].class, type.parameterCount());
+ mh = mh.asType(type);
+ mh = mh.withInternalMemberName(member);
+ return mh;
}
private static final MethodHandle MH_checkCallerClass;
@@ -939,4 +953,41 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
}
}
}
+
+
+ /** This subclass allows a wrapped method handle to be re-associated with an arbitrary member name. */
+ static class WrappedMember extends MethodHandle {
+ private final MethodHandle target;
+ private final MemberName member;
+
+ private WrappedMember(MethodHandle target, MethodType type, MemberName member) {
+ super(type, reinvokerForm(target));
+ this.target = target;
+ this.member = member;
+ }
+
+ @Override
+ MethodHandle reinvokerTarget() {
+ return target;
+ }
+ @Override
+ MemberName internalMemberName() {
+ return member;
+ }
+ @Override
+ boolean isInvokeSpecial() {
+ return target.isInvokeSpecial();
+ }
+ @Override
+ MethodHandle viewAsType(MethodType newType) {
+ return new WrappedMember(target, newType, member);
+ }
+ }
+
+ static MethodHandle makeWrappedMember(MethodHandle target, MemberName member) {
+ if (member.equals(target.internalMemberName()))
+ return target;
+ return new WrappedMember(target, target.type(), member);
+ }
+
}
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java
index 380ca59b6e1..72fd8e91035 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java
@@ -24,80 +24,246 @@
*/
package java.lang.invoke;
+
+import java.lang.reflect.*;
+import java.util.*;
import java.lang.invoke.MethodHandleNatives.Constants;
+import java.lang.invoke.MethodHandles.Lookup;
+import static java.lang.invoke.MethodHandleStatics.*;
/**
- * Cracking (reflecting) method handles back into their constituent symbolic parts.
+ * A symbolic reference obtained by cracking a method handle into its consitutent symbolic parts.
+ * To crack a direct method handle, call {@link Lookup#revealDirect Lookup.revealDirect}.
+ *
+ * A direct method handle represents a method, constructor, or field without
+ * any intervening argument bindings or other transformations.
+ * The method, constructor, or field referred to by a direct method handle is called
+ * its underlying member.
+ * Direct method handles may be obtained in any of these ways:
+ *
+ * - By executing an {@code ldc} instruction on a {@code CONSTANT_MethodHandle} constant.
+ * (See the Java Virtual Machine Specification, sections 4.4.8 and 5.4.3.)
+ *
- By calling one of the Lookup Factory Methods,
+ * such as {@link Lookup#findVirtual Lookup.findVirtual},
+ * to resolve a symbolic reference into a method handle.
+ * A symbolic reference consists of a class, name string, and type.
+ *
- By calling the factory method {@link Lookup#unreflect Lookup.unreflect}
+ * or {@link Lookup#unreflectSpecial Lookup.unreflectSpecial}
+ * to convert a {@link Method} into a method handle.
+ *
- By calling the factory method {@link Lookup#unreflectConstructor Lookup.unreflectConstructor}
+ * to convert a {@link Constructor} into a method handle.
+ *
- By calling the factory method {@link Lookup#unreflectGetter Lookup.unreflectGetter}
+ * or {@link Lookup#unreflectSetter Lookup.unreflectSetter}
+ * to convert a {@link Field} into a method handle.
+ *
+ * In all of these cases, it is possible to crack the resulting direct method handle
+ * to recover a symbolic reference for the underlying method, constructor, or field.
+ * Cracking must be done via a {@code Lookup} object equivalent to that which created
+ * the target method handle, or which has enough access permissions to recreate
+ * an equivalent method handle.
*
+ * Reference kinds
+ * The Lookup Factory Methods
+ * correspond to all major use cases for methods, constructors, and fields.
+ * These use cases may be distinguished using small integers as follows:
+ *
+ * reference kind | descriptive name | scope | member | behavior |
+ *
+ * {@code 1} | {@code REF_getField} | {@code class} |
+ * {@code FT f;} | {@code (T) this.f;} |
+ *
+ *
+ * {@code 2} | {@code REF_getStatic} | {@code class} or {@code interface} |
+ * {@code static} {@code FT f;} | {@code (T) C.f;} |
+ *
+ *
+ * {@code 3} | {@code REF_putField} | {@code class} |
+ * {@code FT f;} | {@code this.f = x;} |
+ *
+ *
+ * {@code 4} | {@code REF_putStatic} | {@code class} |
+ * {@code static} {@code FT f;} | {@code C.f = arg;} |
+ *
+ *
+ * {@code 5} | {@code REF_invokeVirtual} | {@code class} |
+ * {@code T m(A*);} | {@code (T) this.m(arg*);} |
+ *
+ *
+ * {@code 6} | {@code REF_invokeStatic} | {@code class} or {@code interface} |
+ * {@code static} {@code T m(A*);} | {@code (T) C.m(arg*);} |
+ *
+ *
+ * {@code 7} | {@code REF_invokeSpecial} | {@code class} or {@code interface} |
+ * {@code T m(A*);} | {@code (T) super.m(arg*);} |
+ *
+ *
+ * {@code 8} | {@code REF_newInvokeSpecial} | {@code class} |
+ * {@code C(A*);} | {@code new C(arg*);} |
+ *
+ *
+ * {@code 9} | {@code REF_invokeInterface} | {@code interface} |
+ * {@code T m(A*);} | {@code (T) this.m(arg*);} |
+ *
+ *
+ * @since 1.8
*/
-final class MethodHandleInfo {
- public static final int
- REF_getField = Constants.REF_getField,
- REF_getStatic = Constants.REF_getStatic,
- REF_putField = Constants.REF_putField,
- REF_putStatic = Constants.REF_putStatic,
- REF_invokeVirtual = Constants.REF_invokeVirtual,
- REF_invokeStatic = Constants.REF_invokeStatic,
- REF_invokeSpecial = Constants.REF_invokeSpecial,
- REF_newInvokeSpecial = Constants.REF_newInvokeSpecial,
- REF_invokeInterface = Constants.REF_invokeInterface;
+public
+interface MethodHandleInfo {
+ /**
+ * A direct method handle reference kind,
+ * as defined in the table above.
+ */
+ public static final int
+ REF_getField = Constants.REF_getField,
+ REF_getStatic = Constants.REF_getStatic,
+ REF_putField = Constants.REF_putField,
+ REF_putStatic = Constants.REF_putStatic,
+ REF_invokeVirtual = Constants.REF_invokeVirtual,
+ REF_invokeStatic = Constants.REF_invokeStatic,
+ REF_invokeSpecial = Constants.REF_invokeSpecial,
+ REF_newInvokeSpecial = Constants.REF_newInvokeSpecial,
+ REF_invokeInterface = Constants.REF_invokeInterface;
- private final Class> declaringClass;
- private final String name;
- private final MethodType methodType;
- private final int referenceKind;
+ /**
+ * Returns the reference kind of the cracked method handle, which in turn
+ * determines whether the method handle's underlying member was a constructor, method, or field.
+ * See the table above for definitions.
+ * @return the integer code for the kind of reference used to access the underlying member
+ */
+ public int getReferenceKind();
- public MethodHandleInfo(MethodHandle mh) {
- MemberName mn = mh.internalMemberName();
- if (mn == null) throw new IllegalArgumentException("not a direct method handle");
- this.declaringClass = mn.getDeclaringClass();
- this.name = mn.getName();
- this.methodType = mn.getMethodOrFieldType();
- byte refKind = mn.getReferenceKind();
- if (refKind == REF_invokeSpecial && !mh.isInvokeSpecial())
- // Devirtualized method invocation is usually formally virtual.
- refKind = REF_invokeVirtual;
- this.referenceKind = refKind;
- }
+ /**
+ * Returns the class in which the cracked method handle's underlying member was defined.
+ * @return the declaring class of the underlying member
+ */
+ public Class> getDeclaringClass();
- public Class> getDeclaringClass() {
- return declaringClass;
- }
+ /**
+ * Returns the name of the cracked method handle's underlying member.
+ * This is {@code "<init>"} if the underlying member was a constructor,
+ * else it is a simple method name or field name.
+ * @return the simple name of the underlying member
+ */
+ public String getName();
- public String getName() {
- return name;
- }
+ /**
+ * Returns the nominal type of the cracked symbolic reference, expressed as a method type.
+ * If the reference is to a constructor, the return type will be {@code void}.
+ * If it is to a non-static method, the method type will not mention the {@code this} parameter.
+ * If it is to a field and the requested access is to read the field,
+ * the method type will have no parameters and return the field type.
+ * If it is to a field and the requested access is to write the field,
+ * the method type will have one parameter of the field type and return {@code void}.
+ *
+ * Note that original direct method handle may include a leading {@code this} parameter,
+ * or (in the case of a constructor) will replace the {@code void} return type
+ * with the constructed class.
+ * The nominal type does not include any {@code this} parameter,
+ * and (in the case of a constructor) will return {@code void}.
+ * @return the type of the underlying member, expressed as a method type
+ */
+ public MethodType getMethodType();
- public MethodType getMethodType() {
- return methodType;
- }
+ // Utility methods.
+ // NOTE: class/name/type and reference kind constitute a symbolic reference
+ // member and modifiers are an add-on, derived from Core Reflection (or the equivalent)
- public int getModifiers() {
- return -1; //TODO
- }
+ /**
+ * Reflects the underlying member as a method, constructor, or field object.
+ * If the underlying member is public, it is reflected as if by
+ * {@code getMethod}, {@code getConstructor}, or {@code getField}.
+ * Otherwise, it is reflected as if by
+ * {@code getDeclaredMethod}, {@code getDeclaredConstructor}, or {@code getDeclaredField}.
+ * The underlying member must be accessible to the given lookup object.
+ * @param the desired type of the result, either {@link Member} or a subtype
+ * @param expected a class object representing the desired result type {@code T}
+ * @param lookup the lookup object that created this MethodHandleInfo, or one with equivalent access privileges
+ * @return a reference to the method, constructor, or field object
+ * @exception ClassCastException if the member is not of the expected type
+ * @exception NullPointerException if either argument is {@code null}
+ * @exception IllegalArgumentException if the underlying member is not accessible to the given lookup object
+ */
+ public T reflectAs(Class expected, Lookup lookup);
- public int getReferenceKind() {
- return referenceKind;
- }
+ /**
+ * Returns the access modifiers of the underlying member.
+ * @return the Java language modifiers for underlying member,
+ * or -1 if the member cannot be accessed
+ * @see Modifier
+ * @see reflectAs
+ */
+ public int getModifiers();
- static String getReferenceKindString(int referenceKind) {
- switch (referenceKind) {
- case REF_getField: return "getfield";
- case REF_getStatic: return "getstatic";
- case REF_putField: return "putfield";
- case REF_putStatic: return "putstatic";
- case REF_invokeVirtual: return "invokevirtual";
- case REF_invokeStatic: return "invokestatic";
- case REF_invokeSpecial: return "invokespecial";
- case REF_newInvokeSpecial: return "newinvokespecial";
- case REF_invokeInterface: return "invokeinterface";
- default: return "UNKNOWN_REFENCE_KIND" + "[" + referenceKind + "]";
- }
+ /**
+ * Determines if the underlying member was a variable arity method or constructor.
+ * Such members are represented by method handles that are varargs collectors.
+ * @implSpec
+ * This produces a result equivalent to:
+ * {@code
+ * getReferenceKind() >= REF_invokeVirtual && Modifier.isTransient(getModifiers())
+ * }
+ *
+ *
+ * @return {@code true} if and only if the underlying member was declared with variable arity.
+ */
+ // spelling derived from java.lang.reflect.Executable, not MethodHandle.isVarargsCollector
+ public default boolean isVarArgs() {
+ // fields are never varargs:
+ if (MethodHandleNatives.refKindIsField((byte) getReferenceKind()))
+ return false;
+ // not in the public API: Modifier.VARARGS
+ final int ACC_VARARGS = 0x00000080; // from JVMS 4.6 (Table 4.20)
+ assert(ACC_VARARGS == Modifier.TRANSIENT);
+ return Modifier.isTransient(getModifiers());
}
- @Override
- public String toString() {
- return String.format("%s %s.%s:%s", getReferenceKindString(referenceKind),
- declaringClass.getName(), name, methodType);
+ /**
+ * Returns the descriptive name of the given reference kind,
+ * as defined in the table above.
+ * The conventional prefix "REF_" is omitted.
+ * @param referenceKind an integer code for a kind of reference used to access a class member
+ * @return a mixed-case string such as {@code "getField"}
+ * @exception IllegalArgumentException if the argument is not a valid
+ * reference kind number
+ */
+ public static String referenceKindToString(int referenceKind) {
+ if (!MethodHandleNatives.refKindIsValid(referenceKind))
+ throw newIllegalArgumentException("invalid reference kind", referenceKind);
+ return MethodHandleNatives.refKindName((byte)referenceKind);
+ }
+
+ /**
+ * Returns a string representation for a {@code MethodHandleInfo},
+ * given the four parts of its symbolic reference.
+ * This is defined to be of the form {@code "RK C.N:MT"}, where {@code RK} is the
+ * {@linkplain #referenceKindToString reference kind string} for {@code kind},
+ * {@code C} is the {@linkplain java.lang.Class#getName name} of {@code defc}
+ * {@code N} is the {@code name}, and
+ * {@code MT} is the {@code type}.
+ * These four values may be obtained from the
+ * {@linkplain #getReferenceKind reference kind},
+ * {@linkplain #getDeclaringClass declaring class},
+ * {@linkplain #getName member name},
+ * and {@linkplain #getMethodType method type}
+ * of a {@code MethodHandleInfo} object.
+ *
+ * @implSpec
+ * This produces a result equivalent to:
+ * {@code
+ * String.format("%s %s.%s:%s", referenceKindToString(kind), defc.getName(), name, type)
+ * }
+ *
+ * @param kind the {@linkplain #getReferenceKind reference kind} part of the symbolic reference
+ * @param defc the {@linkplain #getDeclaringClass declaring class} part of the symbolic reference
+ * @param name the {@linkplain #getName member name} part of the symbolic reference
+ * @param type the {@linkplain #getMethodType method type} part of the symbolic reference
+ * @return a string of the form {@code "RK C.N:MT"}
+ * @exception IllegalArgumentException if the first argument is not a valid
+ * reference kind number
+ * @exception NullPointerException if any reference argument is {@code null}
+ */
+ public static String toString(int kind, Class> defc, String name, MethodType type) {
+ Objects.requireNonNull(name); Objects.requireNonNull(type);
+ return String.format("%s %s.%s:%s", referenceKindToString(kind), defc.getName(), name, type);
}
}
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java
index 06e61a7dd8b..4f83e82158c 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java
@@ -205,6 +205,9 @@ class MethodHandleNatives {
static boolean refKindIsMethod(byte refKind) {
return !refKindIsField(refKind) && (refKind != REF_newInvokeSpecial);
}
+ static boolean refKindIsConstructor(byte refKind) {
+ return (refKind == REF_newInvokeSpecial);
+ }
static boolean refKindHasReceiver(byte refKind) {
assert(refKindIsValid(refKind));
return (refKind & 1) != 0;
@@ -313,7 +316,65 @@ class MethodHandleNatives {
* The method assumes the following arguments on the stack:
* 0: the method handle being invoked
* 1-N: the arguments to the method handle invocation
- * N+1: an implicitly added type argument (the given MethodType)
+ * N+1: an optional, implicitly added argument (typically the given MethodType)
+ *
+ * The nominal method at such a call site is an instance of
+ * a signature-polymorphic method (see @PolymorphicSignature).
+ * Such method instances are user-visible entities which are
+ * "split" from the generic placeholder method in {@code MethodHandle}.
+ * (Note that the placeholder method is not identical with any of
+ * its instances. If invoked reflectively, is guaranteed to throw an
+ * {@code UnsupportedOperationException}.)
+ * If the signature-polymorphic method instance is ever reified,
+ * it appears as a "copy" of the original placeholder
+ * (a native final member of {@code MethodHandle}) except
+ * that its type descriptor has shape required by the instance,
+ * and the method instance is not varargs.
+ * The method instance is also marked synthetic, since the
+ * method (by definition) does not appear in Java source code.
+ *
+ * The JVM is allowed to reify this method as instance metadata.
+ * For example, {@code invokeBasic} is always reified.
+ * But the JVM may instead call {@code linkMethod}.
+ * If the result is an * ordered pair of a {@code (method, appendix)},
+ * the method gets all the arguments (0..N inclusive)
+ * plus the appendix (N+1), and uses the appendix to complete the call.
+ * In this way, one reusable method (called a "linker method")
+ * can perform the function of any number of polymorphic instance
+ * methods.
+ *
+ * Linker methods are allowed to be weakly typed, with any or
+ * all references rewritten to {@code Object} and any primitives
+ * (except {@code long}/{@code float}/{@code double})
+ * rewritten to {@code int}.
+ * A linker method is trusted to return a strongly typed result,
+ * according to the specific method type descriptor of the
+ * signature-polymorphic instance it is emulating.
+ * This can involve (as necessary) a dynamic check using
+ * data extracted from the appendix argument.
+ *
+ * The JVM does not inspect the appendix, other than to pass
+ * it verbatim to the linker method at every call.
+ * This means that the JDK runtime has wide latitude
+ * for choosing the shape of each linker method and its
+ * corresponding appendix.
+ * Linker methods should be generated from {@code LambdaForm}s
+ * so that they do not become visible on stack traces.
+ *
+ * The {@code linkMethod} call is free to omit the appendix
+ * (returning null) and instead emulate the required function
+ * completely in the linker method.
+ * As a corner case, if N==255, no appendix is possible.
+ * In this case, the method returned must be custom-generated to
+ * to perform any needed type checking.
+ *
+ * If the JVM does not reify a method at a call site, but instead
+ * calls {@code linkMethod}, the corresponding call represented
+ * in the bytecodes may mention a valid method which is not
+ * representable with a {@code MemberName}.
+ * Therefore, use cases for {@code linkMethod} tend to correspond to
+ * special cases in reflective code such as {@code findVirtual}
+ * or {@code revealDirect}.
*/
static MemberName linkMethod(Class> callerClass, int refKind,
Class> defc, String name, Object type,
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
index 78b01215636..f0f9447e001 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
@@ -26,8 +26,6 @@
package java.lang.invoke;
import java.lang.reflect.*;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
@@ -54,6 +52,7 @@ import sun.security.util.SecurityConstants;
*
*
* @author John Rose, JSR 292 EG
+ * @since 1.7
*/
public class MethodHandles {
@@ -96,6 +95,38 @@ public class MethodHandles {
return Lookup.PUBLIC_LOOKUP;
}
+ /**
+ * Performs an unchecked "crack" of a direct method handle.
+ * The result is as if the user had obtained a lookup object capable enough
+ * to crack the target method handle, called
+ * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
+ * on the target to obtain its symbolic reference, and then called
+ * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs}
+ * to resolve the symbolic reference to a member.
+ *
+ * If there is a security manager, its {@code checkPermission} method
+ * is called with a {@code ReflectPermission("suppressAccessChecks")} permission.
+ * @param the desired type of the result, either {@link Member} or a subtype
+ * @param target a direct method handle to crack into symbolic reference components
+ * @param expected a class object representing the desired result type {@code T}
+ * @return a reference to the method, constructor, or field object
+ * @exception SecurityException if the caller is not privileged to call {@code setAccessible}
+ * @exception NullPointerException if either argument is {@code null}
+ * @exception IllegalArgumentException if the target is not a direct method handle
+ * @exception ClassCastException if the member is not of the expected type
+ * @since 1.8
+ */
+ public static T
+ reflectAs(Class expected, MethodHandle target) {
+ SecurityManager smgr = System.getSecurityManager();
+ if (smgr != null) smgr.checkPermission(ACCESS_PERMISSION);
+ Lookup lookup = Lookup.IMPL_LOOKUP; // use maximally privileged lookup
+ return lookup.revealDirect(target).reflectAs(expected, lookup);
+ }
+ // Copied from AccessibleObject, as used by Method.setAccessible, etc.:
+ static final private java.security.Permission ACCESS_PERMISSION =
+ new ReflectPermission("suppressAccessChecks");
+
/**
* A lookup object is a factory for creating method handles,
* when the creation requires access checking.
@@ -647,6 +678,7 @@ public class MethodHandles {
return invoker(type);
if ("invokeExact".equals(name))
return exactInvoker(type);
+ assert(!MemberName.isMethodHandleInvokeName(name));
return null;
}
@@ -892,6 +924,10 @@ return mh1;
* @throws NullPointerException if the argument is null
*/
public MethodHandle unreflect(Method m) throws IllegalAccessException {
+ if (m.getDeclaringClass() == MethodHandle.class) {
+ MethodHandle mh = unreflectForMH(m);
+ if (mh != null) return mh;
+ }
MemberName method = new MemberName(m);
byte refKind = method.getReferenceKind();
if (refKind == REF_invokeSpecial)
@@ -900,6 +936,12 @@ return mh1;
Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this;
return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method, findBoundCallerClass(method));
}
+ private MethodHandle unreflectForMH(Method m) {
+ // these names require special lookups because they throw UnsupportedOperationException
+ if (MemberName.isMethodHandleInvokeName(m.getName()))
+ return MethodHandleImpl.fakeMethodHandleInvoke(new MemberName(m));
+ return null;
+ }
/**
* Produces a method handle for a reflected method.
@@ -1004,6 +1046,46 @@ return mh1;
return unreflectField(f, true);
}
+ /**
+ * Cracks a direct method handle created by this lookup object or a similar one.
+ * Security and access checks are performed to ensure that this lookup object
+ * is capable of reproducing the target method handle.
+ * This means that the cracking may fail if target is a direct method handle
+ * but was created by an unrelated lookup object.
+ * @param target a direct method handle to crack into symbolic reference components
+ * @return a symbolic reference which can be used to reconstruct this method handle from this lookup object
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
+ * @throws IllegalArgumentException if the target is not a direct method handle or if access checking fails
+ * @exception NullPointerException if the target is {@code null}
+ * @since 1.8
+ */
+ public MethodHandleInfo revealDirect(MethodHandle target) {
+ MemberName member = target.internalMemberName();
+ if (member == null || (!member.isResolved() && !member.isMethodHandleInvoke()))
+ throw newIllegalArgumentException("not a direct method handle");
+ Class> defc = member.getDeclaringClass();
+ byte refKind = member.getReferenceKind();
+ assert(MethodHandleNatives.refKindIsValid(refKind));
+ if (refKind == REF_invokeSpecial && !target.isInvokeSpecial())
+ // Devirtualized method invocation is usually formally virtual.
+ // To avoid creating extra MemberName objects for this common case,
+ // we encode this extra degree of freedom using MH.isInvokeSpecial.
+ refKind = REF_invokeVirtual;
+ if (refKind == REF_invokeVirtual && defc.isInterface())
+ // Symbolic reference is through interface but resolves to Object method (toString, etc.)
+ refKind = REF_invokeInterface;
+ // Check SM permissions and member access before cracking.
+ try {
+ checkSecurityManager(defc, member);
+ checkAccess(refKind, defc, member);
+ } catch (IllegalAccessException ex) {
+ throw new IllegalArgumentException(ex);
+ }
+ // Produce the handle to the results.
+ return new InfoFromMemberName(this, member, refKind);
+ }
+
/// Helper methods, all package-private.
MemberName resolveOrFail(byte refKind, Class> refc, String name, Class> type) throws NoSuchFieldException, IllegalAccessException {
@@ -1201,12 +1283,12 @@ return mh1;
private MethodHandle getDirectMethodCommon(byte refKind, Class> refc, MemberName method,
boolean doRestrict, Class> callerClass) throws IllegalAccessException {
checkMethod(refKind, refc, method);
- if (method.isMethodHandleInvoke())
- return fakeMethodHandleInvoke(method);
+ assert(!method.isMethodHandleInvoke());
Class> refcAsSuper;
if (refKind == REF_invokeSpecial &&
refc != lookupClass() &&
+ !refc.isInterface() &&
refc != (refcAsSuper = lookupClass().getSuperclass()) &&
refc.isAssignableFrom(lookupClass())) {
assert(!method.getName().equals("")); // not this code path
@@ -1234,9 +1316,6 @@ return mh1;
mh = restrictReceiver(method, mh, lookupClass());
return mh;
}
- private MethodHandle fakeMethodHandleInvoke(MemberName method) {
- return throwException(method.getReturnType(), UnsupportedOperationException.class);
- }
private MethodHandle maybeBindCaller(MemberName method, MethodHandle mh,
Class> callerClass)
throws IllegalAccessException {
diff --git a/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java b/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java
index a775fc43e34..9be96ff685b 100644
--- a/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java
+++ b/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java
@@ -225,7 +225,7 @@ public final class SerializedLambda implements Serializable {
@Override
public String toString() {
- String implKind=MethodHandleInfo.getReferenceKindString(implMethodKind);
+ String implKind=MethodHandleInfo.referenceKindToString(implMethodKind);
return String.format("SerializedLambda[%s=%s, %s=%s.%s:%s, " +
"%s=%s %s.%s:%s, %s=%s, %s=%d]",
"capturingClass", capturingClass,
diff --git a/jdk/src/share/classes/java/lang/reflect/Executable.java b/jdk/src/share/classes/java/lang/reflect/Executable.java
index aa8820fd2d7..9d41a0217db 100644
--- a/jdk/src/share/classes/java/lang/reflect/Executable.java
+++ b/jdk/src/share/classes/java/lang/reflect/Executable.java
@@ -428,20 +428,32 @@ public abstract class Executable extends AccessibleObject
}
/**
- * Returns an array of arrays that represent the annotations on
- * the formal parameters, in declaration order, of the executable
- * represented by this object. (Returns an array of length zero if
- * the underlying executable is parameterless. If the executable has
- * one or more parameters, a nested array of length zero is
- * returned for each parameter with no annotations.) The
- * annotation objects contained in the returned arrays are
- * serializable. The caller of this method is free to modify the
- * returned arrays; it will have no effect on the arrays returned
- * to other callers.
+ * Returns an array of arrays of {@code Annotation}s that
+ * represent the annotations on the formal parameters, in
+ * declaration order, of the {@code Executable} represented by
+ * this object. Synthetic and mandated parameters (see
+ * explanation below), such as the outer "this" parameter to an
+ * inner class constructor will be represented in the returned
+ * array. If the executable has no parameters (meaning no formal,
+ * no synthetic, and no mandated parameters), a zero-length array
+ * will be returned. If the {@code Executable} has one or more
+ * parameters, a nested array of length zero is returned for each
+ * parameter with no annotations. The annotation objects contained
+ * in the returned arrays are serializable. The caller of this
+ * method is free to modify the returned arrays; it will have no
+ * effect on the arrays returned to other callers.
*
- * @return an array of arrays that represent the annotations on the formal
- * parameters, in declaration order, of the executable represented by this
- * object
+ * A compiler may add extra parameters that are implicitly
+ * declared in source ("mandated"), as well as parameters that
+ * are neither implicitly nor explicitly declared in source
+ * ("synthetic") to the parameter list for a method. See {@link
+ * java.lang.reflect.Parameter} for more information.
+ *
+ * @see java.lang.reflect.Parameter
+ * @see java.lang.reflect.Parameter#getAnnotations
+ * @return an array of arrays that represent the annotations on
+ * the formal and implicit parameters, in declaration order, of
+ * the executable represented by this object
*/
public abstract Annotation[][] getParameterAnnotations();
diff --git a/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java
index be9ac509731..446b4248a8e 100644
--- a/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java
+++ b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java
@@ -719,7 +719,3 @@ abstract class AbstractPlainSocketImpl extends SocketImpl
public final static int SHUT_RD = 0;
public final static int SHUT_WR = 1;
}
-
-class InetAddressContainer {
- InetAddress addr;
-}
diff --git a/jdk/src/share/classes/java/net/IDN.java b/jdk/src/share/classes/java/net/IDN.java
index ed2f3a38159..34642b9824c 100644
--- a/jdk/src/share/classes/java/net/IDN.java
+++ b/jdk/src/share/classes/java/net/IDN.java
@@ -292,13 +292,17 @@ public final class IDN {
if (useSTD3ASCIIRules) {
for (int i = 0; i < dest.length(); i++) {
int c = dest.charAt(i);
- if (!isLDHChar(c)) {
- throw new IllegalArgumentException("Contains non-LDH characters");
+ if (isNonLDHAsciiCodePoint(c)) {
+ throw new IllegalArgumentException(
+ "Contains non-LDH ASCII characters");
}
}
- if (dest.charAt(0) == '-' || dest.charAt(dest.length() - 1) == '-') {
- throw new IllegalArgumentException("Has leading or trailing hyphen");
+ if (dest.charAt(0) == '-' ||
+ dest.charAt(dest.length() - 1) == '-') {
+
+ throw new IllegalArgumentException(
+ "Has leading or trailing hyphen");
}
}
@@ -401,26 +405,20 @@ public final class IDN {
//
// LDH stands for "letter/digit/hyphen", with characters restricted to the
// 26-letter Latin alphabet , the digits <0-9>, and the hyphen
- // <->
- // non-LDH = 0..0x2C, 0x2E..0x2F, 0x3A..0x40, 0x56..0x60, 0x7B..0x7F
+ // <->.
+ // Non LDH refers to characters in the ASCII range, but which are not
+ // letters, digits or the hypen.
//
- private static boolean isLDHChar(int ch){
- // high runner case
- if(ch > 0x007A){
- return false;
- }
- //['-' '0'..'9' 'A'..'Z' 'a'..'z']
- if((ch == 0x002D) ||
- (0x0030 <= ch && ch <= 0x0039) ||
- (0x0041 <= ch && ch <= 0x005A) ||
- (0x0061 <= ch && ch <= 0x007A)
- ){
- return true;
- }
- return false;
+ // non-LDH = 0..0x2C, 0x2E..0x2F, 0x3A..0x40, 0x5B..0x60, 0x7B..0x7F
+ //
+ private static boolean isNonLDHAsciiCodePoint(int ch){
+ return (0x0000 <= ch && ch <= 0x002C) ||
+ (0x002E <= ch && ch <= 0x002F) ||
+ (0x003A <= ch && ch <= 0x0040) ||
+ (0x005B <= ch && ch <= 0x0060) ||
+ (0x007B <= ch && ch <= 0x007F);
}
-
//
// search dots in a string and return the index of that character;
// or if there is no dots, return the length of input string
diff --git a/jdk/src/share/classes/java/net/InetAddressContainer.java b/jdk/src/share/classes/java/net/InetAddressContainer.java
new file mode 100644
index 00000000000..28b64022fc7
--- /dev/null
+++ b/jdk/src/share/classes/java/net/InetAddressContainer.java
@@ -0,0 +1,30 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+class InetAddressContainer {
+ InetAddress addr;
+}
diff --git a/jdk/src/share/classes/java/nio/file/Files.java b/jdk/src/share/classes/java/nio/file/Files.java
index 721184c1533..f084040c179 100644
--- a/jdk/src/share/classes/java/nio/file/Files.java
+++ b/jdk/src/share/classes/java/nio/file/Files.java
@@ -25,34 +25,56 @@
package java.nio.file;
-import java.nio.file.attribute.*;
-import java.nio.file.spi.FileSystemProvider;
-import java.nio.file.spi.FileTypeDetector;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UncheckedIOException;
+import java.io.Writer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.SeekableByteChannel;
-import java.io.Closeable;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.io.Writer;
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.util.*;
-import java.util.function.BiPredicate;
-import java.util.stream.CloseableStream;
-import java.util.stream.DelegatingStream;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
+import java.nio.file.attribute.BasicFileAttributeView;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.DosFileAttributes;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.FileAttributeView;
+import java.nio.file.attribute.FileOwnerAttributeView;
+import java.nio.file.attribute.FileStoreAttributeView;
+import java.nio.file.attribute.FileTime;
+import java.nio.file.attribute.PosixFileAttributeView;
+import java.nio.file.attribute.PosixFileAttributes;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.UserPrincipal;
+import java.nio.file.spi.FileSystemProvider;
+import java.nio.file.spi.FileTypeDetector;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.ServiceLoader;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.BiPredicate;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
/**
* This class consists exclusively of static methods that operate on files,
@@ -74,6 +96,21 @@ public final class Files {
return path.getFileSystem().provider();
}
+ /**
+ * Convert a Closeable to a Runnable by converting checked IOException
+ * to UncheckedIOException
+ */
+ private static Runnable asUncheckedRunnable(Closeable c) {
+ return () -> {
+ try {
+ c.close();
+ }
+ catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ };
+ }
+
// -- File contents --
/**
@@ -3228,29 +3265,7 @@ public final class Files {
// -- Stream APIs --
/**
- * Implementation of CloseableStream
- */
- private static class DelegatingCloseableStream extends DelegatingStream
- implements CloseableStream
- {
- private final Closeable closeable;
-
- DelegatingCloseableStream(Closeable c, Stream delegate) {
- super(delegate);
- this.closeable = c;
- }
-
- public void close() {
- try {
- closeable.close();
- } catch (IOException ex) {
- throw new UncheckedIOException(ex);
- }
- }
- }
-
- /**
- * Return a lazily populated {@code CloseableStream}, the elements of
+ * Return a lazily populated {@code Stream}, the elements of
* which are the entries in the directory. The listing is not recursive.
*
* The elements of the stream are {@link Path} objects that are
@@ -3264,10 +3279,13 @@ public final class Files {
* reflect updates to the directory that occur after returning from this
* method.
*
- * When not using the try-with-resources construct, then the stream's
- * {@link CloseableStream#close close} method should be invoked after the
- * operation is completed so as to free any resources held for the open
- * directory. Operating on a closed stream behaves as if the end of stream
+ * The returned stream encapsulates a {@link DirectoryStream}.
+ * If timely disposal of file system resources is required, the
+ * {@code try}-with-resources construct should be used to ensure that the
+ * stream's {@link Stream#close close} method is invoked after the stream
+ * operations are completed.
+ *
+ * Operating on a closed stream behaves as if the end of stream
* has been reached. Due to read-ahead, one or more elements may be
* returned after the stream has been closed.
*
@@ -3278,7 +3296,7 @@ public final class Files {
*
* @param dir The path to the directory
*
- * @return The {@code CloseableStream} describing the content of the
+ * @return The {@code Stream} describing the content of the
* directory
*
* @throws NotDirectoryException
@@ -3294,43 +3312,54 @@ public final class Files {
* @see #newDirectoryStream(Path)
* @since 1.8
*/
- public static CloseableStream list(Path dir) throws IOException {
+ public static Stream list(Path dir) throws IOException {
DirectoryStream ds = Files.newDirectoryStream(dir);
- final Iterator delegate = ds.iterator();
+ try {
+ final Iterator delegate = ds.iterator();
- // Re-wrap DirectoryIteratorException to UncheckedIOException
- Iterator it = new Iterator() {
- public boolean hasNext() {
- try {
- return delegate.hasNext();
- } catch (DirectoryIteratorException e) {
- throw new UncheckedIOException(e.getCause());
+ // Re-wrap DirectoryIteratorException to UncheckedIOException
+ Iterator it = new Iterator() {
+ @Override
+ public boolean hasNext() {
+ try {
+ return delegate.hasNext();
+ } catch (DirectoryIteratorException e) {
+ throw new UncheckedIOException(e.getCause());
+ }
}
- }
- public Path next() {
- try {
- return delegate.next();
- } catch (DirectoryIteratorException e) {
- throw new UncheckedIOException(e.getCause());
+ @Override
+ public Path next() {
+ try {
+ return delegate.next();
+ } catch (DirectoryIteratorException e) {
+ throw new UncheckedIOException(e.getCause());
+ }
}
- }
- };
+ };
- Stream s = StreamSupport.stream(
- Spliterators.spliteratorUnknownSize(it, Spliterator.DISTINCT),
- false);
- return new DelegatingCloseableStream<>(ds, s);
+ return StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, Spliterator.DISTINCT), false)
+ .onClose(asUncheckedRunnable(ds));
+ } catch (Error|RuntimeException e) {
+ try {
+ ds.close();
+ } catch (IOException ex) {
+ try {
+ e.addSuppressed(ex);
+ } catch (Throwable ignore) {}
+ }
+ throw e;
+ }
}
/**
- * Return a {@code CloseableStream} that is lazily populated with {@code
+ * Return a {@code Stream} that is lazily populated with {@code
* Path} by walking the file tree rooted at a given starting file. The
* file tree is traversed depth-first, the elements in the stream
* are {@link Path} objects that are obtained as if by {@link
* Path#resolve(Path) resolving} the relative path against {@code start}.
*
* The {@code stream} walks the file tree as elements are consumed.
- * The {@code CloseableStream} returned is guaranteed to have at least one
+ * The {@code Stream} returned is guaranteed to have at least one
* element, the starting file itself. For each file visited, the stream
* attempts to read its {@link BasicFileAttributes}. If the file is a
* directory and can be opened successfully, entries in the directory, and
@@ -3370,10 +3399,11 @@ public final class Files {
* When a security manager is installed and it denies access to a file
* (or directory), then it is ignored and not included in the stream.
*
- * When not using the try-with-resources construct, then the stream's
- * {@link CloseableStream#close close} method should be invoked after the
- * operation is completed so as to free any resources held for the open
- * directory. Operate the stream after it is closed will throw an
+ * The returned stream encapsulates one or more {@link DirectoryStream}s.
+ * If timely disposal of file system resources is required, the
+ * {@code try}-with-resources construct should be used to ensure that the
+ * stream's {@link Stream#close close} method is invoked after the stream
+ * operations are completed. Operating on a closed stream will result in an
* {@link java.lang.IllegalStateException}.
*
* If an {@link IOException} is thrown when accessing the directory
@@ -3388,7 +3418,7 @@ public final class Files {
* @param options
* options to configure the traversal
*
- * @return the {@link CloseableStream} of {@link Path}
+ * @return the {@link Stream} of {@link Path}
*
* @throws IllegalArgumentException
* if the {@code maxDepth} parameter is negative
@@ -3401,21 +3431,22 @@ public final class Files {
* if an I/O error is thrown when accessing the starting file.
* @since 1.8
*/
- public static CloseableStream walk(Path start, int maxDepth,
- FileVisitOption... options)
- throws IOException
- {
+ public static Stream walk(Path start, int maxDepth,
+ FileVisitOption... options)
+ throws IOException {
FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options);
-
- Stream s = StreamSupport.stream(
- Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT),
- false).
- map(entry -> entry.file());
- return new DelegatingCloseableStream<>(iterator, s);
+ try {
+ return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false)
+ .onClose(iterator::close)
+ .map(entry -> entry.file());
+ } catch (Error|RuntimeException e) {
+ iterator.close();
+ throw e;
+ }
}
/**
- * Return a {@code CloseableStream} that is lazily populated with {@code
+ * Return a {@code Stream} that is lazily populated with {@code
* Path} by walking the file tree rooted at a given starting file. The
* file tree is traversed depth-first, the elements in the stream
* are {@link Path} objects that are obtained as if by {@link
@@ -3428,12 +3459,19 @@ public final class Files {
*
* In other words, it visits all levels of the file tree.
*
+ * The returned stream encapsulates one or more {@link DirectoryStream}s.
+ * If timely disposal of file system resources is required, the
+ * {@code try}-with-resources construct should be used to ensure that the
+ * stream's {@link Stream#close close} method is invoked after the stream
+ * operations are completed. Operating on a closed stream will result in an
+ * {@link java.lang.IllegalStateException}.
+ *
* @param start
* the starting file
* @param options
* options to configure the traversal
*
- * @return the {@link CloseableStream} of {@link Path}
+ * @return the {@link Stream} of {@link Path}
*
* @throws SecurityException
* If the security manager denies access to the starting file.
@@ -3446,15 +3484,14 @@ public final class Files {
* @see #walk(Path, int, FileVisitOption...)
* @since 1.8
*/
- public static CloseableStream walk(Path start,
- FileVisitOption... options)
- throws IOException
- {
+ public static Stream walk(Path start,
+ FileVisitOption... options)
+ throws IOException {
return walk(start, Integer.MAX_VALUE, options);
}
/**
- * Return a {@code CloseableStream} that is lazily populated with {@code
+ * Return a {@code Stream} that is lazily populated with {@code
* Path} by searching for files in a file tree rooted at a given starting
* file.
*
@@ -3463,12 +3500,19 @@ public final class Files {
* {@link BiPredicate} is invoked with its {@link Path} and {@link
* BasicFileAttributes}. The {@code Path} object is obtained as if by
* {@link Path#resolve(Path) resolving} the relative path against {@code
- * start} and is only included in the returned {@link CloseableStream} if
+ * start} and is only included in the returned {@link Stream} if
* the {@code BiPredicate} returns true. Compare to calling {@link
* java.util.stream.Stream#filter filter} on the {@code Stream}
* returned by {@code walk} method, this method may be more efficient by
* avoiding redundant retrieval of the {@code BasicFileAttributes}.
*
+ * The returned stream encapsulates one or more {@link DirectoryStream}s.
+ * If timely disposal of file system resources is required, the
+ * {@code try}-with-resources construct should be used to ensure that the
+ * stream's {@link Stream#close close} method is invoked after the stream
+ * operations are completed. Operating on a closed stream will result in an
+ * {@link java.lang.IllegalStateException}.
+ *
* If an {@link IOException} is thrown when accessing the directory
* after returned from this method, it is wrapped in an {@link
* UncheckedIOException} which will be thrown from the method that caused
@@ -3484,7 +3528,7 @@ public final class Files {
* @param options
* options to configure the traversal
*
- * @return the {@link CloseableStream} of {@link Path}
+ * @return the {@link Stream} of {@link Path}
*
* @throws IllegalArgumentException
* if the {@code maxDepth} parameter is negative
@@ -3499,24 +3543,25 @@ public final class Files {
* @see #walk(Path, int, FileVisitOption...)
* @since 1.8
*/
- public static CloseableStream find(Path start,
- int maxDepth,
- BiPredicate matcher,
- FileVisitOption... options)
- throws IOException
- {
+ public static Stream find(Path start,
+ int maxDepth,
+ BiPredicate matcher,
+ FileVisitOption... options)
+ throws IOException {
FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options);
-
- Stream s = StreamSupport.stream(
- Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT),
- false).
- filter(entry -> matcher.test(entry.file(), entry.attributes())).
- map(entry -> entry.file());
- return new DelegatingCloseableStream<>(iterator, s);
+ try {
+ return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false)
+ .onClose(iterator::close)
+ .filter(entry -> matcher.test(entry.file(), entry.attributes()))
+ .map(entry -> entry.file());
+ } catch (Error|RuntimeException e) {
+ iterator.close();
+ throw e;
+ }
}
/**
- * Read all lines from a file as a {@code CloseableStream}. Unlike {@link
+ * Read all lines from a file as a {@code Stream}. Unlike {@link
* #readAllLines(Path, Charset) readAllLines}, this method does not read
* all lines into a {@code List}, but instead populates lazily as the stream
* is consumed.
@@ -3528,22 +3573,24 @@ public final class Files {
* After this method returns, then any subsequent I/O exception that
* occurs while reading from the file or when a malformed or unmappable byte
* sequence is read, is wrapped in an {@link UncheckedIOException} that will
- * be thrown form the
+ * be thrown from the
* {@link java.util.stream.Stream} method that caused the read to take
* place. In case an {@code IOException} is thrown when closing the file,
* it is also wrapped as an {@code UncheckedIOException}.
*
- * When not using the try-with-resources construct, then stream's
- * {@link CloseableStream#close close} method should be invoked after
- * operation is completed so as to free any resources held for the open
- * file.
+ * The returned stream encapsulates a {@link Reader}. If timely
+ * disposal of file system resources is required, the try-with-resources
+ * construct should be used to ensure that the stream's
+ * {@link Stream#close close} method is invoked after the stream operations
+ * are completed.
+ *
*
* @param path
* the path to the file
* @param cs
* the charset to use for decoding
*
- * @return the lines from the file as a {@code CloseableStream}
+ * @return the lines from the file as a {@code Stream}
*
* @throws IOException
* if an I/O error occurs opening the file
@@ -3557,10 +3604,19 @@ public final class Files {
* @see java.io.BufferedReader#lines()
* @since 1.8
*/
- public static CloseableStream lines(Path path, Charset cs)
- throws IOException
- {
+ public static Stream lines(Path path, Charset cs) throws IOException {
BufferedReader br = Files.newBufferedReader(path, cs);
- return new DelegatingCloseableStream<>(br, br.lines());
+ try {
+ return br.lines().onClose(asUncheckedRunnable(br));
+ } catch (Error|RuntimeException e) {
+ try {
+ br.close();
+ } catch (IOException ex) {
+ try {
+ e.addSuppressed(ex);
+ } catch (Throwable ignore) {}
+ }
+ throw e;
+ }
}
}
diff --git a/jdk/src/share/classes/java/rmi/activation/Activatable.java b/jdk/src/share/classes/java/rmi/activation/Activatable.java
index 7b43c27bd22..6ab4ba22481 100644
--- a/jdk/src/share/classes/java/rmi/activation/Activatable.java
+++ b/jdk/src/share/classes/java/rmi/activation/Activatable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -93,6 +93,8 @@ public abstract class Activatable extends RemoteServer {
* @exception RemoteException if either of the following fails:
* a) registering the object with the activation system or b) exporting
* the object to the RMI runtime.
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation.
* @since 1.2
**/
protected Activatable(String location,
@@ -143,6 +145,8 @@ public abstract class Activatable extends RemoteServer {
* @exception RemoteException if either of the following fails:
* a) registering the object with the activation system or b) exporting
* the object to the RMI runtime.
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation.
* @since 1.2
**/
protected Activatable(String location,
@@ -175,6 +179,8 @@ public abstract class Activatable extends RemoteServer {
* @param port the port number on which the object is exported
* @exception RemoteException if exporting the object to the RMI
* runtime fails
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @since 1.2
*/
protected Activatable(ActivationID id, int port)
@@ -206,6 +212,8 @@ public abstract class Activatable extends RemoteServer {
* @param ssf the server-side socket factory for receiving remote calls
* @exception RemoteException if exporting the object to the RMI
* runtime fails
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @since 1.2
*/
protected Activatable(ActivationID id, int port,
@@ -239,6 +247,8 @@ public abstract class Activatable extends RemoteServer {
* is not registered with the activation system
* @exception ActivationException if activation system is not running
* @exception RemoteException if remote call fails
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @since 1.2
*/
public static Remote register(ActivationDesc desc)
@@ -273,6 +283,8 @@ public abstract class Activatable extends RemoteServer {
* already be inactive)
* @exception ActivationException if group is not active
* @exception RemoteException if call informing monitor fails
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @since 1.2
*/
public static boolean inactive(ActivationID id)
@@ -290,6 +302,8 @@ public abstract class Activatable extends RemoteServer {
* @exception UnknownObjectException if object (id ) is unknown
* @exception ActivationException if activation system is not running
* @exception RemoteException if remote call to activation system fails
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @since 1.2
*/
public static void unregister(ActivationID id)
@@ -334,6 +348,8 @@ public abstract class Activatable extends RemoteServer {
* the wrong group
* @exception ActivationException if activation group is not active
* @exception RemoteException if object registration or export fails
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @since 1.2
**/
public static ActivationID exportObject(Remote obj,
@@ -407,6 +423,8 @@ public abstract class Activatable extends RemoteServer {
* descriptor with the activation system
* @exception ActivationException if activation group is not active
* @exception RemoteException if object registration or export fails
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @since 1.2
**/
public static ActivationID exportObject(Remote obj,
@@ -473,6 +491,8 @@ public abstract class Activatable extends RemoteServer {
* @param port the port on which the object is exported (an anonymous
* port is used if port=0)
* @exception RemoteException if object export fails
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @since 1.2
*/
public static Remote exportObject(Remote obj,
@@ -503,6 +523,8 @@ public abstract class Activatable extends RemoteServer {
* remote object
* @param ssf the server-side socket factory for receiving remote calls
* @exception RemoteException if object export fails
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @since 1.2
*/
public static Remote exportObject(Remote obj,
@@ -531,6 +553,8 @@ public abstract class Activatable extends RemoteServer {
* @return true if operation is successful, false otherwise
* @exception NoSuchObjectException if the remote object is not
* currently exported
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @since 1.2
*/
public static boolean unexportObject(Remote obj, boolean force)
diff --git a/jdk/src/share/classes/java/rmi/activation/ActivationDesc.java b/jdk/src/share/classes/java/rmi/activation/ActivationDesc.java
index d206337f70f..e9170294d05 100644
--- a/jdk/src/share/classes/java/rmi/activation/ActivationDesc.java
+++ b/jdk/src/share/classes/java/rmi/activation/ActivationDesc.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -105,6 +105,8 @@ public final class ActivationDesc implements Serializable {
* @param data the object's initialization (activation) data contained
* in marshalled form.
* @exception ActivationException if the current group is nonexistent
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @since 1.2
*/
public ActivationDesc(String className,
@@ -142,6 +144,8 @@ public final class ActivationDesc implements Serializable {
* true does not force an initial immediate activation of
* a newly registered object; initial activation is lazy.
* @exception ActivationException if the current group is nonexistent
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @since 1.2
*/
public ActivationDesc(String className,
@@ -176,6 +180,8 @@ public final class ActivationDesc implements Serializable {
* @param data the object's initialization (activation) data contained
* in marshalled form.
* @exception IllegalArgumentException if groupID is null
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @since 1.2
*/
public ActivationDesc(ActivationGroupID groupID,
@@ -208,6 +214,8 @@ public final class ActivationDesc implements Serializable {
* true does not force an initial immediate activation of
* a newly registered object; initial activation is lazy.
* @exception IllegalArgumentException if groupID is null
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @since 1.2
*/
public ActivationDesc(ActivationGroupID groupID,
diff --git a/jdk/src/share/classes/java/rmi/activation/ActivationGroup.java b/jdk/src/share/classes/java/rmi/activation/ActivationGroup.java
index 28d41c25b3f..49dffd18e0e 100644
--- a/jdk/src/share/classes/java/rmi/activation/ActivationGroup.java
+++ b/jdk/src/share/classes/java/rmi/activation/ActivationGroup.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -133,6 +133,8 @@ public abstract class ActivationGroup
*
* @param groupID the group's identifier
* @throws RemoteException if this group could not be exported
+ * @throws UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @since 1.2
*/
protected ActivationGroup(ActivationGroupID groupID)
@@ -267,6 +269,8 @@ public abstract class ActivationGroup
* (Note: The default implementation of the security manager
* checkSetFactory
* method requires the RuntimePermission "setFactory")
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @see SecurityManager#checkSetFactory
* @since 1.2
*/
@@ -345,6 +349,8 @@ public abstract class ActivationGroup
/**
* Returns the current activation group's identifier. Returns null
* if no group is currently active for this VM.
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @return the activation group's identifier
* @since 1.2
*/
@@ -394,6 +400,8 @@ public abstract class ActivationGroup
* (Note: The default implementation of the security manager
* checkSetFactory
* method requires the RuntimePermission "setFactory")
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @see #getSystem
* @see SecurityManager#checkSetFactory
* @since 1.2
@@ -428,6 +436,8 @@ public abstract class ActivationGroup
* @exception ActivationException if activation system cannot be
* obtained or is not bound
* (means that it is not running)
+ * @exception UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @see #setSystem
* @since 1.2
*/
diff --git a/jdk/src/share/classes/java/rmi/activation/ActivationGroupID.java b/jdk/src/share/classes/java/rmi/activation/ActivationGroupID.java
index 85c1f0f5906..bbd816fd73e 100644
--- a/jdk/src/share/classes/java/rmi/activation/ActivationGroupID.java
+++ b/jdk/src/share/classes/java/rmi/activation/ActivationGroupID.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -63,6 +63,8 @@ public class ActivationGroupID implements java.io.Serializable {
* Constructs a unique group id.
*
* @param system the group's activation system
+ * @throws UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @since 1.2
*/
public ActivationGroupID(ActivationSystem system) {
diff --git a/jdk/src/share/classes/java/rmi/activation/ActivationID.java b/jdk/src/share/classes/java/rmi/activation/ActivationID.java
index 1a5b33ff43c..02511b848b8 100644
--- a/jdk/src/share/classes/java/rmi/activation/ActivationID.java
+++ b/jdk/src/share/classes/java/rmi/activation/ActivationID.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -90,6 +90,8 @@ public class ActivationID implements Serializable {
*
* @param activator reference to the activator responsible for
* activating the object
+ * @throws UnsupportedOperationException if and only if activation is
+ * not supported by this implementation
* @since 1.2
*/
public ActivationID(Activator activator) {
diff --git a/jdk/src/share/classes/java/rmi/activation/package.html b/jdk/src/share/classes/java/rmi/activation/package.html
index ceb26788d1f..ed4bb79bffe 100644
--- a/jdk/src/share/classes/java/rmi/activation/package.html
+++ b/jdk/src/share/classes/java/rmi/activation/package.html
@@ -1,5 +1,5 @@
KO!!! "+obj.getClass().getSimpleName()+".hashCode got NPE with a null "+param);
+ failed++;
+ }
+
+ try {
+ obj.toString();
+ System.out.println("OK: "+obj.getClass().getSimpleName()+".toString worked with a null "+param);
+ } catch (NullPointerException npe) {
+ System.out.println("--->KO!!! "+obj.getClass().getSimpleName()+".toString got NPE.");
+ failed++;
+ }
+ }
+}
diff --git a/jdk/test/javax/management/openmbean/OpenMBeanInfoEqualsNPETest.java b/jdk/test/javax/management/openmbean/OpenMBeanInfoEqualsNPETest.java
new file mode 100644
index 00000000000..452e940b0fd
--- /dev/null
+++ b/jdk/test/javax/management/openmbean/OpenMBeanInfoEqualsNPETest.java
@@ -0,0 +1,196 @@
+/*
+ * 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.
+ */
+
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.modelmbean.DescriptorSupport;
+import javax.management.openmbean.OpenMBeanAttributeInfo;
+import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
+import javax.management.openmbean.OpenMBeanConstructorInfo;
+import javax.management.openmbean.OpenMBeanConstructorInfoSupport;
+import javax.management.openmbean.OpenMBeanInfo;
+import javax.management.openmbean.OpenMBeanInfoSupport;
+import javax.management.openmbean.OpenMBeanOperationInfo;
+import javax.management.openmbean.OpenMBeanOperationInfoSupport;
+import javax.management.openmbean.OpenMBeanParameterInfo;
+import javax.management.openmbean.OpenMBeanParameterInfoSupport;
+import javax.management.openmbean.SimpleType;
+
+/*
+ * @test
+ * @bug 8023529
+ * @summary Test that OpenMBean*Info.equals do not throw NPE
+ * @author Shanliang JIANG
+ * @run clean OpenMBeanInfoEqualsNPETest
+ * @run build OpenMBeanInfoEqualsNPETest
+ * @run main OpenMBeanInfoEqualsNPETest
+ */
+public class OpenMBeanInfoEqualsNPETest {
+ private static int failed = 0;
+
+ public static void main(String[] args) throws Exception {
+ System.out.println("---OpenMBeanInfoEqualsNPETest-main ...");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanAttributeInfoSupport...");
+ OpenMBeanAttributeInfo openMBeanAttributeInfo0 = new OpenMBeanAttributeInfoSupport(
+ "name", "description", SimpleType.INTEGER, true, true, false, 1, new Integer[]{1, 2, 3});
+ OpenMBeanAttributeInfo openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport(
+ "name", "description", SimpleType.INTEGER, true, true, false, null, new Integer[]{1, 2, 3});
+ test(openMBeanAttributeInfo0, openMBeanAttributeInfo, "defaultValue");
+
+ openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport(
+ "name", "description", SimpleType.INTEGER, true, true, false, 1, null);
+ test(openMBeanAttributeInfo0, openMBeanAttributeInfo, "legalValues");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanConstructorInfoSupport...");
+ OpenMBeanConstructorInfo openMBeanConstructorInfo0 = new OpenMBeanConstructorInfoSupport(
+ "name", "description", new OpenMBeanParameterInfo[]{}, new DescriptorSupport());
+ OpenMBeanConstructorInfo openMBeanConstructorInfo;
+
+ openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport(
+ "name", "description", null, new DescriptorSupport());
+ test(openMBeanConstructorInfo0, openMBeanConstructorInfo, "sigs");
+
+ openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport(
+ "name", "description", new OpenMBeanParameterInfo[]{}, null);
+ test(openMBeanConstructorInfo0, openMBeanConstructorInfo, "Descriptor");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanOperationInfoSupport...");
+ OpenMBeanOperationInfo openMBeanOperationInfo0 = new OpenMBeanOperationInfoSupport(
+ "name", "description", new OpenMBeanParameterInfo[]{}, SimpleType.INTEGER, 1, new DescriptorSupport());
+ OpenMBeanOperationInfo openMBeanOperationInfo;
+
+ openMBeanOperationInfo = new OpenMBeanOperationInfoSupport(
+ "name", "description", null, SimpleType.INTEGER, 1, new DescriptorSupport());
+ test(openMBeanOperationInfo0, openMBeanOperationInfo, "sigs");
+
+ openMBeanOperationInfo = new OpenMBeanOperationInfoSupport(
+ "name", "description", new OpenMBeanParameterInfo[]{}, SimpleType.INTEGER, MBeanOperationInfo.UNKNOWN, null);
+ test(openMBeanOperationInfo0, openMBeanOperationInfo, "Descriptor");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 1...");
+ OpenMBeanParameterInfo openMBeanParameterInfo0 = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, 0, -1, 1);
+ OpenMBeanParameterInfo openMBeanParameterInfo;
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, null, -1, 1);
+ test(openMBeanParameterInfo0, openMBeanParameterInfo, "default value");
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, 0, null, 1);
+ test(openMBeanParameterInfo0, openMBeanParameterInfo, "min value");
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, 0, -1, null);
+ test(openMBeanParameterInfo0, openMBeanParameterInfo, "max value");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 2...");
+ openMBeanParameterInfo0 = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, 1, new Integer[]{-1, 1, 2});
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, null, new Integer[]{-1, 1, 2});
+ test(openMBeanParameterInfo0, openMBeanParameterInfo, "default value");
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, 1, null);
+ test(openMBeanParameterInfo0, openMBeanParameterInfo, "legal values");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanInfoSupport...");
+ String className = "toto";
+ String description = "titi";
+ OpenMBeanAttributeInfo[] attrInfos = new OpenMBeanAttributeInfo[]{};
+ OpenMBeanConstructorInfo[] constrInfos = new OpenMBeanConstructorInfo[]{};
+ OpenMBeanOperationInfo[] operaInfos = new OpenMBeanOperationInfo[]{};
+ MBeanNotificationInfo[] notifInfos = new MBeanNotificationInfo[]{};
+
+ OpenMBeanInfo ominfo0 = new OpenMBeanInfoSupport("toto", description, attrInfos, constrInfos, operaInfos, notifInfos);
+ OpenMBeanInfo ominfo = new OpenMBeanInfoSupport(null, description, attrInfos, constrInfos, operaInfos, notifInfos);
+ test(ominfo0, ominfo, "class name");
+
+ ominfo = new OpenMBeanInfoSupport(className, null, attrInfos, constrInfos, operaInfos, notifInfos);
+ test(ominfo0, ominfo, "description");
+
+ ominfo = new OpenMBeanInfoSupport(className, description, null, constrInfos, operaInfos, notifInfos);
+ test(ominfo0, ominfo, "attrInfos");
+
+ ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, null, operaInfos, notifInfos);
+ test(ominfo0, ominfo, "constructor infos");
+
+ ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, null, notifInfos);
+ test(ominfo0, ominfo, "operation infos");
+
+ ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, operaInfos, null);
+ test(ominfo0, ominfo, "notif infos");
+
+ if (failed > 0) {
+ throw new RuntimeException("Test failed: "+failed);
+ } else {
+ System.out.println("---Test: PASSED");
+ }
+ }
+
+ private static void test(Object obj1, Object obj2, String param) {
+ try {
+ obj1.equals(obj2);
+ System.out.println("OK-1: "+obj1.getClass().getSimpleName()+
+ ".equals worked with a null field: "+param);
+ } catch (NullPointerException npe) {
+ System.out.println("--->KO-1!!! "+obj1.getClass().getSimpleName()+
+ ".equals got NPE with a null field: "+param);
+ npe.printStackTrace();
+ failed++;
+ }
+
+ try {
+ obj2.equals(obj1);
+ System.out.println("OK-2: "+obj2.getClass().getSimpleName()+
+ ".equals worked with a null field: "+param);
+ } catch (NullPointerException npe) {
+ System.out.println("--->KO-2!!! "+obj2.getClass().getSimpleName()+
+ ".equals got NPE with a null field: "+param);
+ npe.printStackTrace();
+ failed++;
+ }
+
+ try {
+ obj1.equals(null);
+ obj2.equals(null);
+
+ System.out.println("OK-3: "+obj1.getClass().getSimpleName()+
+ ".equals worked with a null object.");
+ } catch (NullPointerException npe) {
+ System.out.println("--->KO-3!!! "+obj1.getClass().getSimpleName()+
+ ".equals got NPE with a null object.");
+ npe.printStackTrace();
+ failed++;
+ }
+ }
+}
diff --git a/jdk/test/javax/management/openmbean/OpenMBeanInfoHashCodeNPETest.java b/jdk/test/javax/management/openmbean/OpenMBeanInfoHashCodeNPETest.java
new file mode 100644
index 00000000000..3c829434193
--- /dev/null
+++ b/jdk/test/javax/management/openmbean/OpenMBeanInfoHashCodeNPETest.java
@@ -0,0 +1,173 @@
+/*
+ * 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.
+ */
+
+import javax.management.MBeanNotificationInfo;
+import javax.management.modelmbean.DescriptorSupport;
+import javax.management.openmbean.OpenMBeanAttributeInfo;
+import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
+import javax.management.openmbean.OpenMBeanConstructorInfo;
+import javax.management.openmbean.OpenMBeanConstructorInfoSupport;
+import javax.management.openmbean.OpenMBeanInfo;
+import javax.management.openmbean.OpenMBeanInfoSupport;
+import javax.management.openmbean.OpenMBeanOperationInfo;
+import javax.management.openmbean.OpenMBeanOperationInfoSupport;
+import javax.management.openmbean.OpenMBeanParameterInfo;
+import javax.management.openmbean.OpenMBeanParameterInfoSupport;
+import javax.management.openmbean.SimpleType;
+
+/*
+ * @test
+ * @bug 8023529
+ * @summary Test that OpenMBean*Info.hashCode do not throw NPE
+ * @author Shanliang JIANG
+ * @run clean OpenMBeanInfoHashCodeNPETest
+ * @run build OpenMBeanInfoHashCodeNPETest
+ * @run main OpenMBeanInfoHashCodeNPETest
+ */
+public class OpenMBeanInfoHashCodeNPETest {
+ private static int failed = 0;
+
+ public static void main(String[] args) throws Exception {
+ System.out.println("---OpenMBeanInfoHashCodeNPETest-main ...");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanInfohashCodeTest...");
+ OpenMBeanAttributeInfo openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport(
+ "name", "description", SimpleType.INTEGER, true, true, false, null, new Integer[]{1, 2, 3});
+ test(openMBeanAttributeInfo, "defaultValue");
+
+ openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport(
+ "name", "description", SimpleType.INTEGER, true, true, false, 1, null);
+ test(openMBeanAttributeInfo, "legalValues");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanConstructorInfoSupport...");
+ OpenMBeanConstructorInfo openMBeanConstructorInfo;
+
+ openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport(
+ "name", "description", null, new DescriptorSupport());
+ test(openMBeanConstructorInfo, "sigs");
+
+ openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport(
+ "name", "description", new OpenMBeanParameterInfo[]{}, null);
+ test(openMBeanConstructorInfo, "Descriptor");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanOperationInfoSupport...");
+ OpenMBeanOperationInfo openMBeanOperationInfo;
+
+ openMBeanOperationInfo = new OpenMBeanOperationInfoSupport(
+ "name", "description", null, SimpleType.INTEGER, 1, new DescriptorSupport());
+ test(openMBeanOperationInfo, "sigs");
+
+ openMBeanOperationInfo = new OpenMBeanOperationInfoSupport(
+ "name", "description", new OpenMBeanParameterInfo[]{}, SimpleType.INTEGER, 1, null);
+ test(openMBeanOperationInfo, "Descriptor");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 1...");
+ OpenMBeanParameterInfo openMBeanParameterInfo;
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, null, -1, 1);
+ test(openMBeanParameterInfo, "default value");
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, 0, null, 1);
+ test(openMBeanParameterInfo, "min value");
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, 0, -1, null);
+ test(openMBeanParameterInfo, "max value");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 2...");
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, 1, new Integer[]{-1, 1, 2});
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, null, new Integer[]{-1, 1, 2});
+ test(openMBeanParameterInfo, "default value");
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, 1, null);
+ test(openMBeanParameterInfo, "legal values");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanInfoSupport...");
+ String className = "toto";
+ String description = "titi";
+ OpenMBeanAttributeInfo[] attrInfos = new OpenMBeanAttributeInfo[]{};
+ OpenMBeanConstructorInfo[] constrInfos = new OpenMBeanConstructorInfo[]{};
+ OpenMBeanOperationInfo[] operaInfos = new OpenMBeanOperationInfo[]{};
+ MBeanNotificationInfo[] notifInfos = new MBeanNotificationInfo[]{};
+
+ OpenMBeanInfo ominfo = new OpenMBeanInfoSupport(null, description, attrInfos, constrInfos, operaInfos, notifInfos);
+ test(ominfo, "class name");
+
+ ominfo = new OpenMBeanInfoSupport(className, null, attrInfos, constrInfos, operaInfos, notifInfos);
+ test(ominfo, "description");
+
+ ominfo = new OpenMBeanInfoSupport(className, description, null, constrInfos, operaInfos, notifInfos);
+ test(ominfo, "attrInfos");
+
+ ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, null, operaInfos, notifInfos);
+ test(ominfo, "constructor infos");
+
+ ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, null, notifInfos);
+ test(ominfo, "operation infos");
+
+ ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, operaInfos, null);
+ test(ominfo, "notif infos");
+
+ if (failed > 0) {
+ throw new RuntimeException("Test failed: "+failed);
+ } else {
+ System.out.println("---Test: PASSED");
+ }
+ }
+
+ private static void test(Object obj, String param) {
+ try {
+ obj.hashCode();
+ System.out.println("OK-1: "+obj.getClass().getSimpleName()+
+ ".hashCode worked with a null paramer: "+param);
+ } catch (NullPointerException npe) {
+ System.out.println("--->KO-1!!! "+obj.getClass().getSimpleName()+
+ ".hashCode got NPE with null paramer: "+param);
+ npe.printStackTrace();
+ failed++;
+ }
+
+ try {
+ obj.toString();
+ System.out.println("OK-1: "+obj.getClass().getSimpleName()+
+ ".toString worked with a null paramer: "+param);
+ } catch (NullPointerException npe) {
+ System.out.println("--->KO-1!!! "+obj.getClass().getSimpleName()+
+ ".toString got NPE with null paramer: "+param);
+ npe.printStackTrace();
+ failed++;
+ }
+ }
+}
diff --git a/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorInternalMapTest.java b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorInternalMapTest.java
new file mode 100644
index 00000000000..86efed134f3
--- /dev/null
+++ b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorInternalMapTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+import java.lang.management.ManagementFactory;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.Map;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXPrincipal;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.rmi.RMIConnector;
+import javax.security.auth.Subject;
+
+/*
+ * @test
+ * @bug 6566891
+ * @summary Check no memory leak on RMIConnector's rmbscMap
+ * @author Shanliang JIANG
+ * @run clean RMIConnectorInternalMapTest
+ * @run build RMIConnectorInternalMapTest
+ * @run main RMIConnectorInternalMapTest
+ */
+
+public class RMIConnectorInternalMapTest {
+ public static void main(String[] args) throws Exception {
+ System.out.println("---RMIConnectorInternalMapTest starting...");
+
+ JMXConnectorServer connectorServer = null;
+ JMXConnector connectorClient = null;
+
+ try {
+ MBeanServer mserver = ManagementFactory.getPlatformMBeanServer();
+ JMXServiceURL serverURL = new JMXServiceURL("rmi", "localhost", 0);
+ connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(serverURL, null, mserver);
+ connectorServer.start();
+
+ JMXServiceURL serverAddr = connectorServer.getAddress();
+ connectorClient = JMXConnectorFactory.connect(serverAddr, null);
+ connectorClient.connect();
+
+ Field rmbscMapField = RMIConnector.class.getDeclaredField("rmbscMap");
+ rmbscMapField.setAccessible(true);
+ Map> map =
+ (Map>) rmbscMapField.get(connectorClient);
+ if (map != null && !map.isEmpty()) { // failed
+ throw new RuntimeException("RMIConnector's rmbscMap must be empty at the initial time.");
+ }
+
+ Subject delegationSubject =
+ new Subject(true,
+ Collections.singleton(new JMXPrincipal("delegate")),
+ Collections.EMPTY_SET,
+ Collections.EMPTY_SET);
+ MBeanServerConnection mbsc1 =
+ connectorClient.getMBeanServerConnection(delegationSubject);
+ MBeanServerConnection mbsc2 =
+ connectorClient.getMBeanServerConnection(delegationSubject);
+
+ if (mbsc1 == null) {
+ throw new RuntimeException("Got null connection.");
+ }
+ if (mbsc1 != mbsc2) {
+ throw new RuntimeException("Not got same connection with a same subject.");
+ }
+
+ map = (Map>) rmbscMapField.get(connectorClient);
+ if (map == null || map.isEmpty()) { // failed
+ throw new RuntimeException("RMIConnector's rmbscMap has wrong size "
+ + "after creating a delegated connection.");
+ }
+
+ delegationSubject = null;
+ mbsc1 = null;
+ mbsc2 = null;
+
+ int i = 0;
+ while (!map.isEmpty() && i++ < 60) {
+ System.gc();
+ Thread.sleep(100);
+ }
+ System.out.println("---GC times: " + i);
+
+ if (!map.isEmpty()) {
+ throw new RuntimeException("Failed to clean RMIConnector's rmbscMap");
+ } else {
+ System.out.println("---RMIConnectorInternalMapTest: PASSED!");
+ }
+ } finally {
+ try {
+ connectorClient.close();
+ connectorServer.stop();
+ } catch (Exception e) {
+ }
+ }
+ }
+}
diff --git a/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorNullSubjectConnTest.java b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorNullSubjectConnTest.java
new file mode 100644
index 00000000000..7b5224e9b92
--- /dev/null
+++ b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorNullSubjectConnTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+import java.lang.management.ManagementFactory;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Field;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.rmi.RMIConnector;
+
+/*
+ * @test
+ * @bug 6566891
+ * @summary Check no memory leak on RMIConnector's nullSubjectConn
+ * @author Shanliang JIANG
+ * @run clean RMIConnectorNullSubjectConnTest
+ * @run build RMIConnectorNullSubjectConnTest
+ * @run main RMIConnectorNullSubjectConnTest
+ */
+
+public class RMIConnectorNullSubjectConnTest {
+ public static void main(String[] args) throws Exception {
+ System.out.println("---RMIConnectorNullSubjectConnTest starting...");
+
+ JMXConnectorServer connectorServer = null;
+ JMXConnector connectorClient = null;
+
+ try {
+ MBeanServer mserver = ManagementFactory.getPlatformMBeanServer();
+ JMXServiceURL serverURL = new JMXServiceURL("rmi", "localhost", 0);
+ connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(serverURL, null, mserver);
+ connectorServer.start();
+
+ JMXServiceURL serverAddr = connectorServer.getAddress();
+ connectorClient = JMXConnectorFactory.connect(serverAddr, null);
+ connectorClient.connect();
+
+ Field nullSubjectConnField = RMIConnector.class.getDeclaredField("nullSubjectConnRef");
+ nullSubjectConnField.setAccessible(true);
+
+ WeakReference weak =
+ (WeakReference)nullSubjectConnField.get(connectorClient);
+
+ if (weak != null && weak.get() != null) {
+ throw new RuntimeException("nullSubjectConnRef must be null at initial time.");
+ }
+
+ MBeanServerConnection conn1 = connectorClient.getMBeanServerConnection(null);
+ MBeanServerConnection conn2 = connectorClient.getMBeanServerConnection(null);
+ if (conn1 == null) {
+ throw new RuntimeException("A connection with null subject should not be null.");
+ } else if (conn1 != conn2) {
+ throw new RuntimeException("The 2 connections with null subject are not equal.");
+ }
+
+ conn1 = null;
+ conn2 = null;
+ int i = 1;
+ do {
+ System.gc();
+ Thread.sleep(100);
+ weak = (WeakReference)nullSubjectConnField.get(connectorClient);
+ } while ((weak != null && weak.get() != null) && i++ < 60);
+
+ System.out.println("---GC times: " + i);
+
+ if (weak != null && weak.get() != null) {
+ throw new RuntimeException("Failed to clean RMIConnector's nullSubjectConn");
+ } else {
+ System.out.println("---RMIConnectorNullSubjectConnTest: PASSED!");
+ }
+ } finally {
+ try {
+ connectorClient.close();
+ connectorServer.stop();
+ } catch (Exception e) {
+ }
+ }
+ }
+}
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestCallerSensitive.java b/jdk/test/jdk/lambda/MethodReferenceTestCallerSensitive.java
new file mode 100644
index 00000000000..805a6a203cb
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestCallerSensitive.java
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Field;
+import java.util.function.Function;
+
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class MethodReferenceTestCallerSensitive {
+
+ private static void getF(T arg) {
+ Function,Field[]> firstFunction = Class::getFields;
+ }
+
+ public void testConstructorReferenceVarArgs() {
+ getF("Hello World");
+ }
+
+}
diff --git a/jdk/test/sun/java2d/cmm/ProfileOp/DisposalCrashTest.java b/jdk/test/sun/java2d/cmm/ProfileOp/DisposalCrashTest.java
new file mode 100644
index 00000000000..ab8527d76da
--- /dev/null
+++ b/jdk/test/sun/java2d/cmm/ProfileOp/DisposalCrashTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8024511
+ * @summary Verifies that instances of color profiles are destroyed correctly.
+ * A crash during profile destruction indicates failure.
+ *
+ * @run main DisposalCrashTest
+ */
+
+import static java.awt.color.ColorSpace.*;
+import java.awt.color.ICC_Profile;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.Vector;
+
+public class DisposalCrashTest {
+
+ static final ReferenceQueue queue = new ReferenceQueue<>();
+ static final Vector> v = new Vector<>();
+
+ public static void main(String[] args) {
+ int[] ids = new int[]{
+ CS_sRGB, CS_CIEXYZ, CS_GRAY, CS_LINEAR_RGB, CS_PYCC
+ };
+
+ for (int id : ids) {
+ ICC_Profile p = getCopyOf(id);
+ }
+
+ while (!v.isEmpty()) {
+ System.gc();
+ System.out.println(".");
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {};
+
+ final Reference extends ICC_Profile> ref = queue.poll();
+ System.out.println("Got reference: " + ref);
+
+ v.remove(ref);
+ }
+
+ System.out.println("Test PASSED.");
+ }
+
+ private static ICC_Profile getCopyOf(int id) {
+ ICC_Profile std = ICC_Profile.getInstance(id);
+
+ byte[] data = std.getData();
+
+ ICC_Profile p = ICC_Profile.getInstance(data);
+
+ WeakReference ref = new WeakReference<>(p, queue);
+
+ v.add(ref);
+
+ return p;
+ }
+}
diff --git a/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java b/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java
index bc14128fcee..f3fa0791d46 100644
--- a/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java
+++ b/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 6476665 6523403 6733501 7042594
+ * @bug 6476665 6523403 6733501 7042594 7043064
* @summary Verifies reading and writing profiles and tags of the standard color
* spaces
* @run main ReadWriteProfileTest
@@ -82,6 +82,7 @@ public class ReadWriteProfileTest implements Runnable {
public void run() {
for (int i = 0; i < cspaces.length; i++) {
+ System.out.println("Profile: " + csNames[i]);
ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]);
byte [] data = pf.getData();
pf = ICC_Profile.getInstance(data);
@@ -92,6 +93,10 @@ public class ReadWriteProfileTest implements Runnable {
}
for (int tagSig : tags[i].keySet()) {
+ String signature = SigToString(tagSig);
+ System.out.printf("Tag: %s\n", signature);
+ System.out.flush();
+
byte [] tagData = pf.getData(tagSig);
byte [] empty = new byte[tagData.length];
boolean emptyDataRejected = false;
@@ -104,15 +109,23 @@ public class ReadWriteProfileTest implements Runnable {
throw new
RuntimeException("Test failed: empty tag data was not rejected.");
}
- pf.setData(tagSig, tagData);
-
+ try {
+ pf.setData(tagSig, tagData);
+ } catch (IllegalArgumentException e) {
+ // let's ignore this exception for Kodak proprietary tags
+ if (isKodakExtention(signature)) {
+ System.out.println("Ignore Kodak tag: " + signature);
+ } else {
+ throw new RuntimeException("Test failed!", e);
+ }
+ }
byte [] tagData1 = pf.getData(tagSig);
if (!Arrays.equals(tagData1, tags[i].get(tagSig)))
{
System.err.println("Incorrect result of getData(int) with" +
" tag " +
- Integer.toHexString(tagSig) +
+ SigToString(tagSig) +
" of " + csNames[i] + " profile");
throw new RuntimeException("Incorrect result of " +
@@ -122,6 +135,19 @@ public class ReadWriteProfileTest implements Runnable {
}
}
+ private static boolean isKodakExtention(String signature) {
+ return signature.matches("K\\d\\d\\d");
+ }
+
+ private static String SigToString(int tagSig ) {
+ return String.format("%c%c%c%c",
+ (char)(0xff & (tagSig >> 24)),
+ (char)(0xff & (tagSig >> 16)),
+ (char)(0xff & (tagSig >> 8)),
+ (char)(0xff & (tagSig)));
+
+ }
+
public static void main(String [] args) {
ReadWriteProfileTest test = new ReadWriteProfileTest();
test.run();
diff --git a/jdk/test/sun/security/krb5/runNameEquals.sh b/jdk/test/sun/security/krb5/runNameEquals.sh
index 6db90c35315..b9cfb08d8b5 100644
--- a/jdk/test/sun/security/krb5/runNameEquals.sh
+++ b/jdk/test/sun/security/krb5/runNameEquals.sh
@@ -22,7 +22,7 @@
#
# @test
-# @bug 6317711 6944847
+# @bug 6317711 6944847 8024046
# @summary Ensure the GSSName has the correct impl which respects
# the contract for equals and hashCode across different configurations.
@@ -56,6 +56,15 @@ case "$OS" in
PATHSEP=":"
FILESEP="/"
NATIVE=true
+ # Not all *nix has native GSS libs installed
+ krb5-config --libs gssapi 2> /dev/null
+ if [ $? != 0 ]; then
+ # Fedora has a different path
+ /usr/kerberos/bin/krb5-config --libs gssapi 2> /dev/null
+ if [ $? != 0 ]; then
+ NATIVE=false
+ fi
+ fi
;;
CYGWIN* )
PATHSEP=";"
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseEngineException.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseEngineException.java
index c6dd8ce9720..b64d424fe88 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseEngineException.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseEngineException.java
@@ -21,17 +21,24 @@
* questions.
*/
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
/*
* @test
* @bug 4969799
* @summary javax.net.ssl.SSLSocket.SSLSocket(InetAddress,int) shouldn't
* throw exception
- *
- * This is making sure that starting a new handshake throws the right
- * exception. There is a similar test for SSLSocket.
- *
+ * @run main/othervm CloseEngineException
*/
+//
+// This is making sure that starting a new handshake throws the right
+// exception. There is a similar test for SSLSocket.
+//
+
import javax.net.ssl.*;
import javax.net.ssl.SSLEngineResult.*;
import java.io.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseInboundException.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseInboundException.java
index 7d9274af36e..1c6103bb353 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseInboundException.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseInboundException.java
@@ -21,11 +21,17 @@
* questions.
*/
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
/*
* @test
* @bug 4931274
* @summary closeInbound does not signal when a close_notify has not
* been received.
+ * @run main/othervm CloseInboundException
* @author Brad Wetmore
*/
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseStart.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseStart.java
index 57224816b71..3c3e2e22b3d 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseStart.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseStart.java
@@ -21,15 +21,22 @@
* questions.
*/
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
/*
* @test
* @bug 5019096
* @summary Add scatter/gather APIs for SSLEngine
- *
- * Check to see if the args are being parsed properly.
- *
+ * @run main/othervm CloseStart
*/
+//
+// Check to see if the args are being parsed properly.
+//
+
import javax.net.ssl.*;
import javax.net.ssl.SSLEngineResult.*;
import java.io.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/DelegatedTaskWrongException.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/DelegatedTaskWrongException.java
index f9548d60be5..e912ff69b95 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/DelegatedTaskWrongException.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/DelegatedTaskWrongException.java
@@ -21,11 +21,16 @@
* questions.
*/
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
/*
* @test
* @bug 4969459
* @summary Delegated tasks are not reflecting the subclasses of SSLException
- *
+ * @run main/othervm DelegatedTaskWrongException
*/
import javax.net.ssl.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EmptyExtensionData.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EmptyExtensionData.java
index f77938869f3..49387e3589b 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EmptyExtensionData.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EmptyExtensionData.java
@@ -21,10 +21,16 @@
* questions.
*/
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
/*
* @test
* @bug 6728126
* @summary Parsing Extensions in Client Hello message is done in a wrong way
+ * @run main/othervm EmptyExtensionData
*/
import javax.net.ssl.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EngineEnforceUseClientMode.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EngineEnforceUseClientMode.java
index ed1f84caeef..b7a1a9c509a 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EngineEnforceUseClientMode.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EngineEnforceUseClientMode.java
@@ -21,11 +21,16 @@
* questions.
*/
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
/*
* @test
* @bug 4980882
* @summary SSLEngine should enforce setUseClientMode
- *
+ * @run main/othervm EngineEnforceUseClientMode
* @author Brad R. Wetmore
*/
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java
index da8e591d922..fbe2f2e7854 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java
@@ -21,16 +21,21 @@
* questions.
*/
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
/*
* @test
* @bug 6207322
* @summary SSLEngine is returning a premature FINISHED message when doing
- * an abbreviated handshake.
+ * an abbreviated handshake.
* @run main/othervm RehandshakeFinished
- *
- * SunJSSE does not support dynamic system properties, no way to re-use
- * system properties in samevm/agentvm mode.
- *
+ * @author Brad Wetmore
+ */
+
+/*
* This test may need some updating if the messages change order.
* Currently I'm expecting that there is a simple renegotiation, with
* each message being contained in a single SSL packet.
@@ -41,8 +46,6 @@
* FINISHED
* CCS
* FINISHED
- *
- * @author Brad Wetmore
*/
/**
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java b/jdk/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java
new file mode 100644
index 00000000000..c25d74c7d2c
--- /dev/null
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java
@@ -0,0 +1,357 @@
+/*
+ * 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.
+ */
+
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
+/*
+ * @test
+ * @bug 7188657
+ * @summary There should be a way to reorder the JSSE ciphers
+ * @run main/othervm UseCipherSuitesOrder
+ * TLS_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA
+ */
+
+import java.io.*;
+import java.net.*;
+import javax.net.ssl.*;
+import java.util.Arrays;
+
+public class UseCipherSuitesOrder {
+
+ /*
+ * =============================================================
+ * 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.
+ */
+ static boolean separateServerThread = false;
+
+ /*
+ * Where do we find the keystores?
+ */
+ static String pathToStores = "../../../../etc";
+ static String keyStoreFile = "keystore";
+ static String trustStoreFile = "truststore";
+ static String passwd = "passphrase";
+
+ /*
+ * Is the server ready to serve?
+ */
+ volatile static boolean serverReady = false;
+
+ /*
+ * Turn on SSL debugging?
+ */
+ static boolean debug = false;
+
+ /*
+ * 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.
+ */
+ void doServerSide() throws Exception {
+ SSLServerSocketFactory sslssf =
+ (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
+ SSLServerSocket sslServerSocket =
+ (SSLServerSocket) sslssf.createServerSocket(serverPort);
+ serverPort = sslServerSocket.getLocalPort();
+
+ // use local cipher suites preference
+ SSLParameters params = sslServerSocket.getSSLParameters();
+ params.setUseCipherSuitesOrder(true);
+ params.setCipherSuites(srvEnabledCipherSuites);
+ sslServerSocket.setSSLParameters(params);
+
+ /*
+ * Signal Client, we're ready for his connect.
+ */
+ serverReady = true;
+
+ SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslIS.read();
+ sslOS.write(85);
+ sslOS.flush();
+
+ SSLSession session = sslSocket.getSession();
+ if (!srvEnabledCipherSuites[0].equals(session.getCipherSuite())) {
+ throw new Exception(
+ "Expected to negotiate " + srvEnabledCipherSuites[0] +
+ " , but not " + session.getCipherSuite());
+ }
+
+ sslSocket.close();
+ }
+
+ /*
+ * Define the client side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doClientSide() throws Exception {
+
+ /*
+ * Wait for server to get started.
+ */
+ while (!serverReady) {
+ Thread.sleep(50);
+ }
+
+ SSLSocketFactory sslsf =
+ (SSLSocketFactory) SSLSocketFactory.getDefault();
+ SSLSocket sslSocket = (SSLSocket)
+ sslsf.createSocket("localhost", serverPort);
+ sslSocket.setEnabledCipherSuites(cliEnabledCipherSuites);
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslOS.write(280);
+ sslOS.flush();
+ sslIS.read();
+
+ sslSocket.close();
+ }
+
+ // client enabled cipher suites
+ private static String[] cliEnabledCipherSuites;
+
+ // server enabled cipher suites
+ private static String[] srvEnabledCipherSuites;
+
+ private static void parseArguments(String[] args) throws Exception {
+ if (args.length != 1) {
+ System.out.println("Usage: java UseCipherSuitesOrder ciphersuites");
+ System.out.println("\tciphersuites: " +
+ "a list of enabled cipher suites, separated with comma");
+ throw new Exception("Incorrect usage");
+ }
+
+ cliEnabledCipherSuites = args[0].split(",");
+
+ if (cliEnabledCipherSuites.length < 2) {
+ throw new Exception("Need to enable at least two cipher suites");
+ }
+
+ // Only need to use 2 cipher suites in server side.
+ srvEnabledCipherSuites = Arrays.copyOf(
+ cliEnabledCipherSuites, 2);
+
+ // Reverse the cipher suite preference in server side.
+ srvEnabledCipherSuites[0] = cliEnabledCipherSuites[1];
+ srvEnabledCipherSuites[1] = cliEnabledCipherSuites[0];
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+
+ // use any free port by default
+ volatile int serverPort = 0;
+
+ volatile Exception serverException = null;
+ volatile Exception clientException = null;
+
+ public static void main(String[] args) throws Exception {
+ // parse the arguments
+ parseArguments(args);
+
+ 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");
+
+ /*
+ * Start the tests.
+ */
+ new UseCipherSuitesOrder();
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ UseCipherSuitesOrder() 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!
+ }
+
+ 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;
+ }
+ }
+ }
+
+ 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;
+ }
+ }
+ }
+}
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java b/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java
index 4d5460739cd..a6a6912c0aa 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java
@@ -34,7 +34,7 @@ public class IllegalSNIName {
public static void main(String[] args) throws Exception {
String[] illegalNames = {
- "example\u3003\u3002com",
+ "example\u3002\u3002com",
"example..com",
"com\u3002",
"com.",
diff --git a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.java b/jdk/test/sun/tools/jconsole/ImmutableResourceTest.java
deleted file mode 100644
index 082776667a4..00000000000
--- a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please 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 isn't the test case: ImmutableResourceTest.sh is.
- * Refer to ImmutableResourceTest.sh when running this test.
- *
- * @bug 6287579
- * @summary SubClasses of ListResourceBundle should fix getContents()
- */
-import java.util.ResourceBundle;
-
-public class ImmutableResourceTest {
-
- public static void main(String[] args) throws Exception {
-
- /* Reach under the covers and get the message strings */
- sun.tools.jconsole.resources.JConsoleResources jcr =
- new sun.tools.jconsole.resources.JConsoleResources ();
- Object [][] testData = jcr.getContents();
-
- /* Shred our copy of the message strings */
- for (int ii = 0; ii < testData.length; ii++) {
- testData[ii][0] = "xxx";
- testData[ii][1] = "yyy";
- }
-
- /*
- * Try a lookup for the shredded key.
- * If this is successful we have a problem.
- */
- String ss = sun.tools.jconsole.Resources.getText("xxx");
- if ("yyy".equals(ss)) {
- throw new Exception ("SubClasses of ListResourceBundle should fix getContents()");
- }
- System.out.println("...Finished.");
- }
-}
diff --git a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.sh b/jdk/test/sun/tools/jconsole/ImmutableResourceTest.sh
deleted file mode 100644
index dedf21271b0..00000000000
--- a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.sh
+++ /dev/null
@@ -1,111 +0,0 @@
-#
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test
-# @bug 6287579
-# @summary SubClasses of ListResourceBundle should fix getContents()
-#
-# @run shell ImmutableResourceTest.sh
-
-# Beginning of subroutines:
-status=1
-
-#Call this from anywhere to fail the test with an error message
-# usage: fail "reason why the test failed"
-fail()
- { echo "The test failed :-("
- echo "$*" 1>&2
- echo "exit status was $status"
- exit $status
- } #end of fail()
-
-#Call this from anywhere to pass the test with a message
-# usage: pass "reason why the test passed if applicable"
-pass()
- { echo "The test passed!!!"
- echo "$*" 1>&2
- exit 0
- } #end of pass()
-
-# end of subroutines
-
-# The beginning of the script proper
-
-OS=`uname -s`
-case "$OS" in
- SunOS | Linux | Darwin )
- PATHSEP=":"
- ;;
-
- Windows* | CYGWIN*)
- PATHSEP=";"
- ;;
-
- # catch all other OSs
- * )
- echo "Unrecognized system! $OS"
- fail "Unrecognized system! $OS"
- ;;
-esac
-
-TARGETCLASS="ImmutableResourceTest"
-if [ -z "${TESTJAVA}" ] ; then
- # TESTJAVA is not set, so the test is running stand-alone.
- # TESTJAVA holds the path to the root directory of the build of the JDK
- # to be tested. That is, any java files run explicitly in this shell
- # should use TESTJAVA in the path to the java interpreter.
- # So, we'll set this to the JDK spec'd on the command line. If none
- # is given on the command line, tell the user that and use a default.
- # THIS IS THE JDK BEING TESTED.
- if [ -n "$1" ] ; then
- TESTJAVA=$1
- else
- TESTJAVA=$JAVA_HOME
- fi
- TESTSRC=.
- TESTCLASSES=.
- #Deal with .class files:
-fi
-#
-echo "JDK under test is: $TESTJAVA"
-#
-CP="-classpath ${TESTCLASSES}${PATHSEP}${TESTJAVA}/lib/jconsole.jar"
-# Compile the test class using the classpath we need:
-#
-env
-#
-set -vx
-#
-#Compile. jconsole.jar is required on the classpath.
-${TESTJAVA}/bin/javac -d "${TESTCLASSES}" ${CP} -g \
- "${TESTSRC}"/"${TARGETCLASS}".java
-#
-#Run the test class, again with the classpath we need:
-${TESTJAVA}/bin/java ${CP} ${TARGETCLASS}
-status=$?
-echo "test status was: $status"
-if [ $status -eq "0" ];
- then pass ""
-
- else fail "unspecified test failure"
-fi
diff --git a/jdk/test/sun/tools/jconsole/ResourceCheckTest.java b/jdk/test/sun/tools/jconsole/ResourceCheckTest.java
index 6d4e27be860..1ed5bb642c7 100644
--- a/jdk/test/sun/tools/jconsole/ResourceCheckTest.java
+++ b/jdk/test/sun/tools/jconsole/ResourceCheckTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -27,377 +27,134 @@
* This isn't the test case: ResourceCheckTest.sh is.
* Refer to ResourceCheckTest.sh when running this test.
*
- * @bug 5008856 5023573 5024917 5062569
+ * @bug 5008856 5023573 5024917 5062569 7172176
* @summary 'missing resource key' error for key = "Operating system"
*/
-import java.awt.event.KeyEvent;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import sun.tools.jconsole.Messages;
import sun.tools.jconsole.Resources;
+/*
+ * Ensures that there is a one-to-one mapping between constants in the
+ * Message class and the keys in the sun.tools.jconsole.resources.messages
+ * bundle.
+ *
+ * An error will be thrown if there is a:
+ *
+ * - key in the resource bundle that doesn't have a public static field with
+ * the same name in the Message class.
+ *
+ * - public static field in the Message class that doesn't have a key with
+ * the same name in the resource bundle.
+ *
+ * - message with a mnemonic identifier(&) for which a mnemonic can't
+ * be looked up using Resources#getMnemonicInt().
+ *
+ */
public class ResourceCheckTest {
+ private static final String MISSING_RESOURCE_KEY_PREFIX = "missing message for";
+ private static final String RESOURCE_BUNDLE = "sun.tools.jconsole.resources.messages";
+ private static final String NEW_LINE = String.format("%n");
- public static void main(String[] args){
- Object [][] testData = {
- {"<", "", "", "", ""},
- {"<<", "", "", "", ""},
- {">", "", "", "", ""},
- {" 1 day", "", "", "", ""},
- {" 1 hour", "", "", "", ""},
- {" 1 min", "", "", "", ""},
- {" 1 month", "", "", "", ""},
- {" 1 year", "", "", "", ""},
- {" 2 hours", "", "", "", ""},
- {" 3 hours", "", "", "", ""},
- {" 3 months", "", "", "", ""},
- {" 5 min", "", "", "", ""},
- {" 6 hours", "", "", "", ""},
- {" 6 months", "", "", "", ""},
- {" 7 days", "", "", "", ""},
- {"10 min", "", "", "", ""},
- {"12 hours", "", "", "", ""},
- {"30 min", "", "", "", ""},
- {"ACTION", "", "", "", ""},
- {"ACTION_INFO", "", "", "", ""},
- {"All", "", "", "", ""},
- {"Architecture", "", "", "", ""},
- {"Attribute", "", "", "", ""},
- {"Attribute value", "", "", "", ""},
- {"Attribute values", "", "", "", ""},
- {"Attributes", "", "", "", ""},
- {"Blank", "", "", "", ""},
- {"BlockedCount WaitedCount", "BlockedCount", "WaitedCount", "", ""},
- {"Boot class path", "", "", "", ""},
- {"BorderedComponent.moreOrLessButton.toolTip", "", "", "", ""},
- {"Close", "", "", "", ""},
- {"CPU Usage", "", "", "", ""},
- {"CPUUsageFormat","PhonyPercentage", "", "", ""},
- {"Cancel", "", "", "", ""},
- {"Cascade", "", "", "", ""},
- {"Cascade.mnemonic", "", "", "", ""},
- {"Chart:", "", "", "", ""},
- {"Chart:.mnemonic", "", "", "", ""},
- {"ClassTab.infoLabelFormat", "LoadedCount", "UnloadedCount", "TotalCount", ""},
- {"ClassTab.loadedClassesPlotter.accessibleName", "", "", "", ""},
- {"Class path", "", "", "", ""},
- {"Classes", "", "", "", ""},
- {"ClassName", "", "", "", ""},
- {"Column.Name", "", "", "", ""},
- {"Column.PID", "", "", "", ""},
- {"Committed", "", "", "", ""},
- {"Committed memory", "", "", "", ""},
- {"Committed virtual memory", "", "", "", ""},
- {"Compiler", "", "", "", ""},
- {"Connect...", "", "", "", ""},
- {"Connect", "", "", "", ""},
- {"Connect.mnemonic", "", "", "", ""},
- {"ConnectDialog.connectButton.toolTip", "", "", "", ""},
- {"ConnectDialog.accessibleDescription", "", "", "", ""},
- {"ConnectDialog.masthead.accessibleName", "", "", "", ""},
- {"ConnectDialog.masthead.title", "", "", "", ""},
- {"ConnectDialog.statusBar.accessibleName", "", "", "", ""},
- {"ConnectDialog.title", "", "", "", ""},
- {"Connected. Click to disconnect.", "", "", "", ""},
- {"connectingTo1", "PhonyConnectionName", "", "", ""},
- {"connectingTo2", "PhonyConnectionName", "", "", ""},
- {"connectionFailed1", "", "", "", ""},
- {"connectionFailed2", "PhonyConnectionName", "", "", ""},
- {"connectionLost1", "", "", "", ""},
- {"connectionLost2", "PhonyConnectionName", "", "", ""},
- {"Connection failed", "", "", "", ""},
- {"Connection", "", "", "", ""},
- {"Connection.mnemonic", "", "", "", ""},
- {"Connection name", "", "", "", ""},
- {"ConnectionName (disconnected)", "Phony", "Phony", "", ""},
- {"Constructor", "", "", "", ""},
- {"Create", "Phony", "Phony", "", ""},
- {"Current classes loaded", "", "", "", ""},
- {"Current heap size", "", "", "", ""},
- {"Current value", "PhonyValue", "", "", ""},
- {"Daemon threads", "", "", "", ""},
- {"deadlockAllTab", "", "", "", ""},
- {"deadlockTab", "", "", "", ""},
- {"deadlockTabN", "PhonyInt", "", "", ""},
- {"Description", "", "", "", ""},
- {"Descriptor", "", "", "", ""},
- {"Details", "", "", "", ""},
- {"Detect Deadlock", "", "", "", ""},
- {"Detect Deadlock.mnemonic", "", "", "", ""},
- {"Detect Deadlock.toolTip", "", "", "", ""},
- {"Dimension is not supported:", "", "", "", ""},
- {"Discard chart", "", "", "", ""},
- {"Disconnected. Click to connect.", "", "", "", ""},
- {"Double click to expand/collapse", "", "", "", ""},
- {"Double click to visualize", "", "", "", ""},
- {"DurationDaysHoursMinutes", 0, 13, 54, ""},
- {"DurationDaysHoursMinutes", 1, 13, 54, ""},
- {"DurationDaysHoursMinutes", 2, 13, 54, ""},
- {"DurationDaysHoursMinutes", 1024, 13, 45, ""},
- {"DurationHoursMinutes", 0, 13, "", ""},
- {"DurationHoursMinutes", 1, 0, "", ""},
- {"DurationHoursMinutes", 1, 1, "", ""},
- {"DurationHoursMinutes", 2, 42, "", ""},
- {"DurationMinutes", 0, "", "", ""},
- {"DurationMinutes", 1, "", "", ""},
- {"DurationMinutes", 2, "", "", ""},
- {"DurationSeconds", 0, "", "", ""},
- {"DurationSeconds", 1, "", "", ""},
- {"DurationSeconds", 2, "", "", ""},
- {"Empty array", "", "", "", ""},
- {"Error", "", "", "", ""},
- {"Error: MBeans already exist", "", "", "", ""},
- {"Error: MBeans do not exist", "", "", "", ""},
- {"Event", "", "", "", ""},
- {"Exit", "", "", "", ""},
- {"Exit.mnemonic", "", "", "", ""},
- {"expand", "", "", "", ""},
- {"Fail to load plugin", "", "", "", ""},
- {"FileChooser.fileExists.cancelOption", "", "", "", ""},
- {"FileChooser.fileExists.message", "PhonyFileName", "", "", ""},
- {"FileChooser.fileExists.okOption", "", "", "", ""},
- {"FileChooser.fileExists.title", "", "", "", ""},
- {"FileChooser.savedFile", "PhonyFilePath", "PhonyFileSize", "", ""},
- {"FileChooser.saveFailed.message", "PhonyFilePath", "PhonyMessage", "", ""},
- {"FileChooser.saveFailed.title", "", "", "", ""},
- {"Free physical memory", "", "", "", ""},
- {"Free swap space", "", "", "", ""},
- {"Garbage collector", "", "", "", ""},
- {"GC time", "", "", "", ""},
- {"GC time details", 54, "Phony", 11, ""},
- {"GcInfo", "Phony", -1, 768, ""},
- {"GcInfo", "Phony", 0, 768, ""},
- {"GcInfo", "Phony", 1, 768, ""},
- {"Heap", "", "", "", ""},
- {"Heap Memory Usage", "", "", "", ""},
- {"Help.AboutDialog.accessibleDescription", "", "", "", ""},
- {"Help.AboutDialog.jConsoleVersion", "DummyVersion", "", "", ""},
- {"Help.AboutDialog.javaVersion", "DummyVersion", "", "", ""},
- {"Help.AboutDialog.masthead.accessibleName", "", "", "", ""},
- {"Help.AboutDialog.masthead.title", "", "", "", ""},
- {"Help.AboutDialog.title", "", "", "", ""},
- {"Help.AboutDialog.userGuideLink", "DummyMessage", "", "", ""},
- {"Help.AboutDialog.userGuideLink.mnemonic", "", "", "", ""},
- {"Help.AboutDialog.userGuideLink.url", "DummyURL", "", "", ""},
- {"HelpMenu.About.title", "", "", "", ""},
- {"HelpMenu.About.title.mnemonic", "", "", "", ""},
- {"HelpMenu.UserGuide.title", "", "", "", ""},
- {"HelpMenu.UserGuide.title.mnemonic", "", "", "", ""},
- {"HelpMenu.title", "", "", "", ""},
- {"HelpMenu.title.mnemonic", "", "", "", ""},
- {"Hotspot MBeans...", "", "", "", ""},
- {"Hotspot MBeans....mnemonic", "", "", "", ""},
- {"Hotspot MBeans.dialog.accessibleDescription", "", "", "", ""},
- {"Impact", "", "", "", ""},
- {"Info", "", "", "", ""},
- {"INFO", "", "", "", ""},
- {"Invalid plugin path", "", "", "", ""},
- {"Invalid URL", "", "", "", ""},
- {"Is", "", "", "", ""},
- {"Java Monitoring & Management Console", "", "", "", ""},
- {"Java Virtual Machine", "", "", "", ""},
- {"JConsole: ", "", "", "", ""},
- {"JConsole.accessibleDescription", "", "", "", ""},
- {"JConsole version", "PhonyVersion", "", "", ""},
- {"JIT compiler", "", "", "", ""},
- {"Library path", "", "", "", ""},
- {"Live Threads", "", "", "", ""},
- {"Loaded", "", "", "", ""},
- {"Local Process:", "", "", "", ""},
- {"Local Process:.mnemonic", "", "", "", ""},
- {"Manage Hotspot MBeans in: ", "", "", "", ""},
- {"Management Not Enabled", "", "", "", ""},
- {"Management Will Be Enabled", "", "", "", ""},
- {"Masthead.font", "", "", "", ""},
- {"Max", "", "", "", ""},
- {"Max", "", "", "", ""},
- {"Maximum heap size", "", "", "", ""},
- {"MBeanAttributeInfo", "", "", "", ""},
- {"MBeanInfo", "", "", "", ""},
- {"MBeanNotificationInfo", "", "", "", ""},
- {"MBeanOperationInfo", "", "", "", ""},
- {"MBeans", "", "", "", ""},
- {"MBeansTab.clearNotificationsButton", "", "", "", ""},
- {"MBeansTab.clearNotificationsButton.mnemonic", "", "", "", ""},
- {"MBeansTab.clearNotificationsButton.toolTip", "", "", "", ""},
- {"MBeansTab.compositeNavigationMultiple", 0, 0, "", ""},
- {"MBeansTab.compositeNavigationSingle", "", "", "", ""},
- {"MBeansTab.refreshAttributesButton", "", "", "", ""},
- {"MBeansTab.refreshAttributesButton.mnemonic", "", "", "", ""},
- {"MBeansTab.refreshAttributesButton.toolTip", "", "", "", ""},
- {"MBeansTab.subscribeNotificationsButton", "", "", "", ""},
- {"MBeansTab.subscribeNotificationsButton.mnemonic", "", "", "", ""},
- {"MBeansTab.subscribeNotificationsButton.toolTip", "", "", "", ""},
- {"MBeansTab.tabularNavigationMultiple", 0, 0, "", ""},
- {"MBeansTab.tabularNavigationSingle", "", "", "", ""},
- {"MBeansTab.unsubscribeNotificationsButton", "", "", "", ""},
- {"MBeansTab.unsubscribeNotificationsButton.mnemonic", "", "", "", ""},
- {"MBeansTab.unsubscribeNotificationsButton.toolTip", "", "", "", ""},
- {"Memory", "", "", "", ""},
- {"MemoryPoolLabel", "PhonyMemoryPool", "", "", ""},
- {"MemoryTab.heapPlotter.accessibleName", "", "", "", ""},
- {"MemoryTab.infoLabelFormat", "UsedCount", "CommittedCount", "MaxCount", ""},
- {"MemoryTab.nonHeapPlotter.accessibleName", "", "", "", ""},
- {"MemoryTab.poolChart.aboveThreshold", "Threshold", "", "", ""},
- {"MemoryTab.poolChart.accessibleName", "", "", "", ""},
- {"MemoryTab.poolChart.belowThreshold", "Threshold", "", "", ""},
- {"MemoryTab.poolPlotter.accessibleName", "PhonyMemoryPool", "", "", ""},
- {"Message", "", "", "", ""},
- {"Method successfully invoked", "", "", "", ""},
- {"Monitor locked", "", "", "", ""},
- {"Minimize All", "", "", "", ""},
- {"Minimize All.mnemonic", "", "", "", ""},
- {"Name", "", "", "", ""},
- {"Name and Build", "PhonyName", "PhonyBuild", "", ""},
- {"Name Build and Mode", "PhonyName", "PhonyBuild", "PhonyMode", ""},
- {"Name State", "PhonyName", "PhonyState", "", ""},
- {"Name State LockName", "PhonyName", "PhonyState", "PhonyLock", ""},
- {"Name State LockName LockOwner", "PhonyName", "PhonyState", "PhonyLock", "PhonyOwner"},
- {"New Connection...", "", "", "", ""},
- {"New Connection....mnemonic", "", "", "", ""},
- {"No deadlock detected", "", "", "", ""},
- {"Non-Heap", "", "", "", ""},
- {"Non-Heap Memory Usage", "", "", "", ""},
- {"Notification", "", "", "", ""},
- {"Notification buffer", "", "", "", ""},
- {"Notifications", "", "", "", ""},
- {"NotifTypes", "", "", "", ""},
- {"Number of Loaded Classes", "", "", "", ""},
- {"Number of processors", "", "", "", ""},
- {"Number of Threads", "", "", "", ""},
- {"ObjectName", "", "", "", ""},
- {"Operating System", "", "", "", ""},
- {"Operation", "", "", "", ""},
- {"Operation invocation", "", "", "", ""},
- {"Operation return value", "", "", "", ""},
- {"Operations", "", "", "", ""},
- {"Overview", "", "", "", ""},
- {"OverviewPanel.plotter.accessibleName", "PhonyPlotter", "", "", ""},
- {"Parameter", "", "", "", ""},
- {"Password: ", "", "", "", ""},
- {"Password: .mnemonic", "", "", "", ""},
- {"Password.accessibleName", "", "", "", ""},
- {"Peak", "", "", "", ""},
- {"Perform GC", "", "", "", ""},
- {"Perform GC.mnemonic", "", "", "", ""},
- {"Perform GC.toolTip", "", "", "", ""},
- {"Plotter.accessibleName", "", "", "", ""},
- {"Plotter.accessibleName.keyAndValue", "Key", "Value", "", ""},
- {"Plotter.accessibleName.noData", "", "", "", ""},
- {"Plotter.saveAsMenuItem", "", "", "", ""},
- {"Plotter.saveAsMenuItem.mnemonic", "", "", "", ""},
- {"Plotter.timeRangeMenu", "", "", "", ""},
- {"Plotter.timeRangeMenu.mnemonic", "", "", "", ""},
- {"plot", "", "", "", ""},
- {"Problem adding listener", "", "", "", ""},
- {"Problem displaying MBean", "", "", "", ""},
- {"Problem invoking", "", "", "", ""},
- {"Problem removing listener", "", "", "", ""},
- {"Problem setting attribute", "", "", "", ""},
- {"Process CPU time", "", "", "", ""},
- {"Readable", "", "", "", ""},
- {"Reconnect", "", "", "", ""},
- {"Remote Process:", "", "", "", ""},
- {"Remote Process:.mnemonic", "", "", "", ""},
- {"Remote Process.textField.accessibleName", "", "", "", ""},
- {"remoteTF.usage", "", "", "", ""},
- {"Restore All", "", "", "", ""},
- {"Restore All.mnemonic", "", "", "", ""},
- {"ReturnType", "", "", "", ""},
- {"SeqNum", "", "", "", ""},
- {"Size Bytes", 512, "", "", ""},
- {"Size Gb", 512, "", "", ""},
- {"Size Kb", 512, "", "", ""},
- {"Size Mb", 512, "", "", ""},
- {"Source", "", "", "", ""},
- {"Stack trace", "", "", "", ""},
- {"SummaryTab.headerDateTimeFormat", "", "", "", ""},
- {"SummaryTab.pendingFinalization.label", "", "", "", ""},
- {"SummaryTab.pendingFinalization.value", "ObjectCount", "", "", ""},
- {"SummaryTab.tabName", "", "", "", ""},
- {"SummaryTab.vmVersion", "VMName", "VMVersion", "", ""},
- {"ThreadTab.infoLabelFormat", "LiveCount", "PeakCount", "TotalCount", ""},
- {"ThreadTab.threadInfo.accessibleName", "", "", "", ""},
- {"ThreadTab.threadPlotter.accessibleName", "", "", "", ""},
- {"Threads", "", "", "", ""},
- {"Threshold", "", "", "", ""},
- {"Tile", "", "", "", ""},
- {"Tile.mnemonic", "", "", "", ""},
- {"Time", "", "", "", ""},
- {"Time Range:", "", "", "", ""},
- {"Time Range:.mnemonic", "", "", "", ""},
- {"TimeStamp", "", "", "", ""},
- {"Total classes loaded", "", "", "", ""},
- {"Total classes unloaded", "", "", "", ""},
- {"Total compile time", "", "", "", ""},
- {"Total Loaded", "", "", "", ""},
- {"Total physical memory", "", "", "", ""},
- {"Total swap space", "", "", "", ""},
- {"Total threads started", "", "", "", ""},
- {"Type", "", "", "", ""},
- {"Unavailable", "", "", "", ""},
- {"UNKNOWN", "", "", "", ""},
- {"Unregister", "", "", "", ""},
- {"Uptime", "", "", "", ""},
- {"Usage Threshold", "", "", "", ""},
- {"Used", "", "", "", ""},
- {"Username: ", "", "", "", ""},
- {"Username: .mnemonic", "", "", "", ""},
- {"Username.accessibleName", "", "", "", ""},
- {"UserData", "", "", "", ""},
- {"Value", "", "", "", ""},
- {"Vendor", "", "", "", ""},
- {"Verbose Output", "", "", "", ""},
- {"Verbose Output.toolTip", "", "", "", ""},
- {"visualize", "", "", "", ""},
- {"VM", "", "", "", ""},
- {"VMInternalFrame.accessibleDescription", "", "", "", ""},
- {"VM arguments", "", "", "", ""},
- {"Virtual Machine", "", "", "", ""},
- {"Window", "", "", "", ""},
- {"Window.mnemonic", "", "", "", ""},
- {"Writable", "", "", "", ""},
- {"zz usage text", "PhonyName", "", "", ""},
- };
- //boolean verbose = false;
- boolean verbose = true;
-
- long badLookups = 0;
- System.out.println("Start...");
- for (int ii = 0; ii < testData.length; ii++) {
- String key = (String)testData[ii][0];
-
- if (key.endsWith(".mnemonic")) {
- String baseKey = key.substring(0, key.length() - ".mnemonic".length());
- int mnemonic = Resources.getMnemonicInt(baseKey);
- if (mnemonic == 0) {
- badLookups++;
- System.out.println("****lookup failed for key = " + key);
+ public static void main(String... args) {
+ List errors = new ArrayList<>();
+ // Ensure that all Message fields have a corresponding key/value
+ // in the resource bundle and that mnemonics can be looked
+ // up where applicable.
+ ResourceBundle rb = ResourceBundle.getBundle(RESOURCE_BUNDLE);
+ for (Field field : Messages.class.getFields()) {
+ if (isResourceKeyField(field)) {
+ String resourceKey = field.getName();
+ String message = readField(field);
+ if (message.startsWith(MISSING_RESOURCE_KEY_PREFIX)) {
+ errors.add("Can't find message (and perhaps mnemonic) for "
+ + Messages.class.getSimpleName() + "."
+ + resourceKey + " in resource bundle.");
} else {
- if (verbose) {
- System.out.println(" mnemonic: " + KeyEvent.getKeyText(mnemonic));
+ String resourceMessage = rb.getString(resourceKey);
+ if (hasMnemonicIdentifier(resourceMessage)) {
+ int mi = Resources.getMnemonicInt(message);
+ if (mi == 0) {
+ errors.add("Could not look up mnemonic for message '"
+ + message + "'.");
+ }
}
}
- continue;
}
+ }
- String ss = Resources.getText(key,
- testData[ii][1],
- testData[ii][2],
- testData[ii][3],
- testData[ii][4]);
- if (ss.startsWith("missing resource key")) {
- badLookups++;
- System.out.println("****lookup failed for key = " + key);
- } else {
- if (verbose) {
- System.out.println(" " + ss);
+ // Ensure that there is Message class field for every resource key.
+ for (String key : Collections.list(rb.getKeys())) {
+ try {
+ Messages.class.getField(key);
+ } catch (NoSuchFieldException nfe) {
+ errors.add("Can't find static field ("
+ + Messages.class.getSimpleName() + "." + key
+ + ") matching '" + key
+ + "' in resource bundle. Unused message?");
+ }
+ }
+
+ if (errors.size() > 0) {
+ throwError(errors);
+ }
+ }
+
+ private static String readField(Field field) {
+ try {
+ return (String) field.get(null);
+ } catch (IllegalArgumentException | IllegalAccessException e) {
+ throw new Error("Could not access field " + field.getName()
+ + " when trying to read resource message.");
+ }
+ }
+
+ private static boolean isResourceKeyField(Field field) {
+ int modifiers = field.getModifiers();
+ return Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers);
+ }
+
+ private static boolean hasMnemonicIdentifier(String s) {
+ for (int i = 0; i < s.length() - 1; i++) {
+ if (s.charAt(i) == '&') {
+ if (s.charAt(i + 1) != '&') {
+ return true;
+ } else {
+ i++;
}
}
}
- if (badLookups > 0) {
- throw new Error ("Resource lookup failed " + badLookups +
- " time(s); Test failed");
+ return false;
+ }
+
+ private static void throwError(List errors) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("Found ");
+ buffer.append(errors.size());
+ buffer.append(" error(s) when checking one-to-one mapping ");
+ buffer.append("between Message and resource bundle keys in ");
+ buffer.append(RESOURCE_BUNDLE);
+ buffer.append(" with ");
+ buffer.append(Locale.getDefault());
+ buffer.append(" locale.");
+ buffer.append(NEW_LINE);
+ int errorIndex = 1;
+ for (String error : errors) {
+ buffer.append("Error ");
+ buffer.append(errorIndex);
+ buffer.append(": ");
+ buffer.append(error);
+ buffer.append(NEW_LINE);
+ errorIndex++;
}
- System.out.println("...Finished.");
+ throw new Error(buffer.toString());
}
}
diff --git a/jdk/test/sun/tools/jconsole/ResourceCheckTest.sh b/jdk/test/sun/tools/jconsole/ResourceCheckTest.sh
index bec63a7992f..01c2e4b6f01 100644
--- a/jdk/test/sun/tools/jconsole/ResourceCheckTest.sh
+++ b/jdk/test/sun/tools/jconsole/ResourceCheckTest.sh
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 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
@@ -54,7 +54,7 @@ pass()
OS=`uname -s`
case "$OS" in
- SunOS | Linux )
+ SunOS | Linux | Darwin)
PATHSEP=":"
;;
diff --git a/jdk/test/sun/util/locale/provider/Bug8024141.java b/jdk/test/sun/util/locale/provider/Bug8024141.java
new file mode 100644
index 00000000000..24bd0f3024a
--- /dev/null
+++ b/jdk/test/sun/util/locale/provider/Bug8024141.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8024141
+ * @summary Test for cache support of sun.util.locale.provider.LocaleResources.getTimeZoneNames
+ */
+
+import java.time.ZoneId;
+import static java.util.Locale.ENGLISH;
+import static java.time.format.TextStyle.FULL;
+import static java.time.format.TextStyle.SHORT;
+
+public class Bug8024141 {
+ // This test assumes that the two time zones are in GMT. If
+ // they become different zones, need to pick up another zones.
+ private static final String[] ZONES = {
+ "Africa/Abidjan",
+ "Africa/Bamako"
+ };
+
+ public static void main(String[] args) {
+ ZoneId gmt = ZoneId.of("GMT");
+ String gmtName = gmt.getDisplayName(FULL, ENGLISH);
+ String gmtAbbr = gmt.getDisplayName(SHORT, ENGLISH);
+
+ for (String zone : ZONES) {
+ ZoneId id = ZoneId.of(zone);
+ String name = id.getDisplayName(FULL, ENGLISH);
+ String abbr = id.getDisplayName(SHORT, ENGLISH);
+
+ if (!name.equals(gmtName) || !abbr.equals(gmtAbbr)) {
+ throw new RuntimeException("inconsistent name/abbr for " + zone + ":\n"
+ + "name=" + name + ", abbr=" + abbr);
+ }
+ }
+ }
+}
diff --git a/langtools/.hgtags b/langtools/.hgtags
index d15910c1e57..2210809d462 100644
--- a/langtools/.hgtags
+++ b/langtools/.hgtags
@@ -228,3 +228,5 @@ ce5a90df517bdceb2739d7dd3e6764b070def802 jdk8-b98
dd4a00c220c6e14d9b2ce93a2bd436a1d04f0d03 jdk8-b104
375834b5cf086dd7ce9e49f602d81bb51d3e0fa9 jdk8-b105
fcd768844b9926c5f994292ec6350c20cc7c0f76 jdk8-b106
+3f274927ec1863544b8214262ab02b7de2970da6 jdk8-b107
+252f872b8a2f81a416f9127e77924ca56a4578b0 jdk8-b108
diff --git a/langtools/README b/langtools/README
index bc8873178ef..94beb071e92 100644
--- a/langtools/README
+++ b/langtools/README
@@ -32,7 +32,7 @@ tests that the compiler performs according to the specifications in
JLS and JVMS.
In addition, there is a substantial collection of regression and unit
-tests for all the tools in the maain langtools test/ directory.
+tests for all the tools in the main langtools test/ directory.
Finally, there is a small set of tests to do basic validation of a build
of the langtools workspace for use by JDK. These tests check the contents
diff --git a/langtools/make/jprt.properties b/langtools/make/jprt.properties
index c0399ed7083..734fa8cd89d 100644
--- a/langtools/make/jprt.properties
+++ b/langtools/make/jprt.properties
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 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
@@ -40,8 +40,8 @@ jprt.build.targets= \
linux_i586_2.6-{product|fastdebug}, \
linux_x64_2.6-{product|fastdebug}, \
macosx_x64_10.7-{product|fastdebug}, \
- windows_i586_5.1-{product|fastdebug}, \
- windows_x64_5.2-{product|fastdebug}
+ windows_i586_6.1-{product|fastdebug}, \
+ windows_x64_6.1-{product|fastdebug}
# Test target list (no fastdebug & limited c2 testing)
jprt.my.test.target.set= \
@@ -52,8 +52,8 @@ jprt.my.test.target.set= \
linux_i586_2.6-product-{c1|c2}-TESTNAME, \
linux_x64_2.6-product-c2-TESTNAME, \
macosx_x64_10.7-product-c2-TESTNAME, \
- windows_i586_5.1-product-c1-TESTNAME, \
- windows_x64_5.2-product-c2-TESTNAME
+ windows_i586_6.1-product-c1-TESTNAME, \
+ windows_x64_6.1-product-c2-TESTNAME
# Default test targets
jprt.make.rule.test.targets= \
@@ -71,8 +71,8 @@ jprt.my.test.target.set= \
linux_i586_2.6-product-{c1|c2}-TESTNAME, \
linux_x64_2.6-product-c2-TESTNAME, \
macosx_x64_10.7-product-c2-TESTNAME, \
- windows_i586_5.1-product-c1-TESTNAME, \
- windows_x64_5.2-product-c2-TESTNAME
+ windows_i586_6.1-product-c1-TESTNAME, \
+ windows_x64_6.1-product-c2-TESTNAME
# Default test targets
jprt.make.rule.test.targets= \
diff --git a/langtools/make/netbeans/langtools/build.xml b/langtools/make/netbeans/langtools/build.xml
index dd2caf9e3bc..cbb007057cc 100644
--- a/langtools/make/netbeans/langtools/build.xml
+++ b/langtools/make/netbeans/langtools/build.xml
@@ -1,6 +1,6 @@
@@ -136,9 +145,9 @@
-
|