--- a/.hgtags Fri Sep 20 17:11:32 2013 -0700
+++ b/.hgtags Fri Sep 20 19:15:59 2013 -0700
@@ -227,3 +227,5 @@
30a1d677a20c6a95f98043d8f20ce570304e3818 jdk8-b103
b5ed503c26ad38869c247c5e32debec217fd056b jdk8-b104
589f4fdc584e373a47cde0162e9eceec9165c381 jdk8-b105
+514b0b69fb9683ef52062fd962a3e0644431f64d jdk8-b106
+892889f445755790ae90e61775bfb59ddc6182b5 jdk8-b107
--- a/.hgtags-top-repo Fri Sep 20 17:11:32 2013 -0700
+++ b/.hgtags-top-repo Fri Sep 20 19:15:59 2013 -0700
@@ -227,3 +227,5 @@
b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103
96c1b9b7524b52c3fcefc90ffad4c767396727c8 jdk8-b104
5166118c59178b5d31001bc4058e92486ee07d9b jdk8-b105
+8e7b4d9fb00fdf1334376aeac050c9bca6d1b383 jdk8-b106
+0874bb4707b723d5bb108d379c557cf41529d1a7 jdk8-b107
--- a/Makefile Fri Sep 20 17:11:32 2013 -0700
+++ b/Makefile Fri Sep 20 19:15:59 2013 -0700
@@ -404,7 +404,6 @@
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_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)
--- a/README-builds.html Fri Sep 20 17:11:32 2013 -0700
+++ b/README-builds.html Fri Sep 20 19:15:59 2013 -0700
@@ -444,10 +444,6 @@
Install
<a href="#vs2010">Visual Studio 2010</a>
</li>
- <li>
- Install the
- <a href="#dxsdk">Microsoft DirectX SDK</a>
- </li>
</ul>
</td>
<td>
@@ -972,25 +968,6 @@
</td>
</tr>
<tr>
- <td><b><code>--with-dxsdk=</code></b><i>path</i></td>
- <td>
- select location of the Windows Direct X SDK install
- <br>
- The <a name="dxsdk">Microsoft DirectX 9.0 SDK</a>
- header files and libraries
- from the Summer 2004 edition
- are required for building OpenJDK.
- This SDK can be downloaded from
- <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=FD044A42-9912-42A3-9A9E-D857199F888E&displaylang=en" target="_blank">
- Microsoft DirectX 9.0 SDK (Summer 2004)</a>.
- If the link above becomes obsolete, the SDK can be found from
- <a href="http://download.microsoft.com" target="_blank">the Microsoft Download Site</a>
- (search with "DirectX 9.0 SDK Update Summer 2004").
- Installation usually will set the environment variable
- <code>DXSDK_DIR</code> to it's install location.
- </td>
- </tr>
- <tr>
<td><b><code>--with-freetype=</code></b><i>path</i></td>
<td>
select the freetype files to use.
--- a/common/autoconf/basics.m4 Fri Sep 20 17:11:32 2013 -0700
+++ b/common/autoconf/basics.m4 Fri Sep 20 19:15:59 2013 -0700
@@ -203,6 +203,15 @@
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.
--- a/common/autoconf/basics_windows.m4 Fri Sep 20 17:11:32 2013 -0700
+++ b/common/autoconf/basics_windows.m4 Fri Sep 20 19:15:59 2013 -0700
@@ -211,7 +211,7 @@
# 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
--- a/common/autoconf/build-aux/autoconf-config.guess Fri Sep 20 17:11:32 2013 -0700
+++ b/common/autoconf/build-aux/autoconf-config.guess Fri Sep 20 19:15:59 2013 -0700
@@ -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 @@
# 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 <http://www.gnu.org/licenses/>.
#
# 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 @@
# the same distribution terms that you use for the rest of that program.
-# Originally written by Per Bothner <per@bothner.com>.
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
+# Originally written by Per Bothner. Please send patches (context
+# diff format) to <config-patches@gnu.org> 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 @@
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 @@
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 @@
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 @@
fi
;;
*)
- os=netbsd
+ os=netbsd
;;
esac
# The OS release
@@ -248,7 +247,7 @@
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 @@
# 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 @@
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 `/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 @@
# 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 @@
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 @@
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
- exit ;;
+ exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit ;;
@@ -557,7 +578,7 @@
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 @@
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 <stdlib.h>
- #include <unistd.h>
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
- 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 @@
# => 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 @@
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 @@
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 @@
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 @@
*: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 @@
[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,91 +886,12 @@
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:*:*)
- 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:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m68*:Linux:*:*)
+ aarch64: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
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
@@ -955,11 +902,90 @@
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 @@
*) 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 @@
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 <features.h>
- #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 @@
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 @@
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 @@
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 @@
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 @@
/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 @@
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 @@
echo ns32k-sni-sysv
fi
exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- # says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
@@ -1227,11 +1209,11 @@
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 @@
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 @@
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 @@
*: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 @@
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 @@
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 @@
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
- "4"
+ "4"
#else
- ""
+ ""
#endif
- ); exit (0);
+ ); exit (0);
#endif
#endif
--- a/common/autoconf/configure Fri Sep 20 17:11:32 2013 -0700
+++ b/common/autoconf/configure Fri Sep 20 19:15:59 2013 -0700
@@ -219,9 +219,4 @@
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
--- a/common/autoconf/configure.ac Fri Sep 20 17:11:32 2013 -0700
+++ b/common/autoconf/configure.ac Fri Sep 20 19:15:59 2013 -0700
@@ -232,9 +232,15 @@
# 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
--- a/common/autoconf/generated-configure.sh Fri Sep 20 17:11:32 2013 -0700
+++ b/common/autoconf/generated-configure.sh Fri Sep 20 19:15:59 2013 -0700
@@ -709,7 +709,6 @@
SHARED_LIBRARY
OBJ_SUFFIX
COMPILER_NAME
-TARGET_BITS_FLAG
JT_HOME
JTREGEXE
LIPO
@@ -766,8 +765,6 @@
BUILD_CXX
BUILD_CC
MSVCR_DLL
-DXSDK_INCLUDE_PATH
-DXSDK_LIB_PATH
VS_PATH
VS_LIB
VS_INCLUDE
@@ -1031,6 +1028,7 @@
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 @@
--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 @@
+# 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 @@
-# Setup the DXSDK paths
-
-
-
@@ -3818,7 +3818,7 @@
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1377850299
+DATE_WHEN_GENERATED=1379504921
###############################################################################
#
@@ -6775,6 +6775,18 @@
VAR_CPU_BITS=64
VAR_CPU_ENDIAN=big
;;
+ s390)
+ VAR_CPU=s390
+ VAR_CPU_ARCH=s390
+ VAR_CPU_BITS=32
+ VAR_CPU_ENDIAN=big
+ ;;
+ s390x)
+ VAR_CPU=s390x
+ VAR_CPU_ARCH=s390
+ VAR_CPU_BITS=64
+ VAR_CPU_ENDIAN=big
+ ;;
sparc)
VAR_CPU=sparc
VAR_CPU_ARCH=sparc
@@ -6883,6 +6895,18 @@
VAR_CPU_BITS=64
VAR_CPU_ENDIAN=big
;;
+ s390)
+ VAR_CPU=s390
+ VAR_CPU_ARCH=s390
+ VAR_CPU_BITS=32
+ VAR_CPU_ENDIAN=big
+ ;;
+ s390x)
+ VAR_CPU=s390x
+ VAR_CPU_ARCH=s390
+ VAR_CPU_BITS=64
+ VAR_CPU_ENDIAN=big
+ ;;
sparc)
VAR_CPU=sparc
VAR_CPU_ARCH=sparc
@@ -8328,7 +8352,7 @@
# 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
@@ -8685,7 +8709,7 @@
# 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
@@ -9039,7 +9063,7 @@
# 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
@@ -9398,7 +9422,7 @@
# 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
@@ -9751,7 +9775,7 @@
# 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
@@ -11051,7 +11075,7 @@
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
@@ -16078,6 +16102,10 @@
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
@@ -16113,6 +16141,10 @@
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
@@ -16175,6 +16207,13 @@
+# 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;
@@ -16252,7 +16291,7 @@
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
@@ -17062,7 +17101,7 @@
# 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
@@ -17562,436 +17601,28 @@
# Check whether --with-dxsdk was given.
if test "${with_dxsdk+set}" = set; then :
- withval=$with_dxsdk;
-fi
+ 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;
-fi
+ 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;
-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"
+ 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
+
fi
@@ -18116,7 +17747,7 @@
# 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
@@ -18427,7 +18058,7 @@
# 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
@@ -18733,7 +18364,7 @@
# 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
@@ -19326,7 +18957,7 @@
# 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
@@ -19762,7 +19393,7 @@
# 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
@@ -20898,7 +20529,7 @@
# 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
@@ -21334,7 +20965,7 @@
# 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
@@ -22235,7 +21866,7 @@
# 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
@@ -22616,7 +22247,7 @@
# 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
@@ -22963,7 +22594,7 @@
# 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
@@ -23300,7 +22931,7 @@
# 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
@@ -23621,7 +23252,7 @@
# 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
@@ -23996,7 +23627,7 @@
# 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
@@ -24302,7 +23933,7 @@
# 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
@@ -24713,7 +24344,7 @@
# 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
@@ -25113,7 +24744,7 @@
# 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
@@ -25442,7 +25073,7 @@
# 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
@@ -25754,7 +25385,7 @@
# 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
@@ -26060,7 +25691,7 @@
# 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
@@ -26366,7 +25997,7 @@
# 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
@@ -26672,7 +26303,7 @@
# 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
@@ -27031,7 +26662,7 @@
# 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
@@ -27391,7 +27022,7 @@
# 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
@@ -27764,7 +27395,7 @@
# 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
@@ -28135,7 +27766,7 @@
# 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
@@ -28444,7 +28075,7 @@
# 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
@@ -28806,35 +28437,41 @@
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}"
-
-
- 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}"
+ # 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_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}"
-
-
- 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}"
+ # 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_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}"
+ CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
+ LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
fi
fi
@@ -33594,6 +33231,7 @@
# 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
@@ -34875,6 +34513,11 @@
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
--- a/common/autoconf/jdk-options.m4 Fri Sep 20 17:11:32 2013 -0700
+++ b/common/autoconf/jdk-options.m4 Fri Sep 20 19:15:59 2013 -0700
@@ -446,7 +446,7 @@
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)
--- a/common/autoconf/platform.m4 Fri Sep 20 17:11:32 2013 -0700
+++ b/common/autoconf/platform.m4 Fri Sep 20 19:15:59 2013 -0700
@@ -60,6 +60,18 @@
VAR_CPU_BITS=64
VAR_CPU_ENDIAN=big
;;
+ s390)
+ VAR_CPU=s390
+ VAR_CPU_ARCH=s390
+ VAR_CPU_BITS=32
+ VAR_CPU_ENDIAN=big
+ ;;
+ s390x)
+ VAR_CPU=s390x
+ VAR_CPU_ARCH=s390
+ VAR_CPU_BITS=64
+ VAR_CPU_ENDIAN=big
+ ;;
sparc)
VAR_CPU=sparc
VAR_CPU_ARCH=sparc
@@ -410,18 +422,21 @@
# 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],
--- a/common/autoconf/source-dirs.m4 Fri Sep 20 17:11:32 2013 -0700
+++ b/common/autoconf/source-dirs.m4 Fri Sep 20 19:15:59 2013 -0700
@@ -101,6 +101,10 @@
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 @@
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-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 @@
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])
--- a/common/autoconf/spec.gmk.in Fri Sep 20 17:11:32 2013 -0700
+++ b/common/autoconf/spec.gmk.in Fri Sep 20 19:15:59 2013 -0700
@@ -291,10 +291,6 @@
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 @@
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@
--- a/common/autoconf/toolchain.m4 Fri Sep 20 17:11:32 2013 -0700
+++ b/common/autoconf/toolchain.m4 Fri Sep 20 19:15:59 2013 -0700
@@ -176,7 +176,9 @@
[
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)
--- a/common/autoconf/toolchain_windows.m4 Fri Sep 20 17:11:32 2013 -0700
+++ b/common/autoconf/toolchain_windows.m4 Fri Sep 20 19:15:59 2013 -0700
@@ -277,61 +277,3 @@
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"
-])
--- a/common/bin/hgforest.sh Fri Sep 20 17:11:32 2013 -0700
+++ b/common/bin/hgforest.sh Fri Sep 20 19:15:59 2013 -0700
@@ -47,7 +47,7 @@
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
--- a/corba/.hgtags Fri Sep 20 17:11:32 2013 -0700
+++ b/corba/.hgtags Fri Sep 20 19:15:59 2013 -0700
@@ -227,3 +227,5 @@
49c4a777fdfd648d4c3fffc940fdb97a23108ca8 jdk8-b103
d411c60a8c2fe8fdc572af907775e90f7eefd513 jdk8-b104
4e38de7c767e34104fa147b5b346d9fe6b731279 jdk8-b105
+2e3a056c84a71eba78945c18b05397858ffd7ad0 jdk8-b106
+23fc34133152692b725db4bd617b4c8dfd6ccb05 jdk8-b107
--- a/corba/src/share/classes/com/sun/corba/se/impl/transport/DefaultSocketFactoryImpl.java Fri Sep 20 17:11:32 2013 -0700
+++ b/corba/src/share/classes/com/sun/corba/se/impl/transport/DefaultSocketFactoryImpl.java Fri Sep 20 19:15:59 2013 -0700
@@ -32,6 +32,7 @@
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 @@
implements ORBSocketFactory
{
private ORB orb;
+ private static final boolean keepAlive;
+
+ static {
+ keepAlive = java.security.AccessController.doPrivileged(
+ new PrivilegedAction<Boolean>() {
+ @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 @@
// Disable Nagle's algorithm (i.e., always send immediately).
socket.setTcpNoDelay(true);
+ if (keepAlive)
+ socket.setKeepAlive(true);
+
return socket;
}
@@ -95,6 +115,8 @@
{
// Disable Nagle's algorithm (i.e., always send immediately).
socket.setTcpNoDelay(true);
+ if (keepAlive)
+ socket.setKeepAlive(true);
}
}
--- a/hotspot/.hgtags Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/.hgtags Fri Sep 20 19:15:59 2013 -0700
@@ -373,3 +373,7 @@
c1604d5885a6f2adc0bcea2fa142a8f6bafad2f0 hs25-b47
acac3bde66b2c22791c257a8d99611d6d08c6713 jdk8-b105
18b4798adbc42c6fa16f5ecb7d5cd3ca130754bf hs25-b48
+aed585cafc0d9655726af6d1e1081d1c94cb3b5c jdk8-b106
+50794d8ac11c9579b41dec4de23b808fef9f34a1 hs25-b49
+5b7f90aab3ad25a25b75b7b2bb18d5ae23d8231c jdk8-b107
+a09fe9d1e016c285307507a5793bc4fa6215e9c9 hs25-b50
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Fri Sep 20 19:15:59 2013 -0700
@@ -354,9 +354,16 @@
public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; }
public long getVtableLen() { return vtableLen.getValue(this); }
public long getItableLen() { return itableLen.getValue(this); }
- public Symbol getGenericSignature() { return getConstants().getSymbolAt(genericSignatureIndex.getValue(this)); }
public long majorVersion() { return majorVersion.getValue(this); }
public long minorVersion() { return minorVersion.getValue(this); }
+ public Symbol getGenericSignature() {
+ long index = genericSignatureIndex.getValue(this);
+ if (index != 0) {
+ return getConstants().getSymbolAt(index);
+ } else {
+ return null;
+ }
+ }
// "size helper" == instance size in words
public long getSizeHelper() {
--- a/hotspot/make/bsd/makefiles/gcc.make Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/make/bsd/makefiles/gcc.make Fri Sep 20 19:15:59 2013 -0700
@@ -129,16 +129,21 @@
# We only use precompiled headers for the JVM build
CFLAGS += $(VM_PCH_FLAG)
-
- # There are some files which don't like precompiled headers
- # The following files are build with 'OPT_CFLAGS/NOOPT' (-O0) in the opt build.
- # But Clang doesn't support a precompiled header which was compiled with -O3
- # to be used in a compilation unit which uses '-O0'. We could also prepare an
- # extra '-O0' PCH file for the opt build and use it here, but it's probably
- # not worth the effort as long as only two files need this special handling.
+
+ # The following files are compiled at various optimization
+ # levels due to optimization issues encountered at the
+ # 'OPT_CFLAGS_DEFAULT' level. The Clang compiler issues a compile
+ # time error if there is an optimization level specification
+ # skew between the PCH file and the C++ file. Especially if the
+ # PCH file is compiled at a higher optimization level than
+ # the C++ file. One solution might be to prepare extra optimization
+ # level specific PCH files for the opt build and use them here, but
+ # it's probably not worth the effort as long as only a few files
+ # need this special handling.
PCH_FLAG/loopTransform.o = $(PCH_FLAG/NO_PCH)
PCH_FLAG/sharedRuntimeTrig.o = $(PCH_FLAG/NO_PCH)
PCH_FLAG/sharedRuntimeTrans.o = $(PCH_FLAG/NO_PCH)
+ PCH_FLAG/unsafe.o = $(PCH_FLAG/NO_PCH)
endif
else # ($(USE_CLANG), true)
@@ -306,6 +311,7 @@
ifeq ($(USE_CLANG), true)
ifeq ($(shell expr $(CC_VER_MAJOR) = 4 \& $(CC_VER_MINOR) = 2), 1)
OPT_CFLAGS/loopTransform.o += $(OPT_CFLAGS/NOOPT)
+ OPT_CFLAGS/unsafe.o += -O1
endif
else
# 6835796. Problem in GCC 4.3.0 with mulnode.o optimized compilation.
--- a/hotspot/make/hotspot_version Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/make/hotspot_version Fri Sep 20 19:15:59 2013 -0700
@@ -35,7 +35,7 @@
HS_MAJOR_VER=25
HS_MINOR_VER=0
-HS_BUILD_NUMBER=48
+HS_BUILD_NUMBER=50
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
--- a/hotspot/make/windows/create.bat Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/make/windows/create.bat Fri Sep 20 19:15:59 2013 -0700
@@ -82,6 +82,7 @@
echo **************************************************************
set ProjectFile=%HotSpotBuildSpace%\jvm.vcproj
+echo MSC_VER = "%MSC_VER%"
if "%MSC_VER%" == "1200" (
set ProjectFile=%HotSpotBuildSpace%\jvm.dsp
echo Will generate VC6 project {unsupported}
@@ -96,11 +97,17 @@
echo Will generate VC10 {Visual Studio 2010}
set ProjectFile=%HotSpotBuildSpace%\jvm.vcxproj
) else (
+if "%MSC_VER%" == "1700" (
+echo Will generate VC10 {compatible with Visual Studio 2012}
+echo After opening in VS 2012, click "Update" when prompted.
+set ProjectFile=%HotSpotBuildSpace%\jvm.vcxproj
+) else (
echo Will generate VC7 project {Visual Studio 2003 .NET}
)
)
)
)
+)
echo %ProjectFile%
echo **************************************************************
--- a/hotspot/make/windows/makefiles/rules.make Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/make/windows/makefiles/rules.make Fri Sep 20 19:15:59 2013 -0700
@@ -69,6 +69,13 @@
VcVersion=VC10
ProjectFile=jvm.vcxproj
+!elseif "$(MSC_VER)" == "1700"
+# This is VS2012, but it loads VS10 projects just fine (and will
+# upgrade them automatically to VS2012 format).
+
+VcVersion=VC10
+ProjectFile=jvm.vcxproj
+
!else
VcVersion=VC7
--- a/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -307,7 +307,7 @@
assert(a_byte == *start++, "should be the same code");
}
#endif
- } else if (_id == load_mirror_id) {
+ } else if (_id == load_mirror_id || _id == load_appendix_id) {
// produce a copy of the load mirror instruction for use by the being initialized case
#ifdef ASSERT
address start = __ pc();
@@ -384,6 +384,7 @@
case access_field_id: target = Runtime1::entry_for(Runtime1::access_field_patching_id); break;
case load_klass_id: target = Runtime1::entry_for(Runtime1::load_klass_patching_id); reloc_type = relocInfo::metadata_type; break;
case load_mirror_id: target = Runtime1::entry_for(Runtime1::load_mirror_patching_id); reloc_type = relocInfo::oop_type; break;
+ case load_appendix_id: target = Runtime1::entry_for(Runtime1::load_appendix_patching_id); reloc_type = relocInfo::oop_type; break;
default: ShouldNotReachHere();
}
__ bind(call_patch);
@@ -397,7 +398,7 @@
ce->add_call_info_here(_info);
__ br(Assembler::always, false, Assembler::pt, _patch_site_entry);
__ delayed()->nop();
- if (_id == load_klass_id || _id == load_mirror_id) {
+ if (_id == load_klass_id || _id == load_mirror_id || _id == load_appendix_id) {
CodeSection* cs = __ code_section();
address pc = (address)_pc_start;
RelocIterator iter(cs, pc, pc + 1);
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -520,7 +520,7 @@
void LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo *info) {
// Allocate a new index in table to hold the object once it's been patched
int oop_index = __ oop_recorder()->allocate_oop_index(NULL);
- PatchingStub* patch = new PatchingStub(_masm, PatchingStub::load_mirror_id, oop_index);
+ PatchingStub* patch = new PatchingStub(_masm, patching_id(info), oop_index);
AddressLiteral addrlit(NULL, oop_Relocation::spec(oop_index));
assert(addrlit.rspec().type() == relocInfo::oop_type, "must be an oop reloc");
--- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -804,6 +804,12 @@
}
break;
+ case load_appendix_patching_id:
+ { __ set_info("load_appendix_patching", dont_gc_arguments);
+ oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_appendix_patching));
+ }
+ break;
+
case dtrace_object_alloc_id:
{ // O0: object
__ set_info("dtrace_object_alloc", dont_gc_arguments);
--- a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -57,6 +57,7 @@
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.
--- a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -402,6 +402,7 @@
case access_field_id: target = Runtime1::entry_for(Runtime1::access_field_patching_id); break;
case load_klass_id: target = Runtime1::entry_for(Runtime1::load_klass_patching_id); reloc_type = relocInfo::metadata_type; break;
case load_mirror_id: target = Runtime1::entry_for(Runtime1::load_mirror_patching_id); reloc_type = relocInfo::oop_type; break;
+ case load_appendix_id: target = Runtime1::entry_for(Runtime1::load_appendix_patching_id); reloc_type = relocInfo::oop_type; break;
default: ShouldNotReachHere();
}
__ bind(call_patch);
@@ -419,7 +420,7 @@
for (int j = __ offset() ; j < jmp_off + 5 ; j++ ) {
__ nop();
}
- if (_id == load_klass_id || _id == load_mirror_id) {
+ if (_id == load_klass_id || _id == load_mirror_id || _id == load_appendix_id) {
CodeSection* cs = __ code_section();
RelocIterator iter(cs, (address)_pc_start, (address)(_pc_start + 1));
relocInfo::change_reloc_info_for_address(&iter, (address) _pc_start, reloc_type, relocInfo::none);
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -362,7 +362,7 @@
void LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo* info) {
jobject o = NULL;
- PatchingStub* patch = new PatchingStub(_masm, PatchingStub::load_mirror_id);
+ PatchingStub* patch = new PatchingStub(_masm, patching_id(info));
__ movoop(reg, o);
patching_epilog(patch, lir_patch_normal, reg, info);
}
--- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -1499,6 +1499,13 @@
}
break;
+ case load_appendix_patching_id:
+ { StubFrame f(sasm, "load_appendix_patching", dont_gc_arguments);
+ // we should set up register map
+ oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_appendix_patching));
+ }
+ break;
+
case dtrace_object_alloc_id:
{ // rax,: object
StubFrame f(sasm, "dtrace_object_alloc", dont_gc_arguments);
--- a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -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, 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);
--- a/hotspot/src/os/linux/vm/os_linux.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -2767,7 +2767,19 @@
Linux::numa_interleave_memory(addr, bytes);
}
+// Define for numa_set_bind_policy(int). Setting the argument to 0 will set the
+// bind policy to MPOL_PREFERRED for the current thread.
+#define USE_MPOL_PREFERRED 0
+
void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) {
+ // To make NUMA and large pages more robust when both enabled, we need to ease
+ // the requirements on where the memory should be allocated. MPOL_BIND is the
+ // default policy and it will force memory to be allocated on the specified
+ // node. Changing this to MPOL_PREFERRED will prefer to allocate the memory on
+ // the specified node, but will not force it. Using this policy will prevent
+ // getting SIGBUS when trying to allocate large pages on NUMA nodes with no
+ // free large pages.
+ Linux::numa_set_bind_policy(USE_MPOL_PREFERRED);
Linux::numa_tonode_memory(addr, bytes, lgrp_hint);
}
@@ -2869,6 +2881,8 @@
libnuma_dlsym(handle, "numa_tonode_memory")));
set_numa_interleave_memory(CAST_TO_FN_PTR(numa_interleave_memory_func_t,
libnuma_dlsym(handle, "numa_interleave_memory")));
+ set_numa_set_bind_policy(CAST_TO_FN_PTR(numa_set_bind_policy_func_t,
+ libnuma_dlsym(handle, "numa_set_bind_policy")));
if (numa_available() != -1) {
@@ -2935,6 +2949,7 @@
os::Linux::numa_available_func_t os::Linux::_numa_available;
os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory;
os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory;
+os::Linux::numa_set_bind_policy_func_t os::Linux::_numa_set_bind_policy;
unsigned long* os::Linux::_numa_all_nodes;
bool os::pd_uncommit_memory(char* addr, size_t size) {
@@ -2943,6 +2958,53 @@
return res != (uintptr_t) MAP_FAILED;
}
+static
+address get_stack_commited_bottom(address bottom, size_t size) {
+ address nbot = bottom;
+ address ntop = bottom + size;
+
+ size_t page_sz = os::vm_page_size();
+ unsigned pages = size / page_sz;
+
+ unsigned char vec[1];
+ unsigned imin = 1, imax = pages + 1, imid;
+ int mincore_return_value;
+
+ while (imin < imax) {
+ imid = (imax + imin) / 2;
+ nbot = ntop - (imid * page_sz);
+
+ // Use a trick with mincore to check whether the page is mapped or not.
+ // mincore sets vec to 1 if page resides in memory and to 0 if page
+ // is swapped output but if page we are asking for is unmapped
+ // it returns -1,ENOMEM
+ mincore_return_value = mincore(nbot, page_sz, vec);
+
+ if (mincore_return_value == -1) {
+ // Page is not mapped go up
+ // to find first mapped page
+ if (errno != EAGAIN) {
+ assert(errno == ENOMEM, "Unexpected mincore errno");
+ imax = imid;
+ }
+ } else {
+ // Page is mapped go down
+ // to find first not mapped page
+ imin = imid + 1;
+ }
+ }
+
+ nbot = nbot + page_sz;
+
+ // Adjust stack bottom one page up if last checked page is not mapped
+ if (mincore_return_value == -1) {
+ nbot = nbot + page_sz;
+ }
+
+ return nbot;
+}
+
+
// Linux uses a growable mapping for the stack, and if the mapping for
// the stack guard pages is not removed when we detach a thread the
// stack cannot grow beyond the pages where the stack guard was
@@ -2957,59 +3019,37 @@
// So, we need to know the extent of the stack mapping when
// create_stack_guard_pages() is called.
-// Find the bounds of the stack mapping. Return true for success.
-//
// We only need this for stacks that are growable: at the time of
// writing thread stacks don't use growable mappings (i.e. those
// creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this
// only applies to the main thread.
-static
-bool get_stack_bounds(uintptr_t *bottom, uintptr_t *top) {
-
- char buf[128];
- int fd, sz;
-
- if ((fd = ::open("/proc/self/maps", O_RDONLY)) < 0) {
- return false;
- }
-
- const char kw[] = "[stack]";
- const int kwlen = sizeof(kw)-1;
-
- // Address part of /proc/self/maps couldn't be more than 128 bytes
- while ((sz = os::get_line_chars(fd, buf, sizeof(buf))) > 0) {
- if (sz > kwlen && ::memcmp(buf+sz-kwlen, kw, kwlen) == 0) {
- // Extract addresses
- if (sscanf(buf, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) {
- uintptr_t sp = (uintptr_t) __builtin_frame_address(0);
- if (sp >= *bottom && sp <= *top) {
- ::close(fd);
- return true;
- }
- }
- }
- }
-
- ::close(fd);
- return false;
-}
-
-
// If the (growable) stack mapping already extends beyond the point
// where we're going to put our guard pages, truncate the mapping at
// that point by munmap()ping it. This ensures that when we later
// munmap() the guard pages we don't leave a hole in the stack
-// mapping. This only affects the main/initial thread, but guard
-// against future OS changes
+// mapping. This only affects the main/initial thread
+
bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
- uintptr_t stack_extent, stack_base;
- bool chk_bounds = NOT_DEBUG(os::Linux::is_initial_thread()) DEBUG_ONLY(true);
- if (chk_bounds && get_stack_bounds(&stack_extent, &stack_base)) {
- assert(os::Linux::is_initial_thread(),
- "growable stack in non-initial thread");
- if (stack_extent < (uintptr_t)addr)
- ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent);
+
+ if (os::Linux::is_initial_thread()) {
+ // As we manually grow stack up to bottom inside create_attached_thread(),
+ // it's likely that os::Linux::initial_thread_stack_bottom is mapped and
+ // we don't need to do anything special.
+ // Check it first, before calling heavy function.
+ uintptr_t stack_extent = (uintptr_t) os::Linux::initial_thread_stack_bottom();
+ unsigned char vec[1];
+
+ if (mincore((address)stack_extent, os::vm_page_size(), vec) == -1) {
+ // Fallback to slow path on all errors, including EAGAIN
+ stack_extent = (uintptr_t) get_stack_commited_bottom(
+ os::Linux::initial_thread_stack_bottom(),
+ (size_t)addr - stack_extent);
+ }
+
+ if (stack_extent < (uintptr_t)addr) {
+ ::munmap((void*)stack_extent, (uintptr_t)(addr - stack_extent));
+ }
}
return os::commit_memory(addr, size, !ExecMem);
@@ -3018,13 +3058,13 @@
// If this is a growable mapping, remove the guard pages entirely by
// munmap()ping them. If not, just call uncommit_memory(). This only
// affects the main/initial thread, but guard against future OS changes
+// It's safe to always unmap guard pages for initial thread because we
+// always place it right after end of the mapped region
+
bool os::remove_stack_guard_pages(char* addr, size_t size) {
uintptr_t stack_extent, stack_base;
- bool chk_bounds = NOT_DEBUG(os::Linux::is_initial_thread()) DEBUG_ONLY(true);
- if (chk_bounds && get_stack_bounds(&stack_extent, &stack_base)) {
- assert(os::Linux::is_initial_thread(),
- "growable stack in non-initial thread");
-
+
+ if (os::Linux::is_initial_thread()) {
return ::munmap(addr, size) == 0;
}
--- a/hotspot/src/os/linux/vm/os_linux.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -235,6 +235,7 @@
typedef int (*numa_available_func_t)(void);
typedef int (*numa_tonode_memory_func_t)(void *start, size_t size, int node);
typedef void (*numa_interleave_memory_func_t)(void *start, size_t size, unsigned long *nodemask);
+ typedef void (*numa_set_bind_policy_func_t)(int policy);
static sched_getcpu_func_t _sched_getcpu;
static numa_node_to_cpus_func_t _numa_node_to_cpus;
@@ -242,6 +243,7 @@
static numa_available_func_t _numa_available;
static numa_tonode_memory_func_t _numa_tonode_memory;
static numa_interleave_memory_func_t _numa_interleave_memory;
+ static numa_set_bind_policy_func_t _numa_set_bind_policy;
static unsigned long* _numa_all_nodes;
static void set_sched_getcpu(sched_getcpu_func_t func) { _sched_getcpu = func; }
@@ -250,6 +252,7 @@
static void set_numa_available(numa_available_func_t func) { _numa_available = func; }
static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; }
static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; }
+ static void set_numa_set_bind_policy(numa_set_bind_policy_func_t func) { _numa_set_bind_policy = func; }
static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; }
static int sched_getcpu_syscall(void);
public:
@@ -267,6 +270,11 @@
_numa_interleave_memory(start, size, _numa_all_nodes);
}
}
+ static void numa_set_bind_policy(int policy) {
+ if (_numa_set_bind_policy != NULL) {
+ _numa_set_bind_policy(policy);
+ }
+ }
static int get_node_by_cpu(int cpu_id);
};
--- a/hotspot/src/os/posix/vm/os_posix.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/os/posix/vm/os_posix.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -30,6 +30,8 @@
#include <unistd.h>
#include <sys/resource.h>
#include <sys/utsname.h>
+#include <pthread.h>
+#include <signal.h>
// Check core dump limit and report possible place where core can be found
@@ -320,11 +322,17 @@
* The callback is supposed to provide the method that should be protected.
*/
bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) {
+ sigset_t saved_sig_mask;
+
assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread");
assert(!WatcherThread::watcher_thread()->has_crash_protection(),
"crash_protection already set?");
- if (sigsetjmp(_jmpbuf, 1) == 0) {
+ // we cannot rely on sigsetjmp/siglongjmp to save/restore the signal mask
+ // since on at least some systems (OS X) siglongjmp will restore the mask
+ // for the process, not the thread
+ pthread_sigmask(0, NULL, &saved_sig_mask);
+ if (sigsetjmp(_jmpbuf, 0) == 0) {
// make sure we can see in the signal handler that we have crash protection
// installed
WatcherThread::watcher_thread()->set_crash_protection(this);
@@ -334,6 +342,7 @@
return true;
}
// this happens when we siglongjmp() back
+ pthread_sigmask(SIG_SETMASK, &saved_sig_mask, NULL);
WatcherThread::watcher_thread()->set_crash_protection(NULL);
return false;
}
--- a/hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -44,6 +44,6 @@
define_pd_global(intx, CompilerThreadStackSize, 0);
// Used on 64 bit platforms for UseCompressedOops base address
-define_pd_global(uintx,HeapBaseMinAddress, 256*M);
+define_pd_global(uintx,HeapBaseMinAddress, 2*G);
#endif // OS_CPU_SOLARIS_X86_VM_GLOBALS_SOLARIS_X86_HPP
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java Fri Sep 20 19:15:59 2013 -0700
@@ -106,10 +106,12 @@
" (" + getMethod().getBytes() + " bytes) " + getReason());
}
}
+ stream.printf(" (end time: %6.4f", getTimeStamp());
if (getEndNodes() > 0) {
- stream.printf(" (end time: %6.4f nodes: %d live: %d)", getTimeStamp(), getEndNodes(), getEndLiveNodes());
+ stream.printf(" nodes: %d live: %d", getEndNodes(), getEndLiveNodes());
}
- stream.println("");
+ stream.println(")");
+
if (getReceiver() != null) {
emit(stream, indent + 4);
// stream.println("type profile " + method.holder + " -> " + receiver + " (" +
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java Fri Sep 20 19:15:59 2013 -0700
@@ -207,7 +207,12 @@
}
String search(Attributes attr, String name) {
- return search(attr, name, null);
+ String result = attr.getValue(name);
+ if (result != null) {
+ return result;
+ } else {
+ throw new InternalError("can't find " + name);
+ }
}
String search(Attributes attr, String name, String defaultValue) {
@@ -215,13 +220,7 @@
if (result != null) {
return result;
}
- if (defaultValue != null) {
- return defaultValue;
- }
- for (int i = 0; i < attr.getLength(); i++) {
- System.out.println(attr.getQName(i) + " " + attr.getValue(attr.getQName(i)));
- }
- throw new InternalError("can't find " + name);
+ return defaultValue;
}
int indent = 0;
@@ -268,17 +267,18 @@
Phase p = new Phase(search(atts, "name"),
Double.parseDouble(search(atts, "stamp")),
Integer.parseInt(search(atts, "nodes", "0")),
- Integer.parseInt(search(atts, "live")));
+ Integer.parseInt(search(atts, "live", "0")));
phaseStack.push(p);
} else if (qname.equals("phase_done")) {
Phase p = phaseStack.pop();
- if (! p.getId().equals(search(atts, "name"))) {
+ String phaseName = search(atts, "name", null);
+ if (phaseName != null && !p.getId().equals(phaseName)) {
System.out.println("phase: " + p.getId());
throw new InternalError("phase name mismatch");
}
p.setEnd(Double.parseDouble(search(atts, "stamp")));
p.setEndNodes(Integer.parseInt(search(atts, "nodes", "0")));
- p.setEndLiveNodes(Integer.parseInt(search(atts, "live")));
+ p.setEndLiveNodes(Integer.parseInt(search(atts, "live", "0")));
compile.getPhases().add(p);
} else if (qname.equals("task")) {
compile = new Compilation(Integer.parseInt(search(atts, "compile_id", "-1")));
@@ -413,8 +413,8 @@
}
} else if (qname.equals("parse_done")) {
CallSite call = scopes.pop();
- call.setEndNodes(Integer.parseInt(search(atts, "nodes", "1")));
- call.setEndLiveNodes(Integer.parseInt(search(atts, "live", "1")));
+ call.setEndNodes(Integer.parseInt(search(atts, "nodes", "0")));
+ call.setEndLiveNodes(Integer.parseInt(search(atts, "live", "0")));
call.setTimeStamp(Double.parseDouble(search(atts, "stamp")));
scopes.push(call);
}
--- a/hotspot/src/share/vm/adlc/arena.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/adlc/arena.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -24,7 +24,7 @@
#include "adlc.hpp"
-void* Chunk::operator new(size_t requested_size, size_t length) {
+void* Chunk::operator new(size_t requested_size, size_t length) throw() {
return CHeapObj::operator new(requested_size + length);
}
@@ -163,7 +163,7 @@
//-----------------------------------------------------------------------------
// CHeapObj
-void* CHeapObj::operator new(size_t size){
+void* CHeapObj::operator new(size_t size) throw() {
return (void *) malloc(size);
}
--- a/hotspot/src/share/vm/adlc/arena.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/adlc/arena.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -42,7 +42,7 @@
class CHeapObj {
public:
- void* operator new(size_t size);
+ void* operator new(size_t size) throw();
void operator delete(void* p);
void* new_array(size_t size);
};
@@ -53,7 +53,7 @@
class ValueObj {
public:
- void* operator new(size_t size);
+ void* operator new(size_t size) throw();
void operator delete(void* p);
};
@@ -61,7 +61,7 @@
class AllStatic {
public:
- void* operator new(size_t size);
+ void* operator new(size_t size) throw();
void operator delete(void* p);
};
@@ -70,7 +70,7 @@
// Linked list of raw memory chunks
class Chunk: public CHeapObj {
public:
- void* operator new(size_t size, size_t length);
+ void* operator new(size_t size, size_t length) throw();
void operator delete(void* p, size_t length);
Chunk(size_t length);
--- a/hotspot/src/share/vm/adlc/main.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/adlc/main.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -485,7 +485,7 @@
// VS2005 has its own definition, identical to this one.
#if !defined(_WIN32) || defined(_WIN64) || _MSC_VER < 1400
-void *operator new( size_t size, int, const char *, int ) {
+void *operator new( size_t size, int, const char *, int ) throw() {
return ::operator new( size );
}
#endif
--- a/hotspot/src/share/vm/adlc/output_c.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/adlc/output_c.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -1095,7 +1095,7 @@
fprintf(fp, " // Identify previous instruction if inside this block\n");
fprintf(fp, " if( ");
print_block_index(fp, inst_position);
- fprintf(fp, " > 0 ) {\n Node *n = block->_nodes.at(");
+ fprintf(fp, " > 0 ) {\n Node *n = block->get_node(");
print_block_index(fp, inst_position);
fprintf(fp, ");\n inst%d = (n->is_Mach()) ? ", inst_position);
fprintf(fp, "n->as_Mach() : NULL;\n }\n");
--- a/hotspot/src/share/vm/asm/codeBuffer.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/asm/codeBuffer.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -296,8 +296,8 @@
// CodeBuffers must be allocated on the stack except for a single
// special case during expansion which is handled internally. This
// is done to guarantee proper cleanup of resources.
- void* operator new(size_t size) { return ResourceObj::operator new(size); }
- void operator delete(void* p) { ShouldNotCallThis(); }
+ void* operator new(size_t size) throw() { return ResourceObj::operator new(size); }
+ void operator delete(void* p) { ShouldNotCallThis(); }
public:
typedef int csize_t; // code size type; would be size_t except for history
--- a/hotspot/src/share/vm/c1/c1_CodeStubs.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_CodeStubs.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -364,7 +364,8 @@
enum PatchID {
access_field_id,
load_klass_id,
- load_mirror_id
+ load_mirror_id,
+ load_appendix_id
};
enum constants {
patch_info_size = 3
@@ -417,7 +418,7 @@
}
NativeMovRegMem* n_move = nativeMovRegMem_at(pc_start());
n_move->set_offset(field_offset);
- } else if (_id == load_klass_id || _id == load_mirror_id) {
+ } else if (_id == load_klass_id || _id == load_mirror_id || _id == load_appendix_id) {
assert(_obj != noreg, "must have register object for load_klass/load_mirror");
#ifdef ASSERT
// verify that we're pointing at a NativeMovConstReg
--- a/hotspot/src/share/vm/c1/c1_Compilation.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -74,16 +74,19 @@
private:
JavaThread* _thread;
CompileLog* _log;
+ TimerName _timer;
public:
PhaseTraceTime(TimerName timer)
- : TraceTime("", &timers[timer], CITime || CITimeEach, Verbose), _log(NULL) {
+ : TraceTime("", &timers[timer], CITime || CITimeEach, Verbose),
+ _log(NULL), _timer(timer)
+ {
if (Compilation::current() != NULL) {
_log = Compilation::current()->log();
}
if (_log != NULL) {
- _log->begin_head("phase name='%s'", timer_name[timer]);
+ _log->begin_head("phase name='%s'", timer_name[_timer]);
_log->stamp();
_log->end_head();
}
@@ -91,7 +94,7 @@
~PhaseTraceTime() {
if (_log != NULL)
- _log->done("phase");
+ _log->done("phase name='%s'", timer_name[_timer]);
}
};
--- a/hotspot/src/share/vm/c1/c1_Compilation.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_Compilation.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -279,8 +279,8 @@
// Base class for objects allocated by the compiler in the compilation arena
class CompilationResourceObj ALLOCATION_SUPER_CLASS_SPEC {
public:
- void* operator new(size_t size) { return Compilation::current()->arena()->Amalloc(size); }
- void* operator new(size_t size, Arena* arena) {
+ void* operator new(size_t size) throw() { return Compilation::current()->arena()->Amalloc(size); }
+ void* operator new(size_t size, Arena* arena) throw() {
return arena->Amalloc(size);
}
void operator delete(void* p) {} // nothing to do
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -1583,7 +1583,7 @@
ObjectType* obj_type = obj->type()->as_ObjectType();
if (obj_type->is_constant() && !PatchALot) {
ciObject* const_oop = obj_type->constant_value();
- if (!const_oop->is_null_object()) {
+ if (!const_oop->is_null_object() && const_oop->is_loaded()) {
if (field->is_constant()) {
ciConstant field_val = field->constant_value_of(const_oop);
BasicType field_type = field_val.basic_type();
@@ -1667,9 +1667,8 @@
const Bytecodes::Code bc_raw = stream()->cur_bc_raw();
assert(declared_signature != NULL, "cannot be null");
- // FIXME bail out for now
- if (Bytecodes::has_optional_appendix(bc_raw) && !will_link) {
- BAILOUT("unlinked call site (FIXME needs patching or recompile support)");
+ if (!C1PatchInvokeDynamic && Bytecodes::has_optional_appendix(bc_raw) && !will_link) {
+ BAILOUT("unlinked call site (C1PatchInvokeDynamic is off)");
}
// we have to make sure the argument size (incl. the receiver)
@@ -1713,10 +1712,23 @@
code = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokespecial;
break;
}
+ } else {
+ if (bc_raw == Bytecodes::_invokehandle) {
+ assert(!will_link, "should come here only for unlinked call");
+ code = Bytecodes::_invokespecial;
+ }
}
// Push appendix argument (MethodType, CallSite, etc.), if one.
- if (stream()->has_appendix()) {
+ bool patch_for_appendix = false;
+ int patching_appendix_arg = 0;
+ if (C1PatchInvokeDynamic &&
+ (Bytecodes::has_optional_appendix(bc_raw) && (!will_link || PatchALot))) {
+ Value arg = append(new Constant(new ObjectConstant(compilation()->env()->unloaded_ciinstance()), copy_state_before()));
+ apush(arg);
+ patch_for_appendix = true;
+ patching_appendix_arg = (will_link && stream()->has_appendix()) ? 0 : 1;
+ } else if (stream()->has_appendix()) {
ciObject* appendix = stream()->get_appendix();
Value arg = append(new Constant(new ObjectConstant(appendix)));
apush(arg);
@@ -1732,7 +1744,8 @@
if (UseCHA && DeoptC1 && klass->is_loaded() && target->is_loaded() &&
!(// %%% FIXME: Are both of these relevant?
target->is_method_handle_intrinsic() ||
- target->is_compiled_lambda_form())) {
+ target->is_compiled_lambda_form()) &&
+ !patch_for_appendix) {
Value receiver = NULL;
ciInstanceKlass* receiver_klass = NULL;
bool type_is_exact = false;
@@ -1850,7 +1863,8 @@
// check if we could do inlining
if (!PatchALot && Inline && klass->is_loaded() &&
(klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized())
- && target->is_loaded()) {
+ && target->is_loaded()
+ && !patch_for_appendix) {
// callee is known => check if we have static binding
assert(target->is_loaded(), "callee must be known");
if (code == Bytecodes::_invokestatic ||
@@ -1901,7 +1915,7 @@
code == Bytecodes::_invokespecial ||
code == Bytecodes::_invokevirtual ||
code == Bytecodes::_invokeinterface;
- Values* args = state()->pop_arguments(target->arg_size_no_receiver());
+ Values* args = state()->pop_arguments(target->arg_size_no_receiver() + patching_appendix_arg);
Value recv = has_receiver ? apop() : NULL;
int vtable_index = Method::invalid_vtable_index;
--- a/hotspot/src/share/vm/c1/c1_Instruction.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -323,7 +323,7 @@
}
public:
- void* operator new(size_t size) {
+ void* operator new(size_t size) throw() {
Compilation* c = Compilation::current();
void* res = c->arena()->Amalloc(size);
((Instruction*)res)->_id = c->get_next_id();
@@ -1611,7 +1611,7 @@
friend class SuxAndWeightAdjuster;
public:
- void* operator new(size_t size) {
+ void* operator new(size_t size) throw() {
Compilation* c = Compilation::current();
void* res = c->arena()->Amalloc(size);
((BlockBegin*)res)->_id = c->get_next_id();
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIR.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -1211,8 +1211,6 @@
bool is_invokedynamic() const { return code() == lir_dynamic_call; }
bool is_method_handle_invoke() const {
return
- is_invokedynamic() // An invokedynamic is always a MethodHandle call site.
- ||
method()->is_compiled_lambda_form() // Java-generated adapter
||
method()->is_method_handle_intrinsic(); // JVM-generated MH intrinsic
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -93,12 +93,23 @@
default:
ShouldNotReachHere();
}
+ } else if (patch->id() == PatchingStub::load_appendix_id) {
+ Bytecodes::Code bc_raw = info->scope()->method()->raw_code_at_bci(info->stack()->bci());
+ assert(Bytecodes::has_optional_appendix(bc_raw), "unexpected appendix resolution");
} else {
ShouldNotReachHere();
}
#endif
}
+PatchingStub::PatchID LIR_Assembler::patching_id(CodeEmitInfo* info) {
+ IRScope* scope = info->scope();
+ Bytecodes::Code bc_raw = scope->method()->raw_code_at_bci(info->stack()->bci());
+ if (Bytecodes::has_optional_appendix(bc_raw)) {
+ return PatchingStub::load_appendix_id;
+ }
+ return PatchingStub::load_mirror_id;
+}
//---------------------------------------------------------------
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -119,6 +119,8 @@
void comp_op(LIR_Condition condition, LIR_Opr src, LIR_Opr result, LIR_Op2* op);
+ PatchingStub::PatchID patching_id(CodeEmitInfo* info);
+
public:
LIR_Assembler(Compilation* c);
~LIR_Assembler();
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -819,6 +819,7 @@
KlassHandle init_klass(THREAD, NULL); // klass needed by load_klass_patching code
KlassHandle load_klass(THREAD, NULL); // klass needed by load_klass_patching code
Handle mirror(THREAD, NULL); // oop needed by load_mirror_patching code
+ Handle appendix(THREAD, NULL); // oop needed by appendix_patching code
bool load_klass_or_mirror_patch_id =
(stub_id == Runtime1::load_klass_patching_id || stub_id == Runtime1::load_mirror_patching_id);
@@ -888,10 +889,32 @@
mirror = Handle(THREAD, m);
}
break;
- default: Unimplemented();
+ default: fatal("unexpected bytecode for load_klass_or_mirror_patch_id");
}
// convert to handle
load_klass = KlassHandle(THREAD, k);
+ } else if (stub_id == load_appendix_patching_id) {
+ Bytecode_invoke bytecode(caller_method, bci);
+ Bytecodes::Code bc = bytecode.invoke_code();
+
+ CallInfo info;
+ constantPoolHandle pool(thread, caller_method->constants());
+ int index = bytecode.index();
+ LinkResolver::resolve_invoke(info, Handle(), pool, index, bc, CHECK);
+ appendix = info.resolved_appendix();
+ switch (bc) {
+ case Bytecodes::_invokehandle: {
+ int cache_index = ConstantPool::decode_cpcache_index(index, true);
+ assert(cache_index >= 0 && cache_index < pool->cache()->length(), "unexpected cache index");
+ pool->cache()->entry_at(cache_index)->set_method_handle(pool, info);
+ break;
+ }
+ case Bytecodes::_invokedynamic: {
+ pool->invokedynamic_cp_cache_entry_at(index)->set_dynamic_call(pool, info);
+ break;
+ }
+ default: fatal("unexpected bytecode for load_appendix_patching_id");
+ }
} else {
ShouldNotReachHere();
}
@@ -992,8 +1015,8 @@
n_copy->data() == (intptr_t)Universe::non_oop_word(),
"illegal init value");
if (stub_id == Runtime1::load_klass_patching_id) {
- assert(load_klass() != NULL, "klass not set");
- n_copy->set_data((intx) (load_klass()));
+ assert(load_klass() != NULL, "klass not set");
+ n_copy->set_data((intx) (load_klass()));
} else {
assert(mirror() != NULL, "klass not set");
n_copy->set_data((intx) (mirror()));
@@ -1002,43 +1025,55 @@
if (TracePatching) {
Disassembler::decode(copy_buff, copy_buff + *byte_count, tty);
}
+ }
+ } else if (stub_id == Runtime1::load_appendix_patching_id) {
+ NativeMovConstReg* n_copy = nativeMovConstReg_at(copy_buff);
+ assert(n_copy->data() == 0 ||
+ n_copy->data() == (intptr_t)Universe::non_oop_word(),
+ "illegal init value");
+ n_copy->set_data((intx) (appendix()));
-#if defined(SPARC) || defined(PPC)
- // Update the location in the nmethod with the proper
- // metadata. When the code was generated, a NULL was stuffed
- // in the metadata table and that table needs to be update to
- // have the right value. On intel the value is kept
- // directly in the instruction instead of in the metadata
- // table, so set_data above effectively updated the value.
- nmethod* nm = CodeCache::find_nmethod(instr_pc);
- assert(nm != NULL, "invalid nmethod_pc");
- RelocIterator mds(nm, copy_buff, copy_buff + 1);
- bool found = false;
- while (mds.next() && !found) {
- if (mds.type() == relocInfo::oop_type) {
- assert(stub_id == Runtime1::load_mirror_patching_id, "wrong stub id");
- oop_Relocation* r = mds.oop_reloc();
- oop* oop_adr = r->oop_addr();
- *oop_adr = mirror();
- r->fix_oop_relocation();
- found = true;
- } else if (mds.type() == relocInfo::metadata_type) {
- assert(stub_id == Runtime1::load_klass_patching_id, "wrong stub id");
- metadata_Relocation* r = mds.metadata_reloc();
- Metadata** metadata_adr = r->metadata_addr();
- *metadata_adr = load_klass();
- r->fix_metadata_relocation();
- found = true;
- }
- }
- assert(found, "the metadata must exist!");
-#endif
-
+ if (TracePatching) {
+ Disassembler::decode(copy_buff, copy_buff + *byte_count, tty);
}
} else {
ShouldNotReachHere();
}
+#if defined(SPARC) || defined(PPC)
+ if (load_klass_or_mirror_patch_id ||
+ stub_id == Runtime1::load_appendix_patching_id) {
+ // Update the location in the nmethod with the proper
+ // metadata. When the code was generated, a NULL was stuffed
+ // in the metadata table and that table needs to be update to
+ // have the right value. On intel the value is kept
+ // directly in the instruction instead of in the metadata
+ // table, so set_data above effectively updated the value.
+ nmethod* nm = CodeCache::find_nmethod(instr_pc);
+ assert(nm != NULL, "invalid nmethod_pc");
+ RelocIterator mds(nm, copy_buff, copy_buff + 1);
+ bool found = false;
+ while (mds.next() && !found) {
+ if (mds.type() == relocInfo::oop_type) {
+ assert(stub_id == Runtime1::load_mirror_patching_id ||
+ stub_id == Runtime1::load_appendix_patching_id, "wrong stub id");
+ oop_Relocation* r = mds.oop_reloc();
+ oop* oop_adr = r->oop_addr();
+ *oop_adr = stub_id == Runtime1::load_mirror_patching_id ? mirror() : appendix();
+ r->fix_oop_relocation();
+ found = true;
+ } else if (mds.type() == relocInfo::metadata_type) {
+ assert(stub_id == Runtime1::load_klass_patching_id, "wrong stub id");
+ metadata_Relocation* r = mds.metadata_reloc();
+ Metadata** metadata_adr = r->metadata_addr();
+ *metadata_adr = load_klass();
+ r->fix_metadata_relocation();
+ found = true;
+ }
+ }
+ assert(found, "the metadata must exist!");
+ }
+#endif
if (do_patch) {
// replace instructions
// first replace the tail, then the call
@@ -1077,7 +1112,8 @@
ICache::invalidate_range(instr_pc, *byte_count);
NativeGeneralJump::replace_mt_safe(instr_pc, copy_buff);
- if (load_klass_or_mirror_patch_id) {
+ if (load_klass_or_mirror_patch_id ||
+ stub_id == Runtime1::load_appendix_patching_id) {
relocInfo::relocType rtype =
(stub_id == Runtime1::load_klass_patching_id) ?
relocInfo::metadata_type :
@@ -1118,7 +1154,8 @@
// If we are patching in a non-perm oop, make sure the nmethod
// is on the right list.
- if (ScavengeRootsInCode && mirror.not_null() && mirror()->is_scavengable()) {
+ if (ScavengeRootsInCode && ((mirror.not_null() && mirror()->is_scavengable()) ||
+ (appendix.not_null() && appendix->is_scavengable()))) {
MutexLockerEx ml_code (CodeCache_lock, Mutex::_no_safepoint_check_flag);
nmethod* nm = CodeCache::find_nmethod(caller_frame.pc());
guarantee(nm != NULL, "only nmethods can contain non-perm oops");
@@ -1179,6 +1216,24 @@
return caller_is_deopted();
}
+int Runtime1::move_appendix_patching(JavaThread* thread) {
+//
+// NOTE: we are still in Java
+//
+ Thread* THREAD = thread;
+ debug_only(NoHandleMark nhm;)
+ {
+ // Enter VM mode
+
+ ResetNoHandleMark rnhm;
+ patch_code(thread, load_appendix_patching_id);
+ }
+ // Back in JAVA, use no oops DON'T safepoint
+
+ // Return true if calling code is deoptimized
+
+ return caller_is_deopted();
+}
//
// Entry point for compiled code. We want to patch a nmethod.
// We don't do a normal VM transition here because we want to
--- a/hotspot/src/share/vm/c1/c1_Runtime1.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -67,6 +67,7 @@
stub(access_field_patching) \
stub(load_klass_patching) \
stub(load_mirror_patching) \
+ stub(load_appendix_patching) \
stub(g1_pre_barrier_slow) \
stub(g1_post_barrier_slow) \
stub(fpu2long_stub) \
@@ -160,6 +161,7 @@
static int access_field_patching(JavaThread* thread);
static int move_klass_patching(JavaThread* thread);
static int move_mirror_patching(JavaThread* thread);
+ static int move_appendix_patching(JavaThread* thread);
static void patch_code(JavaThread* thread, StubID stub_id);
--- a/hotspot/src/share/vm/c1/c1_globals.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_globals.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -25,4 +25,4 @@
#include "precompiled.hpp"
#include "c1/c1_globals.hpp"
-C1_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, MATERIALIZE_NOTPRODUCT_FLAG)
+C1_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG)
--- a/hotspot/src/share/vm/c1/c1_globals.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_globals.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -54,7 +54,7 @@
//
// Defines all global flags used by the client compiler.
//
-#define C1_FLAGS(develop, develop_pd, product, product_pd, notproduct) \
+#define C1_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \
\
/* Printing */ \
notproduct(bool, PrintC1Statistics, false, \
@@ -333,15 +333,19 @@
"Use CHA and exact type results at call sites when updating MDOs")\
\
product(bool, C1UpdateMethodData, trueInTiered, \
- "Update MethodData*s in Tier1-generated code") \
+ "Update MethodData*s in Tier1-generated code") \
\
develop(bool, PrintCFGToFile, false, \
"print control flow graph to a separate file during compilation") \
\
+ diagnostic(bool, C1PatchInvokeDynamic, true, \
+ "Patch invokedynamic appendix not known at compile time") \
+ \
+ \
// Read default values for c1 globals
-C1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_NOTPRODUCT_FLAG)
+C1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
#endif // SHARE_VM_C1_C1_GLOBALS_HPP
--- a/hotspot/src/share/vm/ci/ciArray.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciArray.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
--- a/hotspot/src/share/vm/ci/ciArray.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciArray.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -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 @@
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; }
--- a/hotspot/src/share/vm/ci/ciConstant.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciConstant.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -41,7 +41,6 @@
union {
jint _int;
jlong _long;
- jint _long_half[2];
jfloat _float;
jdouble _double;
ciObject* _object;
@@ -111,6 +110,20 @@
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();
};
--- a/hotspot/src/share/vm/ci/ciEnv.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -1150,6 +1150,10 @@
record_method_not_compilable("out of memory");
}
+ciInstance* ciEnv::unloaded_ciinstance() {
+ GUARDED_VM_ENTRY(return _factory->get_unloaded_object_constant();)
+}
+
void ciEnv::dump_replay_data(outputStream* out) {
VM_ENTRY_MARK;
MutexLocker ml(Compile_lock);
--- a/hotspot/src/share/vm/ci/ciEnv.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciEnv.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -400,6 +400,7 @@
static ciInstanceKlass* unloaded_ciinstance_klass() {
return _unloaded_ciinstance_klass;
}
+ ciInstance* unloaded_ciinstance();
ciKlass* find_system_klass(ciSymbol* klass_name);
// Note: To find a class from its name string, use ciSymbol::make,
--- a/hotspot/src/share/vm/ci/ciField.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciField.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -189,12 +189,14 @@
_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 +229,6 @@
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 +274,12 @@
}
}
}
+ 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;
}
@@ -373,8 +380,11 @@
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=");
--- a/hotspot/src/share/vm/ci/ciField.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciField.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -139,7 +139,10 @@
// 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 +176,7 @@
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(); }
--- a/hotspot/src/share/vm/ci/ciFlags.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciFlags.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -59,6 +59,7 @@
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; }
--- a/hotspot/src/share/vm/ci/ciInstance.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciInstance.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -60,10 +60,10 @@
//
// Constant value of a field.
ciConstant ciInstance::field_value(ciField* field) {
- assert(is_loaded() &&
- field->holder()->is_loaded() &&
- klass()->is_subclass_of(field->holder()),
- "invalid access");
+ assert(is_loaded(), "invalid access - must be loaded");
+ assert(field->holder()->is_loaded(), "invalid access - holder must be loaded");
+ assert(klass()->is_subclass_of(field->holder()), "invalid access - must be subclass");
+
VM_ENTRY_MARK;
ciConstant result;
Handle obj = get_oop();
@@ -127,6 +127,8 @@
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);
}
--- a/hotspot/src/share/vm/ci/ciMethod.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -177,6 +177,10 @@
address bcp = code() + bci;
return Bytecodes::java_code_at(NULL, bcp);
}
+ Bytecodes::Code raw_code_at_bci(int bci) {
+ address bcp = code() + bci;
+ return Bytecodes::code_at(NULL, bcp);
+ }
BCEscapeAnalyzer *get_bcea();
ciMethodBlocks *get_method_blocks();
--- a/hotspot/src/share/vm/ci/ciObjectFactory.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciObjectFactory.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -563,7 +563,10 @@
return get_unloaded_instance(ciEnv::_MethodType_klass->as_instance_klass());
}
-
+ciInstance* ciObjectFactory::get_unloaded_object_constant() {
+ if (ciEnv::_Object_klass == NULL) return NULL;
+ return get_unloaded_instance(ciEnv::_Object_klass->as_instance_klass());
+}
//------------------------------------------------------------------
// ciObjectFactory::get_empty_methodData
--- a/hotspot/src/share/vm/ci/ciObjectFactory.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciObjectFactory.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -131,6 +131,8 @@
ciInstance* get_unloaded_method_type_constant(ciSymbol* signature);
+ ciInstance* get_unloaded_object_constant();
+
// Get the ciMethodData representing the methodData for a method
// with none.
ciMethodData* get_empty_methodData();
--- a/hotspot/src/share/vm/ci/ciTypeArray.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciTypeArray.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -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;
}
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -28,7 +28,6 @@
#include "classfile/classLoaderData.hpp"
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/defaultMethods.hpp"
-#include "classfile/genericSignatures.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
@@ -1775,6 +1774,10 @@
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
@@ -1787,6 +1790,8 @@
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() {
@@ -3039,35 +3044,6 @@
return annotations;
}
-
-#ifdef ASSERT
-static void parseAndPrintGenericSignatures(
- instanceKlassHandle this_klass, TRAPS) {
- assert(ParseAllGenericSignatures == true, "Shouldn't call otherwise");
- ResourceMark rm;
-
- if (this_klass->generic_signature() != NULL) {
- using namespace generic;
- ClassDescriptor* spec = ClassDescriptor::parse_generic_signature(this_klass(), CHECK);
-
- tty->print_cr("Parsing %s", this_klass->generic_signature()->as_C_string());
- spec->print_on(tty);
-
- for (int i = 0; i < this_klass->methods()->length(); ++i) {
- Method* m = this_klass->methods()->at(i);
- MethodDescriptor* method_spec = MethodDescriptor::parse_generic_signature(m, spec);
- Symbol* sig = m->generic_signature();
- if (sig == NULL) {
- sig = m->signature();
- }
- tty->print_cr("Parsing %s", sig->as_C_string());
- method_spec->print_on(tty);
- }
- }
-}
-#endif // def ASSERT
-
-
instanceKlassHandle ClassFileParser::parse_super_class(int super_class_index,
TRAPS) {
instanceKlassHandle super_klass;
@@ -4060,12 +4036,6 @@
java_lang_Class::create_mirror(this_klass, protection_domain, CHECK_(nullHandle));
-#ifdef ASSERT
- if (ParseAllGenericSignatures) {
- parseAndPrintGenericSignatures(this_klass, CHECK_(nullHandle));
- }
-#endif
-
// Generate any default methods - default methods are interface methods
// that have a default implementation. This is new with Lambda project.
if (has_default_methods && !access_flags.is_interface() &&
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -125,6 +125,7 @@
_method_LambdaForm_Compiled,
_method_LambdaForm_Hidden,
_sun_misc_Contended,
+ _field_Stable,
_annotation_LIMIT
};
const Location _location;
@@ -143,14 +144,23 @@
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.
--- a/hotspot/src/share/vm/classfile/classLoader.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -197,7 +197,7 @@
}
-ClassFileStream* ClassPathDirEntry::open_stream(const char* name) {
+ClassFileStream* ClassPathDirEntry::open_stream(const char* name, TRAPS) {
// construct full path name
char path[JVM_MAXPATHLEN];
if (jio_snprintf(path, sizeof(path), "%s%s%s", _dir, os::file_separator(), name) == -1) {
@@ -240,7 +240,7 @@
FREE_C_HEAP_ARRAY(char, _zip_name, mtClass);
}
-ClassFileStream* ClassPathZipEntry::open_stream(const char* name) {
+ClassFileStream* ClassPathZipEntry::open_stream(const char* name, TRAPS) {
// enable call to C land
JavaThread* thread = JavaThread::current();
ThreadToNativeFromVM ttn(thread);
@@ -284,24 +284,24 @@
}
}
-LazyClassPathEntry::LazyClassPathEntry(char* path, struct stat st) : ClassPathEntry() {
+LazyClassPathEntry::LazyClassPathEntry(char* path, const struct stat* st) : ClassPathEntry() {
_path = strdup(path);
- _st = st;
+ _st = *st;
_meta_index = NULL;
_resolved_entry = NULL;
+ _has_error = false;
}
bool LazyClassPathEntry::is_jar_file() {
return ((_st.st_mode & S_IFREG) == S_IFREG);
}
-ClassPathEntry* LazyClassPathEntry::resolve_entry() {
+ClassPathEntry* LazyClassPathEntry::resolve_entry(TRAPS) {
if (_resolved_entry != NULL) {
return (ClassPathEntry*) _resolved_entry;
}
ClassPathEntry* new_entry = NULL;
- ClassLoader::create_class_path_entry(_path, _st, &new_entry, false);
- assert(new_entry != NULL, "earlier code should have caught this");
+ new_entry = ClassLoader::create_class_path_entry(_path, &_st, false, CHECK_NULL);
{
ThreadCritical tc;
if (_resolved_entry == NULL) {
@@ -314,12 +314,21 @@
return (ClassPathEntry*) _resolved_entry;
}
-ClassFileStream* LazyClassPathEntry::open_stream(const char* name) {
+ClassFileStream* LazyClassPathEntry::open_stream(const char* name, TRAPS) {
if (_meta_index != NULL &&
!_meta_index->may_contain(name)) {
return NULL;
}
- return resolve_entry()->open_stream(name);
+ if (_has_error) {
+ return NULL;
+ }
+ ClassPathEntry* cpe = resolve_entry(THREAD);
+ if (cpe == NULL) {
+ _has_error = true;
+ return NULL;
+ } else {
+ return cpe->open_stream(name, THREAD);
+ }
}
bool LazyClassPathEntry::is_lazy() {
@@ -465,20 +474,19 @@
}
}
-void ClassLoader::create_class_path_entry(char *path, struct stat st, ClassPathEntry **new_entry, bool lazy) {
+ClassPathEntry* ClassLoader::create_class_path_entry(char *path, const struct stat* st, bool lazy, TRAPS) {
JavaThread* thread = JavaThread::current();
if (lazy) {
- *new_entry = new LazyClassPathEntry(path, st);
- return;
+ return new LazyClassPathEntry(path, st);
}
- if ((st.st_mode & S_IFREG) == S_IFREG) {
+ ClassPathEntry* new_entry = NULL;
+ if ((st->st_mode & S_IFREG) == S_IFREG) {
// Regular file, should be a zip file
// Canonicalized filename
char canonical_path[JVM_MAXPATHLEN];
if (!get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) {
// This matches the classic VM
- EXCEPTION_MARK;
- THROW_MSG(vmSymbols::java_io_IOException(), "Bad pathname");
+ THROW_MSG_(vmSymbols::java_io_IOException(), "Bad pathname", NULL);
}
char* error_msg = NULL;
jzfile* zip;
@@ -489,7 +497,7 @@
zip = (*ZipOpen)(canonical_path, &error_msg);
}
if (zip != NULL && error_msg == NULL) {
- *new_entry = new ClassPathZipEntry(zip, path);
+ new_entry = new ClassPathZipEntry(zip, path);
if (TraceClassLoading) {
tty->print_cr("[Opened %s]", path);
}
@@ -504,16 +512,16 @@
msg = NEW_RESOURCE_ARRAY(char, len); ;
jio_snprintf(msg, len - 1, "error in opening JAR file <%s> %s", error_msg, path);
}
- EXCEPTION_MARK;
- THROW_MSG(vmSymbols::java_lang_ClassNotFoundException(), msg);
+ THROW_MSG_(vmSymbols::java_lang_ClassNotFoundException(), msg, NULL);
}
} else {
// Directory
- *new_entry = new ClassPathDirEntry(path);
+ new_entry = new ClassPathDirEntry(path);
if (TraceClassLoading) {
tty->print_cr("[Path %s]", path);
}
}
+ return new_entry;
}
@@ -572,13 +580,14 @@
}
}
-void ClassLoader::update_class_path_entry_list(const char *path,
+void ClassLoader::update_class_path_entry_list(char *path,
bool check_for_duplicates) {
struct stat st;
- if (os::stat((char *)path, &st) == 0) {
+ if (os::stat(path, &st) == 0) {
// File or directory found
ClassPathEntry* new_entry = NULL;
- create_class_path_entry((char *)path, st, &new_entry, LazyBootClassLoader);
+ Thread* THREAD = Thread::current();
+ new_entry = create_class_path_entry(path, &st, LazyBootClassLoader, CHECK);
// The kernel VM adds dynamically to the end of the classloader path and
// doesn't reorder the bootclasspath which would break java.lang.Package
// (see PackageInfo).
@@ -897,7 +906,7 @@
PerfClassTraceTime::CLASS_LOAD);
ClassPathEntry* e = _first_entry;
while (e != NULL) {
- stream = e->open_stream(name);
+ stream = e->open_stream(name, CHECK_NULL);
if (stream != NULL) {
break;
}
@@ -1257,11 +1266,16 @@
}
void LazyClassPathEntry::compile_the_world(Handle loader, TRAPS) {
- resolve_entry()->compile_the_world(loader, CHECK);
+ ClassPathEntry* cpe = resolve_entry(THREAD);
+ if (cpe != NULL) {
+ cpe->compile_the_world(loader, CHECK);
+ }
}
bool LazyClassPathEntry::is_rt_jar() {
- return resolve_entry()->is_rt_jar();
+ Thread* THREAD = Thread::current();
+ ClassPathEntry* cpe = resolve_entry(THREAD);
+ return (cpe != NULL) ? cpe->is_jar_file() : false;
}
void ClassLoader::compile_the_world() {
--- a/hotspot/src/share/vm/classfile/classLoader.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -63,7 +63,7 @@
ClassPathEntry();
// Attempt to locate file_name through this class path entry.
// Returns a class file parsing stream if successfull.
- virtual ClassFileStream* open_stream(const char* name) = 0;
+ virtual ClassFileStream* open_stream(const char* name, TRAPS) = 0;
// Debugging
NOT_PRODUCT(virtual void compile_the_world(Handle loader, TRAPS) = 0;)
NOT_PRODUCT(virtual bool is_rt_jar() = 0;)
@@ -77,7 +77,7 @@
bool is_jar_file() { return false; }
const char* name() { return _dir; }
ClassPathDirEntry(char* dir);
- ClassFileStream* open_stream(const char* name);
+ ClassFileStream* open_stream(const char* name, TRAPS);
// Debugging
NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
NOT_PRODUCT(bool is_rt_jar();)
@@ -107,7 +107,7 @@
const char* name() { return _zip_name; }
ClassPathZipEntry(jzfile* zip, const char* zip_name);
~ClassPathZipEntry();
- ClassFileStream* open_stream(const char* name);
+ ClassFileStream* open_stream(const char* name, TRAPS);
void contents_do(void f(const char* name, void* context), void* context);
// Debugging
NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
@@ -125,13 +125,14 @@
char* _path; // dir or file
struct stat _st;
MetaIndex* _meta_index;
+ bool _has_error;
volatile ClassPathEntry* _resolved_entry;
- ClassPathEntry* resolve_entry();
+ ClassPathEntry* resolve_entry(TRAPS);
public:
bool is_jar_file();
const char* name() { return _path; }
- LazyClassPathEntry(char* path, struct stat st);
- ClassFileStream* open_stream(const char* name);
+ LazyClassPathEntry(char* path, const struct stat* st);
+ ClassFileStream* open_stream(const char* name, TRAPS);
void set_meta_index(MetaIndex* meta_index) { _meta_index = meta_index; }
virtual bool is_lazy();
// Debugging
@@ -207,14 +208,15 @@
static void setup_meta_index();
static void setup_bootstrap_search_path();
static void load_zip_library();
- static void create_class_path_entry(char *path, struct stat st, ClassPathEntry **new_entry, bool lazy);
+ static ClassPathEntry* create_class_path_entry(char *path, const struct stat* st,
+ bool lazy, TRAPS);
// Canonicalizes path names, so strcmp will work properly. This is mainly
// to avoid confusing the zip library
static bool get_canonical_path(char* orig, char* out, int len);
public:
// Used by the kernel jvm.
- static void update_class_path_entry_list(const char *path,
+ static void update_class_path_entry_list(char *path,
bool check_for_duplicates);
static void print_bootclasspath();
--- a/hotspot/src/share/vm/classfile/defaultMethods.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -25,7 +25,6 @@
#include "precompiled.hpp"
#include "classfile/bytecodeAssembler.hpp"
#include "classfile/defaultMethods.hpp"
-#include "classfile/genericSignatures.hpp"
#include "classfile/symbolTable.hpp"
#include "memory/allocation.hpp"
#include "memory/metadataFactory.hpp"
@@ -75,14 +74,6 @@
}
};
-class ContextMark : public PseudoScopeMark {
- private:
- generic::Context::Mark _mark;
- public:
- ContextMark(const generic::Context::Mark& cm) : _mark(cm) {}
- virtual void destroy() { _mark.destroy(); }
-};
-
#ifndef PRODUCT
static void print_slot(outputStream* str, Symbol* name, Symbol* signature) {
ResourceMark rm;
@@ -503,38 +494,6 @@
return SymbolTable::new_symbol(ss.base(), (int)ss.size(), CHECK_NULL);
}
-// A generic method family contains a set of all methods that implement a single
-// language-level method. Because of erasure, these methods may have different
-// signatures. As members of the set are collected while walking over the
-// hierarchy, they are tagged with a qualification state. The qualification
-// state for an erased method is set to disqualified if there exists a path
-// from the root of hierarchy to the method that contains an interleaving
-// language-equivalent method defined in an interface.
-class GenericMethodFamily : public MethodFamily {
- private:
-
- generic::MethodDescriptor* _descriptor; // language-level description
-
- public:
-
- GenericMethodFamily(generic::MethodDescriptor* canonical_desc)
- : _descriptor(canonical_desc) {}
-
- generic::MethodDescriptor* descriptor() const { return _descriptor; }
-
- bool descriptor_matches(generic::MethodDescriptor* md, generic::Context* ctx) {
- return descriptor()->covariant_match(md, ctx);
- }
-
-#ifndef PRODUCT
- Symbol* get_generic_sig() const {
-
- generic::Context ctx(NULL); // empty, as _descriptor already canonicalized
- TempNewSymbol sig = descriptor()->reify_signature(&ctx, Thread::current());
- return sig;
- }
-#endif // ndef PRODUCT
-};
class StateRestorer;
@@ -571,26 +530,6 @@
StateRestorer* record_method_and_dq_further(Method* mo);
};
-
-// StatefulGenericMethodFamily is a wrapper around GenericMethodFamily that maintains the
-// qualification state during hierarchy visitation, and applies that state
-// when adding members to the GenericMethodFamily.
-class StatefulGenericMethodFamily : public StatefulMethodFamily {
-
- public:
- StatefulGenericMethodFamily(generic::MethodDescriptor* md, generic::Context* ctx)
- : StatefulMethodFamily(new GenericMethodFamily(md->canonicalize(ctx))) {
-
- }
- GenericMethodFamily* get_method_family() {
- return (GenericMethodFamily*)_method_family;
- }
-
- bool descriptor_matches(generic::MethodDescriptor* md, generic::Context* ctx) {
- return get_method_family()->descriptor_matches(md, ctx);
- }
-};
-
class StateRestorer : public PseudoScopeMark {
private:
StatefulMethodFamily* _method;
@@ -616,39 +555,6 @@
return mark;
}
-class StatefulGenericMethodFamilies : public ResourceObj {
- private:
- GrowableArray<StatefulGenericMethodFamily*> _methods;
-
- public:
- StatefulGenericMethodFamily* find_matching(
- generic::MethodDescriptor* md, generic::Context* ctx) {
- for (int i = 0; i < _methods.length(); ++i) {
- StatefulGenericMethodFamily* existing = _methods.at(i);
- if (existing->descriptor_matches(md, ctx)) {
- return existing;
- }
- }
- return NULL;
- }
-
- StatefulGenericMethodFamily* find_matching_or_create(
- generic::MethodDescriptor* md, generic::Context* ctx) {
- StatefulGenericMethodFamily* method = find_matching(md, ctx);
- if (method == NULL) {
- method = new StatefulGenericMethodFamily(md, ctx);
- _methods.append(method);
- }
- return method;
- }
-
- void extract_families_into(GrowableArray<GenericMethodFamily*>* array) {
- for (int i = 0; i < _methods.length(); ++i) {
- array->append(_methods.at(i)->get_method_family());
- }
- }
-};
-
// Represents a location corresponding to a vtable slot for methods that
// neither the class nor any of it's ancestors provide an implementaion.
// Default methods may be present to fill this slot.
@@ -779,146 +685,11 @@
};
-// Iterates over the type hierarchy looking for all methods with a specific
-// method name. The result of this is a set of method families each of
-// which is populated with a set of methods that implement the same
-// language-level signature.
-class FindMethodsByGenericSig : public HierarchyVisitor<FindMethodsByGenericSig> {
- private:
- // Context data
- Thread* THREAD;
- generic::DescriptorCache* _cache;
- Symbol* _method_name;
- generic::Context* _ctx;
- StatefulGenericMethodFamilies _families;
- public:
-
- FindMethodsByGenericSig(generic::DescriptorCache* cache, Symbol* name,
- generic::Context* ctx, Thread* thread) :
- _cache(cache), _method_name(name), _ctx(ctx), THREAD(thread) {}
-
- void get_discovered_families(GrowableArray<GenericMethodFamily*>* methods) {
- _families.extract_families_into(methods);
- }
-
- void* new_node_data(InstanceKlass* cls) { return new PseudoScope(); }
- void free_node_data(void* node_data) {
- PseudoScope::cast(node_data)->destroy();
- }
-
- bool visit() {
- PseudoScope* scope = PseudoScope::cast(current_data());
- InstanceKlass* klass = current_class();
- InstanceKlass* sub = current_depth() > 0 ? class_at_depth(1) : NULL;
-
- ContextMark* cm = new ContextMark(_ctx->mark());
- scope->add_mark(cm); // will restore context when scope is freed
-
- _ctx->apply_type_arguments(sub, klass, THREAD);
-
- int start, end = 0;
- start = klass->find_method_by_name(_method_name, &end);
- if (start != -1) {
- for (int i = start; i < end; ++i) {
- Method* m = klass->methods()->at(i);
- // This gets the method's parameter list with its generic type
- // parameters resolved
- generic::MethodDescriptor* md = _cache->descriptor_for(m, THREAD);
-
- // Find all methods on this hierarchy that match this method
- // (name, signature). This class collects other families of this
- // method name.
- StatefulGenericMethodFamily* family =
- _families.find_matching_or_create(md, _ctx);
-
- if (klass->is_interface()) {
- // ???
- StateRestorer* restorer = family->record_method_and_dq_further(m);
- scope->add_mark(restorer);
- } else {
- // This is the rule that methods in classes "win" (bad word) over
- // methods in interfaces. This works because of single inheritance
- family->set_target_if_empty(m);
- }
- }
- }
- return true;
- }
-};
-
-#ifndef PRODUCT
-static void print_generic_families(
- GrowableArray<GenericMethodFamily*>* methods, Symbol* match) {
- streamIndentor si(tty, 4);
- if (methods->length() == 0) {
- tty->indent();
- tty->print_cr("No Logical Method found");
- }
- for (int i = 0; i < methods->length(); ++i) {
- tty->indent();
- GenericMethodFamily* lm = methods->at(i);
- if (lm->contains_signature(match)) {
- tty->print_cr("<Matching>");
- } else {
- tty->print_cr("<Non-Matching>");
- }
- lm->print_sig_on(tty, lm->get_generic_sig(), 1);
- }
-}
-#endif // ndef PRODUCT
static void create_overpasses(
GrowableArray<EmptyVtableSlot*>* slots, InstanceKlass* klass, TRAPS);
-static void generate_generic_defaults(
- InstanceKlass* klass, GrowableArray<EmptyVtableSlot*>* empty_slots,
- EmptyVtableSlot* slot, int current_slot_index, TRAPS) {
-
- if (slot->is_bound()) {
-#ifndef PRODUCT
- if (TraceDefaultMethods) {
- streamIndentor si(tty, 4);
- tty->indent().print_cr("Already bound to logical method:");
- GenericMethodFamily* lm = (GenericMethodFamily*)(slot->get_binding());
- lm->print_sig_on(tty, lm->get_generic_sig(), 1);
- }
-#endif // ndef PRODUCT
- return; // covered by previous processing
- }
-
- generic::DescriptorCache cache;
-
- generic::Context ctx(&cache);
- FindMethodsByGenericSig visitor(&cache, slot->name(), &ctx, CHECK);
- visitor.run(klass);
-
- GrowableArray<GenericMethodFamily*> discovered_families;
- visitor.get_discovered_families(&discovered_families);
-
-#ifndef PRODUCT
- if (TraceDefaultMethods) {
- print_generic_families(&discovered_families, slot->signature());
- }
-#endif // ndef PRODUCT
-
- // Find and populate any other slots that match the discovered families
- for (int j = current_slot_index; j < empty_slots->length(); ++j) {
- EmptyVtableSlot* open_slot = empty_slots->at(j);
-
- if (slot->name() == open_slot->name()) {
- for (int k = 0; k < discovered_families.length(); ++k) {
- GenericMethodFamily* lm = discovered_families.at(k);
-
- if (lm->contains_signature(open_slot->signature())) {
- lm->determine_target(klass, CHECK);
- open_slot->bind_family(lm);
- }
- }
- }
- }
-}
-
static void generate_erased_defaults(
InstanceKlass* klass, GrowableArray<EmptyVtableSlot*>* empty_slots,
EmptyVtableSlot* slot, TRAPS) {
@@ -943,21 +714,14 @@
//
// First if finds any name/signature slots that need any implementation (either
// because they are miranda or a superclass's implementation is an overpass
-// itself). For each slot, iterate over the hierarchy, using generic signature
-// information to partition any methods that match the name into method families
-// where each family contains methods whose signatures are equivalent at the
-// language level (i.e., their reified parameters match and return values are
-// covariant). Check those sets to see if they contain a signature that matches
-// the slot we're looking at (if we're lucky, there might be other empty slots
-// that we can fill using the same analysis).
+// itself). For each slot, iterate over the hierarchy, to see if they contain a
+// signature that matches the slot we are looking at.
//
// For each slot filled, we generate an overpass method that either calls the
// unique default method candidate using invokespecial, or throws an exception
// (in the case of no default method candidates, or more than one valid
-// candidate). These methods are then added to the class's method list. If
-// the method set we're using contains methods (qualified or not) with a
-// different runtime signature than the method we're creating, then we have to
-// create bridges with those signatures too.
+// candidate). These methods are then added to the class's method list.
+// The JVM does not create bridges nor handle generic signatures here.
void DefaultMethods::generate_default_methods(
InstanceKlass* klass, GrowableArray<Method*>* mirandas, TRAPS) {
@@ -997,11 +761,7 @@
}
#endif // ndef PRODUCT
- if (ParseGenericDefaults) {
- generate_generic_defaults(klass, empty_slots, slot, i, CHECK);
- } else {
- generate_erased_defaults(klass, empty_slots, slot, CHECK);
- }
+ generate_erased_defaults(klass, empty_slots, slot, CHECK);
}
#ifndef PRODUCT
if (TraceDefaultMethods) {
@@ -1019,13 +779,13 @@
}
/**
- * Generic analysis was used upon interface '_target' and found a unique
- * default method candidate with generic signature '_method_desc'. This
+ * Interface inheritance rules were used to find a unique default method
+ * candidate for the resolved class. This
* method is only viable if it would also be in the set of default method
* candidates if we ran a full analysis on the current class.
*
* The only reason that the method would not be in the set of candidates for
- * the current class is if that there's another covariantly matching method
+ * the current class is if that there's another matching method
* which is "more specific" than the found method -- i.e., one could find a
* path in the interface hierarchy in which the matching method appears
* before we get to '_target'.
@@ -1110,49 +870,6 @@
: ShadowChecker(thread, name, holder, target) {}
};
-class GenericShadowChecker : public ShadowChecker {
- private:
- generic::DescriptorCache* _cache;
- generic::MethodDescriptor* _method_desc;
-
- bool path_has_shadow() {
- generic::Context ctx(_cache);
-
- for (int i = current_depth() - 1; i > 0; --i) {
- InstanceKlass* ik = class_at_depth(i);
- InstanceKlass* sub = class_at_depth(i + 1);
- ctx.apply_type_arguments(sub, ik, THREAD);
-
- if (ik->is_interface()) {
- int end;
- int start = ik->find_method_by_name(_method_name, &end);
- if (start != -1) {
- for (int j = start; j < end; ++j) {
- Method* mo = ik->methods()->at(j);
- generic::MethodDescriptor* md = _cache->descriptor_for(mo, THREAD);
- if (_method_desc->covariant_match(md, &ctx)) {
- return true;
- }
- }
- }
- }
- }
- return false;
- }
-
- public:
-
- GenericShadowChecker(generic::DescriptorCache* cache, Thread* thread,
- Symbol* name, InstanceKlass* holder, generic::MethodDescriptor* desc,
- InstanceKlass* target)
- : ShadowChecker(thread, name, holder, target) {
- _cache = cache;
- _method_desc = desc;
- }
-};
-
-
-
// Find the unique qualified candidate from the perspective of the super_class
// which is the resolved_klass, which must be an immediate superinterface
// of klass
@@ -1166,103 +883,48 @@
if (family != NULL) {
family->determine_target(current_class, CHECK_NULL); // get target from current_class
- }
- if (family->has_target()) {
- Method* target = family->get_selected_target();
- InstanceKlass* holder = InstanceKlass::cast(target->method_holder());
+ if (family->has_target()) {
+ Method* target = family->get_selected_target();
+ InstanceKlass* holder = InstanceKlass::cast(target->method_holder());
- // Verify that the identified method is valid from the context of
- // the current class, which is the caller class for invokespecial
- // link resolution, i.e. ensure there it is not shadowed.
- // You can use invokespecial to disambiguate interface methods, but
- // you can not use it to skip over an interface method that would shadow it.
- ErasedShadowChecker checker(THREAD, target->name(), holder, super_class);
- checker.run(current_class);
+ // Verify that the identified method is valid from the context of
+ // the current class, which is the caller class for invokespecial
+ // link resolution, i.e. ensure there it is not shadowed.
+ // You can use invokespecial to disambiguate interface methods, but
+ // you can not use it to skip over an interface method that would shadow it.
+ ErasedShadowChecker checker(THREAD, target->name(), holder, super_class);
+ checker.run(current_class);
- if (checker.found_shadow()) {
+ if (checker.found_shadow()) {
#ifndef PRODUCT
- if (TraceDefaultMethods) {
- tty->print_cr(" Only candidate found was shadowed.");
- }
+ if (TraceDefaultMethods) {
+ tty->print_cr(" Only candidate found was shadowed.");
+ }
#endif // ndef PRODUCT
- THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(),
- "Accessible default method not found", NULL);
- } else {
+ THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(),
+ "Accessible default method not found", NULL);
+ } else {
#ifndef PRODUCT
- if (TraceDefaultMethods) {
- family->print_sig_on(tty, target->signature(), 1);
- }
+ if (TraceDefaultMethods) {
+ family->print_sig_on(tty, target->signature(), 1);
+ }
#endif // ndef PRODUCT
- return target;
- }
+ return target;
+ }
+ } else {
+ assert(family->throws_exception(), "must have target or throw");
+ THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(),
+ family->get_exception_message()->as_C_string(), NULL);
+ }
} else {
- assert(family->throws_exception(), "must have target or throw");
- THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(),
- family->get_exception_message()->as_C_string(), NULL);
+ // no method found
+ ResourceMark rm(THREAD);
+ THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(),
+ Method::name_and_sig_as_C_string(current_class,
+ method_name, sig), NULL);
}
}
-
-// super_class is assumed to be the direct super of current_class
-Method* find_generic_super_default( InstanceKlass* current_class,
- InstanceKlass* super_class,
- Symbol* method_name, Symbol* sig, TRAPS) {
- generic::DescriptorCache cache;
- generic::Context ctx(&cache);
-
- // Prime the initial generic context for current -> super_class
- ctx.apply_type_arguments(current_class, super_class, CHECK_NULL);
-
- FindMethodsByGenericSig visitor(&cache, method_name, &ctx, CHECK_NULL);
- visitor.run(super_class);
-
- GrowableArray<GenericMethodFamily*> families;
- visitor.get_discovered_families(&families);
-
-#ifndef PRODUCT
- if (TraceDefaultMethods) {
- print_generic_families(&families, sig);
- }
-#endif // ndef PRODUCT
-
- GenericMethodFamily* selected_family = NULL;
-
- for (int i = 0; i < families.length(); ++i) {
- GenericMethodFamily* lm = families.at(i);
- if (lm->contains_signature(sig)) {
- lm->determine_target(current_class, CHECK_NULL);
- selected_family = lm;
- }
- }
-
- if (selected_family->has_target()) {
- Method* target = selected_family->get_selected_target();
- InstanceKlass* holder = InstanceKlass::cast(target->method_holder());
-
- // Verify that the identified method is valid from the context of
- // the current class
- GenericShadowChecker checker(&cache, THREAD, target->name(),
- holder, selected_family->descriptor(), super_class);
- checker.run(current_class);
-
- if (checker.found_shadow()) {
-#ifndef PRODUCT
- if (TraceDefaultMethods) {
- tty->print_cr(" Only candidate found was shadowed.");
- }
-#endif // ndef PRODUCT
- THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(),
- "Accessible default method not found", NULL);
- } else {
- return target;
- }
- } else {
- assert(selected_family->throws_exception(), "must have target or throw");
- THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(),
- selected_family->get_exception_message()->as_C_string(), NULL);
- }
-}
-
// This is called during linktime when we find an invokespecial call that
// refers to a direct superinterface. It indicates that we should find the
// default method in the hierarchy of that superinterface, and if that method
@@ -1296,13 +958,8 @@
assert(super_class->is_interface(), "only call for default methods");
Method* target = NULL;
- if (ParseGenericDefaults) {
- target = find_generic_super_default(current_class, super_class,
- method_name, sig, CHECK_NULL);
- } else {
- target = find_erased_super_default(current_class, super_class,
- method_name, sig, CHECK_NULL);
- }
+ target = find_erased_super_default(current_class, super_class,
+ method_name, sig, CHECK_NULL);
#ifndef PRODUCT
if (target != NULL) {
--- a/hotspot/src/share/vm/classfile/genericSignatures.cpp Fri Sep 20 17:11:32 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1279 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-
-#include "classfile/genericSignatures.hpp"
-#include "classfile/symbolTable.hpp"
-#include "classfile/systemDictionary.hpp"
-#include "memory/resourceArea.hpp"
-
-namespace generic {
-
-// Helper class for parsing the generic signature Symbol in klass and methods
-class DescriptorStream : public ResourceObj {
- private:
- Symbol* _symbol;
- int _offset;
- int _mark;
- const char* _parse_error;
-
- void set_parse_error(const char* error) {
- assert(error != NULL, "Can't set NULL error string");
- _parse_error = error;
- }
-
- public:
- DescriptorStream(Symbol* sym)
- : _symbol(sym), _offset(0), _mark(-1), _parse_error(NULL) {}
-
- const char* parse_error() const {
- return _parse_error;
- }
-
- bool at_end() { return _offset >= _symbol->utf8_length(); }
-
- char peek() {
- if (at_end()) {
- set_parse_error("Peeking past end of signature");
- return '\0';
- } else {
- return _symbol->byte_at(_offset);
- }
- }
-
- char read() {
- if (at_end()) {
- set_parse_error("Reading past end of signature");
- return '\0';
- } else {
- return _symbol->byte_at(_offset++);
- }
- }
-
- void read(char expected) {
- char c = read();
- assert_char(c, expected, 0);
- }
-
- void assert_char(char c, char expected, int pos = -1) {
- if (c != expected) {
- const char* fmt = "Parse error at %d: expected %c but got %c";
- size_t len = strlen(fmt) + 5;
- char* buffer = NEW_RESOURCE_ARRAY(char, len);
- jio_snprintf(buffer, len, fmt, _offset + pos, expected, c);
- set_parse_error(buffer);
- }
- }
-
- void push(char c) {
- assert(c == _symbol->byte_at(_offset - 1), "Pushing back wrong value");
- --_offset;
- }
-
- void expect_end() {
- if (!at_end()) {
- set_parse_error("Unexpected data trailing signature");
- }
- }
-
- bool has_mark() { return _mark != -1; }
-
- void set_mark() {
- _mark = _offset;
- }
-
- Identifier* identifier_from_mark() {
- assert(has_mark(), "Mark should be set");
- if (!has_mark()) {
- set_parse_error("Expected mark to be set");
- return NULL;
- } else {
- Identifier* id = new Identifier(_symbol, _mark, _offset - 1);
- _mark = -1;
- return id;
- }
- }
-};
-
-
-#define CHECK_FOR_PARSE_ERROR() \
- if (STREAM->parse_error() != NULL) { \
- if (VerifyGenericSignatures) { \
- fatal(STREAM->parse_error()); \
- } \
- return NULL; \
- } (void)0
-
-#define READ() STREAM->read(); CHECK_FOR_PARSE_ERROR()
-#define PEEK() STREAM->peek(); CHECK_FOR_PARSE_ERROR()
-#define PUSH(c) STREAM->push(c)
-#define EXPECT(c) STREAM->read(c); CHECK_FOR_PARSE_ERROR()
-#define EXPECTED(c, ch) STREAM->assert_char(c, ch); CHECK_FOR_PARSE_ERROR()
-#define EXPECT_END() STREAM->expect_end(); CHECK_FOR_PARSE_ERROR()
-
-#define CHECK_STREAM STREAM); CHECK_FOR_PARSE_ERROR(); ((void)0
-
-#ifndef PRODUCT
-void Identifier::print_on(outputStream* str) const {
- for (int i = _begin; i < _end; ++i) {
- str->print("%c", (char)_sym->byte_at(i));
- }
-}
-#endif // ndef PRODUCT
-
-bool Identifier::equals(Identifier* other) {
- if (_sym == other->_sym && _begin == other->_begin && _end == other->_end) {
- return true;
- } else if (_end - _begin != other->_end - other->_begin) {
- return false;
- } else {
- size_t len = _end - _begin;
- char* addr = ((char*)_sym->bytes()) + _begin;
- char* oaddr = ((char*)other->_sym->bytes()) + other->_begin;
- return strncmp(addr, oaddr, len) == 0;
- }
-}
-
-bool Identifier::equals(Symbol* sym) {
- Identifier id(sym, 0, sym->utf8_length());
- return equals(&id);
-}
-
-/**
- * A formal type parameter may be found in the the enclosing class, but it could
- * also come from an enclosing method or outer class, in the case of inner-outer
- * classes or anonymous classes. For example:
- *
- * class Outer<T,V> {
- * class Inner<W> {
- * void m(T t, V v, W w);
- * }
- * }
- *
- * In this case, the type variables in m()'s signature are not all found in the
- * immediate enclosing class (Inner). class Inner has only type parameter W,
- * but it's outer_class field will reference Outer's descriptor which contains
- * T & V (no outer_method in this case).
- *
- * If you have an anonymous class, it has both an enclosing method *and* an
- * enclosing class where type parameters can be declared:
- *
- * class MOuter<T> {
- * <V> void bar(V v) {
- * Runnable r = new Runnable() {
- * public void run() {}
- * public void foo(T t, V v) { ... }
- * };
- * }
- * }
- *
- * In this case, foo will be a member of some class, Runnable$1, which has no
- * formal parameters itself, but has an outer_method (bar()) which provides
- * type parameter V, and an outer class MOuter with type parameter T.
- *
- * It is also possible that the outer class is itself an inner class to some
- * other class (or an anonymous class with an enclosing method), so we need to
- * follow the outer_class/outer_method chain to it's end when looking for a
- * type parameter.
- */
-TypeParameter* Descriptor::find_type_parameter(Identifier* id, int* depth) {
-
- int current_depth = 0;
-
- MethodDescriptor* outer_method = as_method_signature();
- ClassDescriptor* outer_class = as_class_signature();
-
- if (outer_class == NULL) { // 'this' is a method signature; use the holder
- outer_class = outer_method->outer_class();
- }
-
- while (outer_method != NULL || outer_class != NULL) {
- if (outer_method != NULL) {
- for (int i = 0; i < outer_method->type_parameters().length(); ++i) {
- TypeParameter* p = outer_method->type_parameters().at(i);
- if (p->identifier()->equals(id)) {
- *depth = -1; // indicates this this is a method parameter
- return p;
- }
- }
- }
- if (outer_class != NULL) {
- for (int i = 0; i < outer_class->type_parameters().length(); ++i) {
- TypeParameter* p = outer_class->type_parameters().at(i);
- if (p->identifier()->equals(id)) {
- *depth = current_depth;
- return p;
- }
- }
- outer_method = outer_class->outer_method();
- outer_class = outer_class->outer_class();
- ++current_depth;
- }
- }
-
- if (VerifyGenericSignatures) {
- fatal("Could not resolve identifier");
- }
-
- return NULL;
-}
-
-ClassDescriptor* ClassDescriptor::parse_generic_signature(Klass* klass, TRAPS) {
- return parse_generic_signature(klass, NULL, CHECK_NULL);
-}
-
-ClassDescriptor* ClassDescriptor::parse_generic_signature(
- Klass* klass, Symbol* original_name, TRAPS) {
-
- InstanceKlass* ik = InstanceKlass::cast(klass);
- Symbol* sym = ik->generic_signature();
-
- ClassDescriptor* spec;
-
- if (sym == NULL || (spec = ClassDescriptor::parse_generic_signature(sym)) == NULL) {
- spec = ClassDescriptor::placeholder(ik);
- }
-
- u2 outer_index = get_outer_class_index(ik, CHECK_NULL);
- if (outer_index != 0) {
- if (original_name == NULL) {
- original_name = ik->name();
- }
- Handle class_loader = Handle(THREAD, ik->class_loader());
- Handle protection_domain = Handle(THREAD, ik->protection_domain());
-
- Symbol* outer_name = ik->constants()->klass_name_at(outer_index);
- Klass* outer = SystemDictionary::find(
- outer_name, class_loader, protection_domain, CHECK_NULL);
- if (outer == NULL && !THREAD->is_Compiler_thread()) {
- if (outer_name == ik->super()->name()) {
- outer = SystemDictionary::resolve_super_or_fail(original_name, outer_name,
- class_loader, protection_domain,
- false, CHECK_NULL);
- }
- else {
- outer = SystemDictionary::resolve_or_fail(outer_name, class_loader,
- protection_domain, false, CHECK_NULL);
- }
- }
-
- InstanceKlass* outer_ik;
- ClassDescriptor* outer_spec = NULL;
- if (outer == NULL) {
- outer_spec = ClassDescriptor::placeholder(ik);
- assert(false, "Outer class not loaded and not loadable from here");
- } else {
- outer_ik = InstanceKlass::cast(outer);
- outer_spec = parse_generic_signature(outer, original_name, CHECK_NULL);
- }
- spec->set_outer_class(outer_spec);
-
- u2 encl_method_idx = ik->enclosing_method_method_index();
- if (encl_method_idx != 0 && outer_ik != NULL) {
- ConstantPool* cp = ik->constants();
- u2 name_index = cp->name_ref_index_at(encl_method_idx);
- u2 sig_index = cp->signature_ref_index_at(encl_method_idx);
- Symbol* name = cp->symbol_at(name_index);
- Symbol* sig = cp->symbol_at(sig_index);
- Method* m = outer_ik->find_method(name, sig);
- if (m != NULL) {
- Symbol* gsig = m->generic_signature();
- if (gsig != NULL) {
- MethodDescriptor* gms = MethodDescriptor::parse_generic_signature(gsig, outer_spec);
- spec->set_outer_method(gms);
- }
- } else if (VerifyGenericSignatures) {
- ResourceMark rm;
- stringStream ss;
- ss.print("Could not find method %s %s in class %s",
- name->as_C_string(), sig->as_C_string(), outer_name->as_C_string());
- fatal(ss.as_string());
- }
- }
- }
-
- spec->bind_variables_to_parameters();
- return spec;
-}
-
-ClassDescriptor* ClassDescriptor::placeholder(InstanceKlass* klass) {
- GrowableArray<TypeParameter*> formals;
- GrowableArray<ClassType*> interfaces;
- ClassType* super_type = NULL;
-
- Klass* super_klass = klass->super();
- if (super_klass != NULL) {
- InstanceKlass* super = InstanceKlass::cast(super_klass);
- super_type = ClassType::from_symbol(super->name());
- }
-
- for (int i = 0; i < klass->local_interfaces()->length(); ++i) {
- InstanceKlass* iface = InstanceKlass::cast(klass->local_interfaces()->at(i));
- interfaces.append(ClassType::from_symbol(iface->name()));
- }
- return new ClassDescriptor(formals, super_type, interfaces);
-}
-
-ClassDescriptor* ClassDescriptor::parse_generic_signature(Symbol* sym) {
-
- DescriptorStream ds(sym);
- DescriptorStream* STREAM = &ds;
-
- GrowableArray<TypeParameter*> parameters(8);
- char c = READ();
- if (c == '<') {
- c = READ();
- while (c != '>') {
- PUSH(c);
- TypeParameter* ftp = TypeParameter::parse_generic_signature(CHECK_STREAM);
- parameters.append(ftp);
- c = READ();
- }
- } else {
- PUSH(c);
- }
-
- EXPECT('L');
- ClassType* super = ClassType::parse_generic_signature(CHECK_STREAM);
-
- GrowableArray<ClassType*> signatures(2);
- while (!STREAM->at_end()) {
- EXPECT('L');
- ClassType* iface = ClassType::parse_generic_signature(CHECK_STREAM);
- signatures.append(iface);
- }
-
- EXPECT_END();
-
- return new ClassDescriptor(parameters, super, signatures);
-}
-
-#ifndef PRODUCT
-void ClassDescriptor::print_on(outputStream* str) const {
- str->indent().print_cr("ClassDescriptor {");
- {
- streamIndentor si(str);
- if (_type_parameters.length() > 0) {
- str->indent().print_cr("Formals {");
- {
- streamIndentor si(str);
- for (int i = 0; i < _type_parameters.length(); ++i) {
- _type_parameters.at(i)->print_on(str);
- }
- }
- str->indent().print_cr("}");
- }
- if (_super != NULL) {
- str->indent().print_cr("Superclass: ");
- {
- streamIndentor si(str);
- _super->print_on(str);
- }
- }
- if (_interfaces.length() > 0) {
- str->indent().print_cr("SuperInterfaces: {");
- {
- streamIndentor si(str);
- for (int i = 0; i < _interfaces.length(); ++i) {
- _interfaces.at(i)->print_on(str);
- }
- }
- str->indent().print_cr("}");
- }
- if (_outer_method != NULL) {
- str->indent().print_cr("Outer Method: {");
- {
- streamIndentor si(str);
- _outer_method->print_on(str);
- }
- str->indent().print_cr("}");
- }
- if (_outer_class != NULL) {
- str->indent().print_cr("Outer Class: {");
- {
- streamIndentor si(str);
- _outer_class->print_on(str);
- }
- str->indent().print_cr("}");
- }
- }
- str->indent().print_cr("}");
-}
-#endif // ndef PRODUCT
-
-ClassType* ClassDescriptor::interface_desc(Symbol* sym) {
- for (int i = 0; i < _interfaces.length(); ++i) {
- if (_interfaces.at(i)->identifier()->equals(sym)) {
- return _interfaces.at(i);
- }
- }
- if (VerifyGenericSignatures) {
- fatal("Did not find expected interface");
- }
- return NULL;
-}
-
-void ClassDescriptor::bind_variables_to_parameters() {
- if (_outer_class != NULL) {
- _outer_class->bind_variables_to_parameters();
- }
- if (_outer_method != NULL) {
- _outer_method->bind_variables_to_parameters();
- }
- for (int i = 0; i < _type_parameters.length(); ++i) {
- _type_parameters.at(i)->bind_variables_to_parameters(this, i);
- }
- if (_super != NULL) {
- _super->bind_variables_to_parameters(this);
- }
- for (int i = 0; i < _interfaces.length(); ++i) {
- _interfaces.at(i)->bind_variables_to_parameters(this);
- }
-}
-
-ClassDescriptor* ClassDescriptor::canonicalize(Context* ctx) {
-
- GrowableArray<TypeParameter*> type_params(_type_parameters.length());
- for (int i = 0; i < _type_parameters.length(); ++i) {
- type_params.append(_type_parameters.at(i)->canonicalize(ctx, 0));
- }
-
- ClassDescriptor* outer = _outer_class == NULL ? NULL :
- _outer_class->canonicalize(ctx);
-
- ClassType* super = _super == NULL ? NULL : _super->canonicalize(ctx, 0);
-
- GrowableArray<ClassType*> interfaces(_interfaces.length());
- for (int i = 0; i < _interfaces.length(); ++i) {
- interfaces.append(_interfaces.at(i)->canonicalize(ctx, 0));
- }
-
- MethodDescriptor* md = _outer_method == NULL ? NULL :
- _outer_method->canonicalize(ctx);
-
- return new ClassDescriptor(type_params, super, interfaces, outer, md);
-}
-
-u2 ClassDescriptor::get_outer_class_index(InstanceKlass* klass, TRAPS) {
- int inner_index = InstanceKlass::inner_class_inner_class_info_offset;
- int outer_index = InstanceKlass::inner_class_outer_class_info_offset;
- int name_offset = InstanceKlass::inner_class_inner_name_offset;
- int next_offset = InstanceKlass::inner_class_next_offset;
-
- if (klass->inner_classes() == NULL || klass->inner_classes()->length() == 0) {
- // No inner class info => no declaring class
- return 0;
- }
-
- Array<u2>* i_icls = klass->inner_classes();
- ConstantPool* i_cp = klass->constants();
- int i_length = i_icls->length();
-
- // Find inner_klass attribute
- for (int i = 0; i + next_offset < i_length; i += next_offset) {
- u2 ioff = i_icls->at(i + inner_index);
- u2 ooff = i_icls->at(i + outer_index);
- u2 noff = i_icls->at(i + name_offset);
- if (ioff != 0) {
- // Check to see if the name matches the class we're looking for
- // before attempting to find the class.
- if (i_cp->klass_name_at_matches(klass, ioff) && ooff != 0) {
- return ooff;
- }
- }
- }
-
- // It may be anonymous; try for that.
- u2 encl_method_class_idx = klass->enclosing_method_class_index();
- if (encl_method_class_idx != 0) {
- return encl_method_class_idx;
- }
-
- return 0;
-}
-
-MethodDescriptor* MethodDescriptor::parse_generic_signature(Method* m, ClassDescriptor* outer) {
- Symbol* generic_sig = m->generic_signature();
- MethodDescriptor* md = NULL;
- if (generic_sig == NULL || (md = parse_generic_signature(generic_sig, outer)) == NULL) {
- md = parse_generic_signature(m->signature(), outer);
- }
- assert(md != NULL, "Could not parse method signature");
- md->bind_variables_to_parameters();
- return md;
-}
-
-MethodDescriptor* MethodDescriptor::parse_generic_signature(Symbol* sym, ClassDescriptor* outer) {
-
- DescriptorStream ds(sym);
- DescriptorStream* STREAM = &ds;
-
- GrowableArray<TypeParameter*> params(8);
- char c = READ();
- if (c == '<') {
- c = READ();
- while (c != '>') {
- PUSH(c);
- TypeParameter* ftp = TypeParameter::parse_generic_signature(CHECK_STREAM);
- params.append(ftp);
- c = READ();
- }
- } else {
- PUSH(c);
- }
-
- EXPECT('(');
-
- GrowableArray<Type*> parameters(8);
- c = READ();
- while (c != ')') {
- PUSH(c);
- Type* arg = Type::parse_generic_signature(CHECK_STREAM);
- parameters.append(arg);
- c = READ();
- }
-
- Type* rt = Type::parse_generic_signature(CHECK_STREAM);
-
- GrowableArray<Type*> throws;
- while (!STREAM->at_end()) {
- EXPECT('^');
- Type* spec = Type::parse_generic_signature(CHECK_STREAM);
- throws.append(spec);
- }
-
- return new MethodDescriptor(params, outer, parameters, rt, throws);
-}
-
-void MethodDescriptor::bind_variables_to_parameters() {
- for (int i = 0; i < _type_parameters.length(); ++i) {
- _type_parameters.at(i)->bind_variables_to_parameters(this, i);
- }
- for (int i = 0; i < _parameters.length(); ++i) {
- _parameters.at(i)->bind_variables_to_parameters(this);
- }
- _return_type->bind_variables_to_parameters(this);
- for (int i = 0; i < _throws.length(); ++i) {
- _throws.at(i)->bind_variables_to_parameters(this);
- }
-}
-
-bool MethodDescriptor::covariant_match(MethodDescriptor* other, Context* ctx) {
-
- if (_parameters.length() == other->_parameters.length()) {
- for (int i = 0; i < _parameters.length(); ++i) {
- if (!_parameters.at(i)->covariant_match(other->_parameters.at(i), ctx)) {
- return false;
- }
- }
-
- if (_return_type->as_primitive() != NULL) {
- return _return_type->covariant_match(other->_return_type, ctx);
- } else {
- // return type is a reference
- return other->_return_type->as_class() != NULL ||
- other->_return_type->as_variable() != NULL ||
- other->_return_type->as_array() != NULL;
- }
- } else {
- return false;
- }
-}
-
-MethodDescriptor* MethodDescriptor::canonicalize(Context* ctx) {
-
- GrowableArray<TypeParameter*> type_params(_type_parameters.length());
- for (int i = 0; i < _type_parameters.length(); ++i) {
- type_params.append(_type_parameters.at(i)->canonicalize(ctx, 0));
- }
-
- ClassDescriptor* outer = _outer_class == NULL ? NULL :
- _outer_class->canonicalize(ctx);
-
- GrowableArray<Type*> params(_parameters.length());
- for (int i = 0; i < _parameters.length(); ++i) {
- params.append(_parameters.at(i)->canonicalize(ctx, 0));
- }
-
- Type* rt = _return_type->canonicalize(ctx, 0);
-
- GrowableArray<Type*> throws(_throws.length());
- for (int i = 0; i < _throws.length(); ++i) {
- throws.append(_throws.at(i)->canonicalize(ctx, 0));
- }
-
- return new MethodDescriptor(type_params, outer, params, rt, throws);
-}
-
-#ifndef PRODUCT
-TempNewSymbol MethodDescriptor::reify_signature(Context* ctx, TRAPS) {
- stringStream ss(256);
-
- ss.print("(");
- for (int i = 0; i < _parameters.length(); ++i) {
- _parameters.at(i)->reify_signature(&ss, ctx);
- }
- ss.print(")");
- _return_type->reify_signature(&ss, ctx);
- return SymbolTable::new_symbol(ss.base(), (int)ss.size(), THREAD);
-}
-
-void MethodDescriptor::print_on(outputStream* str) const {
- str->indent().print_cr("MethodDescriptor {");
- {
- streamIndentor si(str);
- if (_type_parameters.length() > 0) {
- str->indent().print_cr("Formals: {");
- {
- streamIndentor si(str);
- for (int i = 0; i < _type_parameters.length(); ++i) {
- _type_parameters.at(i)->print_on(str);
- }
- }
- str->indent().print_cr("}");
- }
- str->indent().print_cr("Parameters: {");
- {
- streamIndentor si(str);
- for (int i = 0; i < _parameters.length(); ++i) {
- _parameters.at(i)->print_on(str);
- }
- }
- str->indent().print_cr("}");
- str->indent().print_cr("Return Type: ");
- {
- streamIndentor si(str);
- _return_type->print_on(str);
- }
-
- if (_throws.length() > 0) {
- str->indent().print_cr("Throws: {");
- {
- streamIndentor si(str);
- for (int i = 0; i < _throws.length(); ++i) {
- _throws.at(i)->print_on(str);
- }
- }
- str->indent().print_cr("}");
- }
- }
- str->indent().print_cr("}");
-}
-#endif // ndef PRODUCT
-
-TypeParameter* TypeParameter::parse_generic_signature(DescriptorStream* STREAM) {
- STREAM->set_mark();
- char c = READ();
- while (c != ':') {
- c = READ();
- }
-
- Identifier* id = STREAM->identifier_from_mark();
-
- ClassType* class_bound = NULL;
- GrowableArray<ClassType*> interface_bounds(8);
-
- c = READ();
- if (c != '>') {
- if (c != ':') {
- EXPECTED(c, 'L');
- class_bound = ClassType::parse_generic_signature(CHECK_STREAM);
- c = READ();
- }
-
- while (c == ':') {
- EXPECT('L');
- ClassType* fts = ClassType::parse_generic_signature(CHECK_STREAM);
- interface_bounds.append(fts);
- c = READ();
- }
- }
- PUSH(c);
-
- return new TypeParameter(id, class_bound, interface_bounds);
-}
-
-void TypeParameter::bind_variables_to_parameters(Descriptor* sig, int position) {
- if (_class_bound != NULL) {
- _class_bound->bind_variables_to_parameters(sig);
- }
- for (int i = 0; i < _interface_bounds.length(); ++i) {
- _interface_bounds.at(i)->bind_variables_to_parameters(sig);
- }
- _position = position;
-}
-
-Type* TypeParameter::resolve(
- Context* ctx, int inner_depth, int ctx_depth) {
-
- if (inner_depth == -1) {
- // This indicates that the parameter is a method type parameter, which
- // isn't resolveable using the class hierarchy context
- return bound();
- }
-
- ClassType* provider = ctx->at_depth(ctx_depth);
- if (provider != NULL) {
- for (int i = 0; i < inner_depth && provider != NULL; ++i) {
- provider = provider->outer_class();
- }
- if (provider != NULL) {
- TypeArgument* arg = provider->type_argument_at(_position);
- if (arg != NULL) {
- Type* value = arg->lower_bound();
- return value->canonicalize(ctx, ctx_depth + 1);
- }
- }
- }
-
- return bound();
-}
-
-TypeParameter* TypeParameter::canonicalize(Context* ctx, int ctx_depth) {
- ClassType* bound = _class_bound == NULL ? NULL :
- _class_bound->canonicalize(ctx, ctx_depth);
-
- GrowableArray<ClassType*> ifaces(_interface_bounds.length());
- for (int i = 0; i < _interface_bounds.length(); ++i) {
- ifaces.append(_interface_bounds.at(i)->canonicalize(ctx, ctx_depth));
- }
-
- TypeParameter* ret = new TypeParameter(_identifier, bound, ifaces);
- ret->_position = _position;
- return ret;
-}
-
-ClassType* TypeParameter::bound() {
- if (_class_bound != NULL) {
- return _class_bound;
- }
-
- if (_interface_bounds.length() == 1) {
- return _interface_bounds.at(0);
- }
-
- return ClassType::java_lang_Object(); // TODO: investigate this case
-}
-
-#ifndef PRODUCT
-void TypeParameter::print_on(outputStream* str) const {
- str->indent().print_cr("Formal: {");
- {
- streamIndentor si(str);
-
- str->indent().print("Identifier: ");
- _identifier->print_on(str);
- str->print_cr("");
- if (_class_bound != NULL) {
- str->indent().print_cr("Class Bound: ");
- streamIndentor si(str);
- _class_bound->print_on(str);
- }
- if (_interface_bounds.length() > 0) {
- str->indent().print_cr("Interface Bounds: {");
- {
- streamIndentor si(str);
- for (int i = 0; i < _interface_bounds.length(); ++i) {
- _interface_bounds.at(i)->print_on(str);
- }
- }
- str->indent().print_cr("}");
- }
- str->indent().print_cr("Ordinal Position: %d", _position);
- }
- str->indent().print_cr("}");
-}
-#endif // ndef PRODUCT
-
-Type* Type::parse_generic_signature(DescriptorStream* STREAM) {
- char c = READ();
- switch (c) {
- case 'L':
- return ClassType::parse_generic_signature(CHECK_STREAM);
- case 'T':
- return TypeVariable::parse_generic_signature(CHECK_STREAM);
- case '[':
- return ArrayType::parse_generic_signature(CHECK_STREAM);
- default:
- return new PrimitiveType(c);
- }
-}
-
-Identifier* ClassType::parse_generic_signature_simple(GrowableArray<TypeArgument*>* args,
- bool* has_inner, DescriptorStream* STREAM) {
- STREAM->set_mark();
-
- char c = READ();
- while (c != ';' && c != '.' && c != '<') { c = READ(); }
- Identifier* id = STREAM->identifier_from_mark();
-
- if (c == '<') {
- c = READ();
- while (c != '>') {
- PUSH(c);
- TypeArgument* arg = TypeArgument::parse_generic_signature(CHECK_STREAM);
- args->append(arg);
- c = READ();
- }
- c = READ();
- }
-
- *has_inner = (c == '.');
- if (!(*has_inner)) {
- EXPECTED(c, ';');
- }
-
- return id;
-}
-
-ClassType* ClassType::parse_generic_signature(DescriptorStream* STREAM) {
- return parse_generic_signature(NULL, CHECK_STREAM);
-}
-
-ClassType* ClassType::parse_generic_signature(ClassType* outer, DescriptorStream* STREAM) {
- GrowableArray<TypeArgument*> args;
- ClassType* gct = NULL;
- bool has_inner = false;
-
- Identifier* id = parse_generic_signature_simple(&args, &has_inner, STREAM);
- if (id != NULL) {
- gct = new ClassType(id, args, outer);
-
- if (has_inner) {
- gct = parse_generic_signature(gct, CHECK_STREAM);
- }
- }
- return gct;
-}
-
-ClassType* ClassType::from_symbol(Symbol* sym) {
- assert(sym != NULL, "Must not be null");
- GrowableArray<TypeArgument*> args;
- Identifier* id = new Identifier(sym, 0, sym->utf8_length());
- return new ClassType(id, args, NULL);
-}
-
-ClassType* ClassType::java_lang_Object() {
- return from_symbol(vmSymbols::java_lang_Object());
-}
-
-void ClassType::bind_variables_to_parameters(Descriptor* sig) {
- for (int i = 0; i < _type_arguments.length(); ++i) {
- _type_arguments.at(i)->bind_variables_to_parameters(sig);
- }
- if (_outer_class != NULL) {
- _outer_class->bind_variables_to_parameters(sig);
- }
-}
-
-TypeArgument* ClassType::type_argument_at(int i) {
- if (i >= 0 && i < _type_arguments.length()) {
- return _type_arguments.at(i);
- } else {
- return NULL;
- }
-}
-
-#ifndef PRODUCT
-void ClassType::reify_signature(stringStream* ss, Context* ctx) {
- ss->print("L");
- _identifier->print_on(ss);
- ss->print(";");
-}
-
-void ClassType::print_on(outputStream* str) const {
- str->indent().print_cr("Class {");
- {
- streamIndentor si(str);
- str->indent().print("Name: ");
- _identifier->print_on(str);
- str->print_cr("");
- if (_type_arguments.length() != 0) {
- str->indent().print_cr("Type Arguments: {");
- {
- streamIndentor si(str);
- for (int j = 0; j < _type_arguments.length(); ++j) {
- _type_arguments.at(j)->print_on(str);
- }
- }
- str->indent().print_cr("}");
- }
- if (_outer_class != NULL) {
- str->indent().print_cr("Outer Class: ");
- streamIndentor sir(str);
- _outer_class->print_on(str);
- }
- }
- str->indent().print_cr("}");
-}
-#endif // ndef PRODUCT
-
-bool ClassType::covariant_match(Type* other, Context* ctx) {
-
- if (other == this) {
- return true;
- }
-
- TypeVariable* variable = other->as_variable();
- if (variable != NULL) {
- other = variable->resolve(ctx, 0);
- }
-
- ClassType* outer = outer_class();
- ClassType* other_class = other->as_class();
-
- if (other_class == NULL ||
- (outer == NULL) != (other_class->outer_class() == NULL)) {
- return false;
- }
-
- if (!_identifier->equals(other_class->_identifier)) {
- return false;
- }
-
- if (outer != NULL && !outer->covariant_match(other_class->outer_class(), ctx)) {
- return false;
- }
-
- return true;
-}
-
-ClassType* ClassType::canonicalize(Context* ctx, int ctx_depth) {
-
- GrowableArray<TypeArgument*> args(_type_arguments.length());
- for (int i = 0; i < _type_arguments.length(); ++i) {
- args.append(_type_arguments.at(i)->canonicalize(ctx, ctx_depth));
- }
-
- ClassType* outer = _outer_class == NULL ? NULL :
- _outer_class->canonicalize(ctx, ctx_depth);
-
- return new ClassType(_identifier, args, outer);
-}
-
-TypeVariable* TypeVariable::parse_generic_signature(DescriptorStream* STREAM) {
- STREAM->set_mark();
- char c = READ();
- while (c != ';') {
- c = READ();
- }
- Identifier* id = STREAM->identifier_from_mark();
-
- return new TypeVariable(id);
-}
-
-void TypeVariable::bind_variables_to_parameters(Descriptor* sig) {
- _parameter = sig->find_type_parameter(_id, &_inner_depth);
- if (VerifyGenericSignatures && _parameter == NULL) {
- fatal("Could not find formal parameter");
- }
-}
-
-Type* TypeVariable::resolve(Context* ctx, int ctx_depth) {
- if (parameter() != NULL) {
- return parameter()->resolve(ctx, inner_depth(), ctx_depth);
- } else {
- if (VerifyGenericSignatures) {
- fatal("Type variable matches no parameter");
- }
- return NULL;
- }
-}
-
-bool TypeVariable::covariant_match(Type* other, Context* ctx) {
-
- if (other == this) {
- return true;
- }
-
- Context my_context(NULL); // empty, results in erasure
- Type* my_type = resolve(&my_context, 0);
- if (my_type == NULL) {
- return false;
- }
-
- return my_type->covariant_match(other, ctx);
-}
-
-Type* TypeVariable::canonicalize(Context* ctx, int ctx_depth) {
- return resolve(ctx, ctx_depth);
-}
-
-#ifndef PRODUCT
-void TypeVariable::reify_signature(stringStream* ss, Context* ctx) {
- Type* type = resolve(ctx, 0);
- if (type != NULL) {
- type->reify_signature(ss, ctx);
- }
-}
-
-void TypeVariable::print_on(outputStream* str) const {
- str->indent().print_cr("Type Variable {");
- {
- streamIndentor si(str);
- str->indent().print("Name: ");
- _id->print_on(str);
- str->print_cr("");
- str->indent().print_cr("Inner depth: %d", _inner_depth);
- }
- str->indent().print_cr("}");
-}
-#endif // ndef PRODUCT
-
-ArrayType* ArrayType::parse_generic_signature(DescriptorStream* STREAM) {
- Type* base = Type::parse_generic_signature(CHECK_STREAM);
- return new ArrayType(base);
-}
-
-void ArrayType::bind_variables_to_parameters(Descriptor* sig) {
- assert(_base != NULL, "Invalid base");
- _base->bind_variables_to_parameters(sig);
-}
-
-bool ArrayType::covariant_match(Type* other, Context* ctx) {
- assert(_base != NULL, "Invalid base");
-
- if (other == this) {
- return true;
- }
-
- ArrayType* other_array = other->as_array();
- return (other_array != NULL && _base->covariant_match(other_array->_base, ctx));
-}
-
-ArrayType* ArrayType::canonicalize(Context* ctx, int ctx_depth) {
- assert(_base != NULL, "Invalid base");
- return new ArrayType(_base->canonicalize(ctx, ctx_depth));
-}
-
-#ifndef PRODUCT
-void ArrayType::reify_signature(stringStream* ss, Context* ctx) {
- assert(_base != NULL, "Invalid base");
- ss->print("[");
- _base->reify_signature(ss, ctx);
-}
-
-void ArrayType::print_on(outputStream* str) const {
- str->indent().print_cr("Array {");
- {
- streamIndentor si(str);
- _base->print_on(str);
- }
- str->indent().print_cr("}");
-}
-#endif // ndef PRODUCT
-
-bool PrimitiveType::covariant_match(Type* other, Context* ctx) {
-
- PrimitiveType* other_prim = other->as_primitive();
- return (other_prim != NULL && _type == other_prim->_type);
-}
-
-PrimitiveType* PrimitiveType::canonicalize(Context* ctx, int ctxd) {
- return this;
-}
-
-#ifndef PRODUCT
-void PrimitiveType::reify_signature(stringStream* ss, Context* ctx) {
- ss->print("%c", _type);
-}
-
-void PrimitiveType::print_on(outputStream* str) const {
- str->indent().print_cr("Primitive: '%c'", _type);
-}
-#endif // ndef PRODUCT
-
-void PrimitiveType::bind_variables_to_parameters(Descriptor* sig) {
-}
-
-TypeArgument* TypeArgument::parse_generic_signature(DescriptorStream* STREAM) {
- char c = READ();
- Type* type = NULL;
-
- switch (c) {
- case '*':
- return new TypeArgument(ClassType::java_lang_Object(), NULL);
- break;
- default:
- PUSH(c);
- // fall-through
- case '+':
- case '-':
- type = Type::parse_generic_signature(CHECK_STREAM);
- if (c == '+') {
- return new TypeArgument(type, NULL);
- } else if (c == '-') {
- return new TypeArgument(ClassType::java_lang_Object(), type);
- } else {
- return new TypeArgument(type, type);
- }
- }
-}
-
-void TypeArgument::bind_variables_to_parameters(Descriptor* sig) {
- assert(_lower_bound != NULL, "Invalid lower bound");
- _lower_bound->bind_variables_to_parameters(sig);
- if (_upper_bound != NULL && _upper_bound != _lower_bound) {
- _upper_bound->bind_variables_to_parameters(sig);
- }
-}
-
-bool TypeArgument::covariant_match(TypeArgument* other, Context* ctx) {
- assert(_lower_bound != NULL, "Invalid lower bound");
-
- if (other == this) {
- return true;
- }
-
- if (!_lower_bound->covariant_match(other->lower_bound(), ctx)) {
- return false;
- }
- return true;
-}
-
-TypeArgument* TypeArgument::canonicalize(Context* ctx, int ctx_depth) {
- assert(_lower_bound != NULL, "Invalid lower bound");
- Type* lower = _lower_bound->canonicalize(ctx, ctx_depth);
- Type* upper = NULL;
-
- if (_upper_bound == _lower_bound) {
- upper = lower;
- } else if (_upper_bound != NULL) {
- upper = _upper_bound->canonicalize(ctx, ctx_depth);
- }
-
- return new TypeArgument(lower, upper);
-}
-
-#ifndef PRODUCT
-void TypeArgument::print_on(outputStream* str) const {
- str->indent().print_cr("TypeArgument {");
- {
- streamIndentor si(str);
- if (_lower_bound != NULL) {
- str->indent().print("Lower bound: ");
- _lower_bound->print_on(str);
- }
- if (_upper_bound != NULL) {
- str->indent().print("Upper bound: ");
- _upper_bound->print_on(str);
- }
- }
- str->indent().print_cr("}");
-}
-#endif // ndef PRODUCT
-
-void Context::Mark::destroy() {
- if (is_active()) {
- _context->reset_to_mark(_marked_size);
- }
- deactivate();
-}
-
-void Context::apply_type_arguments(
- InstanceKlass* current, InstanceKlass* super, TRAPS) {
- assert(_cache != NULL, "Cannot use an empty context");
- ClassType* spec = NULL;
- if (current != NULL) {
- ClassDescriptor* descriptor = _cache->descriptor_for(current, CHECK);
- if (super == current->super()) {
- spec = descriptor->super();
- } else {
- spec = descriptor->interface_desc(super->name());
- }
- if (spec != NULL) {
- _type_arguments.push(spec);
- }
- }
-}
-
-void Context::reset_to_mark(int size) {
- _type_arguments.trunc_to(size);
-}
-
-ClassType* Context::at_depth(int i) const {
- if (i < _type_arguments.length()) {
- return _type_arguments.at(_type_arguments.length() - 1 - i);
- }
- return NULL;
-}
-
-#ifndef PRODUCT
-void Context::print_on(outputStream* str) const {
- str->indent().print_cr("Context {");
- for (int i = 0; i < _type_arguments.length(); ++i) {
- streamIndentor si(str);
- str->indent().print("leval %d: ", i);
- ClassType* ct = at_depth(i);
- if (ct == NULL) {
- str->print_cr("<empty>");
- continue;
- } else {
- str->print_cr("{");
- }
-
- for (int j = 0; j < ct->type_arguments_length(); ++j) {
- streamIndentor si(str);
- TypeArgument* ta = ct->type_argument_at(j);
- Type* bound = ta->lower_bound();
- bound->print_on(str);
- }
- str->indent().print_cr("}");
- }
- str->indent().print_cr("}");
-}
-#endif // ndef PRODUCT
-
-ClassDescriptor* DescriptorCache::descriptor_for(InstanceKlass* ik, TRAPS) {
-
- ClassDescriptor** existing = _class_descriptors.get(ik);
- if (existing == NULL) {
- ClassDescriptor* cd = ClassDescriptor::parse_generic_signature(ik, CHECK_NULL);
- _class_descriptors.put(ik, cd);
- return cd;
- } else {
- return *existing;
- }
-}
-
-MethodDescriptor* DescriptorCache::descriptor_for(
- Method* mh, ClassDescriptor* cd, TRAPS) {
- assert(mh != NULL && cd != NULL, "Should not be NULL");
- MethodDescriptor** existing = _method_descriptors.get(mh);
- if (existing == NULL) {
- MethodDescriptor* md = MethodDescriptor::parse_generic_signature(mh, cd);
- _method_descriptors.put(mh, md);
- return md;
- } else {
- return *existing;
- }
-}
-MethodDescriptor* DescriptorCache::descriptor_for(Method* mh, TRAPS) {
- ClassDescriptor* cd = descriptor_for(
- InstanceKlass::cast(mh->method_holder()), CHECK_NULL);
- return descriptor_for(mh, cd, THREAD);
-}
-
-} // namespace generic
--- a/hotspot/src/share/vm/classfile/genericSignatures.hpp Fri Sep 20 17:11:32 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,467 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP
-#define SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP
-
-#include "classfile/symbolTable.hpp"
-#include "memory/allocation.hpp"
-#include "runtime/signature.hpp"
-#include "utilities/growableArray.hpp"
-#include "utilities/resourceHash.hpp"
-
-class stringStream;
-
-namespace generic {
-
-class Identifier;
-class ClassDescriptor;
-class MethodDescriptor;
-
-class TypeParameter; // a formal type parameter declared in generic signatures
-class TypeArgument; // The "type value" passed to fill parameters in supertypes
-class TypeVariable; // A usage of a type parameter as a value
-/**
- * Example:
- *
- * <T, V> class Foo extends Bar<String> { int m(V v) {} }
- * ^^^^^^ ^^^^^^ ^^
- * type parameters type argument type variable
- *
- * Note that a type variable could be passed as an argument too:
- * <T, V> class Foo extends Bar<T> { int m(V v) {} }
- * ^^^
- * type argument's value is a type variable
- */
-
-
-class Type;
-class ClassType;
-class ArrayType;
-class PrimitiveType;
-class Context;
-class DescriptorCache;
-
-class DescriptorStream;
-
-class Identifier : public ResourceObj {
- private:
- Symbol* _sym;
- int _begin;
- int _end;
-
- public:
- Identifier(Symbol* sym, int begin, int end) :
- _sym(sym), _begin(begin), _end(end) {}
-
- bool equals(Identifier* other);
- bool equals(Symbol* sym);
-
-#ifndef PRODUCT
- void print_on(outputStream* str) const;
-#endif // ndef PRODUCT
-};
-
-class Descriptor : public ResourceObj {
- protected:
- GrowableArray<TypeParameter*> _type_parameters;
- ClassDescriptor* _outer_class;
-
- Descriptor(GrowableArray<TypeParameter*>& params,
- ClassDescriptor* outer)
- : _type_parameters(params), _outer_class(outer) {}
-
- public:
-
- ClassDescriptor* outer_class() { return _outer_class; }
- void set_outer_class(ClassDescriptor* sig) { _outer_class = sig; }
-
- virtual ClassDescriptor* as_class_signature() { return NULL; }
- virtual MethodDescriptor* as_method_signature() { return NULL; }
-
- bool is_class_signature() { return as_class_signature() != NULL; }
- bool is_method_signature() { return as_method_signature() != NULL; }
-
- GrowableArray<TypeParameter*>& type_parameters() {
- return _type_parameters;
- }
-
- TypeParameter* find_type_parameter(Identifier* id, int* param_depth);
-
- virtual void bind_variables_to_parameters() = 0;
-
-#ifndef PRODUCT
- virtual void print_on(outputStream* str) const = 0;
-#endif
-};
-
-class ClassDescriptor : public Descriptor {
- private:
- ClassType* _super;
- GrowableArray<ClassType*> _interfaces;
- MethodDescriptor* _outer_method;
-
- ClassDescriptor(GrowableArray<TypeParameter*>& ftp, ClassType* scs,
- GrowableArray<ClassType*>& sis, ClassDescriptor* outer_class = NULL,
- MethodDescriptor* outer_method = NULL)
- : Descriptor(ftp, outer_class), _super(scs), _interfaces(sis),
- _outer_method(outer_method) {}
-
- static u2 get_outer_class_index(InstanceKlass* k, TRAPS);
- static ClassDescriptor* parse_generic_signature(Klass* k, Symbol* original_name, TRAPS);
-
- public:
-
- virtual ClassDescriptor* as_class_signature() { return this; }
-
- MethodDescriptor* outer_method() { return _outer_method; }
- void set_outer_method(MethodDescriptor* m) { _outer_method = m; }
-
- ClassType* super() { return _super; }
- ClassType* interface_desc(Symbol* sym);
-
- static ClassDescriptor* parse_generic_signature(Klass* k, TRAPS);
- static ClassDescriptor* parse_generic_signature(Symbol* sym);
-
- // For use in superclass chains in positions where this is no generic info
- static ClassDescriptor* placeholder(InstanceKlass* klass);
-
-#ifndef PRODUCT
- void print_on(outputStream* str) const;
-#endif
-
- ClassDescriptor* canonicalize(Context* ctx);
-
- // Linking sets the position index in any contained TypeVariable type
- // to correspond to the location of that identifier in the formal type
- // parameters.
- void bind_variables_to_parameters();
-};
-
-class MethodDescriptor : public Descriptor {
- private:
- GrowableArray<Type*> _parameters;
- Type* _return_type;
- GrowableArray<Type*> _throws;
-
- MethodDescriptor(GrowableArray<TypeParameter*>& ftp, ClassDescriptor* outer,
- GrowableArray<Type*>& sigs, Type* rt, GrowableArray<Type*>& throws)
- : Descriptor(ftp, outer), _parameters(sigs), _return_type(rt),
- _throws(throws) {}
-
- public:
-
- static MethodDescriptor* parse_generic_signature(Method* m, ClassDescriptor* outer);
- static MethodDescriptor* parse_generic_signature(Symbol* sym, ClassDescriptor* outer);
-
- MethodDescriptor* as_method_signature() { return this; }
-
- // Performs generic analysis on the method parameters to determine
- // if both methods refer to the same argument types.
- bool covariant_match(MethodDescriptor* other, Context* ctx);
-
- // Returns a new method descriptor with all generic variables
- // removed and replaced with whatever is indicated using the Context.
- MethodDescriptor* canonicalize(Context* ctx);
-
- void bind_variables_to_parameters();
-
-#ifndef PRODUCT
- TempNewSymbol reify_signature(Context* ctx, TRAPS);
- void print_on(outputStream* str) const;
-#endif
-};
-
-class TypeParameter : public ResourceObj {
- private:
- Identifier* _identifier;
- ClassType* _class_bound;
- GrowableArray<ClassType*> _interface_bounds;
-
- // The position is the ordinal location of the parameter within the
- // formal parameter list (excluding outer classes). It is only set for
- // formal type parameters that are associated with a class -- method
- // type parameters are left as -1. When resolving a generic variable to
- // find the actual type, this index is used to access the generic type
- // argument in the provided context object.
- int _position; // Assigned during variable linking
-
- TypeParameter(Identifier* id, ClassType* class_bound,
- GrowableArray<ClassType*>& interface_bounds) :
- _identifier(id), _class_bound(class_bound),
- _interface_bounds(interface_bounds), _position(-1) {}
-
- public:
- static TypeParameter* parse_generic_signature(DescriptorStream* str);
-
- ClassType* bound();
- int position() { return _position; }
-
- void bind_variables_to_parameters(Descriptor* sig, int position);
- Identifier* identifier() { return _identifier; }
-
- Type* resolve(Context* ctx, int inner_depth, int ctx_depth);
- TypeParameter* canonicalize(Context* ctx, int ctx_depth);
-
-#ifndef PRODUCT
- void print_on(outputStream* str) const;
-#endif
-};
-
-class Type : public ResourceObj {
- public:
- static Type* parse_generic_signature(DescriptorStream* str);
-
- virtual ClassType* as_class() { return NULL; }
- virtual TypeVariable* as_variable() { return NULL; }
- virtual ArrayType* as_array() { return NULL; }
- virtual PrimitiveType* as_primitive() { return NULL; }
-
- virtual bool covariant_match(Type* gt, Context* ctx) = 0;
- virtual Type* canonicalize(Context* ctx, int ctx_depth) = 0;
-
- virtual void bind_variables_to_parameters(Descriptor* sig) = 0;
-
-#ifndef PRODUCT
- virtual void reify_signature(stringStream* ss, Context* ctx) = 0;
- virtual void print_on(outputStream* str) const = 0;
-#endif
-};
-
-class ClassType : public Type {
- friend class ClassDescriptor;
- protected:
- Identifier* _identifier;
- GrowableArray<TypeArgument*> _type_arguments;
- ClassType* _outer_class;
-
- ClassType(Identifier* identifier,
- GrowableArray<TypeArgument*>& args,
- ClassType* outer)
- : _identifier(identifier), _type_arguments(args), _outer_class(outer) {}
-
- // Returns true if there are inner classes to read
- static Identifier* parse_generic_signature_simple(
- GrowableArray<TypeArgument*>* args,
- bool* has_inner, DescriptorStream* str);
-
- static ClassType* parse_generic_signature(ClassType* outer,
- DescriptorStream* str);
- static ClassType* from_symbol(Symbol* sym);
-
- public:
- ClassType* as_class() { return this; }
-
- static ClassType* parse_generic_signature(DescriptorStream* str);
- static ClassType* java_lang_Object();
-
- Identifier* identifier() { return _identifier; }
- int type_arguments_length() { return _type_arguments.length(); }
- TypeArgument* type_argument_at(int i);
-
- virtual ClassType* outer_class() { return _outer_class; }
-
- bool covariant_match(Type* gt, Context* ctx);
- ClassType* canonicalize(Context* ctx, int context_depth);
-
- void bind_variables_to_parameters(Descriptor* sig);
-
-#ifndef PRODUCT
- void reify_signature(stringStream* ss, Context* ctx);
- void print_on(outputStream* str) const;
-#endif
-};
-
-class TypeVariable : public Type {
- private:
- Identifier* _id;
- TypeParameter* _parameter; // assigned during linking
-
- // how many steps "out" from inner classes, -1 if method
- int _inner_depth;
-
- TypeVariable(Identifier* id)
- : _id(id), _parameter(NULL), _inner_depth(0) {}
-
- public:
- TypeVariable* as_variable() { return this; }
-
- static TypeVariable* parse_generic_signature(DescriptorStream* str);
-
- Identifier* identifier() { return _id; }
- TypeParameter* parameter() { return _parameter; }
- int inner_depth() { return _inner_depth; }
-
- void bind_variables_to_parameters(Descriptor* sig);
-
- Type* resolve(Context* ctx, int ctx_depth);
- bool covariant_match(Type* gt, Context* ctx);
- Type* canonicalize(Context* ctx, int ctx_depth);
-
-#ifndef PRODUCT
- void reify_signature(stringStream* ss, Context* ctx);
- void print_on(outputStream* str) const;
-#endif
-};
-
-class ArrayType : public Type {
- private:
- Type* _base;
-
- ArrayType(Type* base) : _base(base) {}
-
- public:
- ArrayType* as_array() { return this; }
-
- static ArrayType* parse_generic_signature(DescriptorStream* str);
-
- bool covariant_match(Type* gt, Context* ctx);
- ArrayType* canonicalize(Context* ctx, int ctx_depth);
-
- void bind_variables_to_parameters(Descriptor* sig);
-
-#ifndef PRODUCT
- void reify_signature(stringStream* ss, Context* ctx);
- void print_on(outputStream* str) const;
-#endif
-};
-
-class PrimitiveType : public Type {
- friend class Type;
- private:
- char _type; // includes V for void
-
- PrimitiveType(char& type) : _type(type) {}
-
- public:
- PrimitiveType* as_primitive() { return this; }
-
- bool covariant_match(Type* gt, Context* ctx);
- PrimitiveType* canonicalize(Context* ctx, int ctx_depth);
-
- void bind_variables_to_parameters(Descriptor* sig);
-
-#ifndef PRODUCT
- void reify_signature(stringStream* ss, Context* ctx);
- void print_on(outputStream* str) const;
-#endif
-};
-
-class TypeArgument : public ResourceObj {
- private:
- Type* _lower_bound;
- Type* _upper_bound; // may be null or == _lower_bound
-
- TypeArgument(Type* lower_bound, Type* upper_bound)
- : _lower_bound(lower_bound), _upper_bound(upper_bound) {}
-
- public:
-
- static TypeArgument* parse_generic_signature(DescriptorStream* str);
-
- Type* lower_bound() { return _lower_bound; }
- Type* upper_bound() { return _upper_bound; }
-
- void bind_variables_to_parameters(Descriptor* sig);
- TypeArgument* canonicalize(Context* ctx, int ctx_depth);
-
- bool covariant_match(TypeArgument* a, Context* ctx);
-
-#ifndef PRODUCT
- void print_on(outputStream* str) const;
-#endif
-};
-
-
-class Context : public ResourceObj {
- private:
- DescriptorCache* _cache;
- GrowableArray<ClassType*> _type_arguments;
-
- void reset_to_mark(int size);
-
- public:
- // When this object goes out of scope or 'destroy' is
- // called, then the application of the type to the
- // context is wound-back (unless it's been deactivated).
- class Mark : public StackObj {
- private:
- mutable Context* _context;
- int _marked_size;
-
- bool is_active() const { return _context != NULL; }
- void deactivate() const { _context = NULL; }
-
- public:
- Mark() : _context(NULL), _marked_size(0) {}
- Mark(Context* ctx, int sz) : _context(ctx), _marked_size(sz) {}
- Mark(const Mark& m) : _context(m._context), _marked_size(m._marked_size) {
- m.deactivate(); // Ownership is transferred
- }
-
- Mark& operator=(const Mark& cm) {
- destroy();
- _context = cm._context;
- _marked_size = cm._marked_size;
- cm.deactivate();
- return *this;
- }
-
- void destroy();
- ~Mark() { destroy(); }
- };
-
- Context(DescriptorCache* cache) : _cache(cache) {}
-
- Mark mark() { return Mark(this, _type_arguments.length()); }
- void apply_type_arguments(InstanceKlass* current, InstanceKlass* super,TRAPS);
-
- ClassType* at_depth(int i) const;
-
-#ifndef PRODUCT
- void print_on(outputStream* str) const;
-#endif
-};
-
-/**
- * Contains a cache of descriptors for classes and methods so they can be
- * looked-up instead of reparsing each time they are needed.
- */
-class DescriptorCache : public ResourceObj {
- private:
- ResourceHashtable<InstanceKlass*, ClassDescriptor*> _class_descriptors;
- ResourceHashtable<Method*, MethodDescriptor*> _method_descriptors;
-
- public:
- ClassDescriptor* descriptor_for(InstanceKlass* ikh, TRAPS);
-
- MethodDescriptor* descriptor_for(Method* mh, ClassDescriptor* cd, TRAPS);
- // Class descriptor derived from method holder
- MethodDescriptor* descriptor_for(Method* mh, TRAPS);
-};
-
-} // namespace generic
-
-#endif // SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP
-
--- a/hotspot/src/share/vm/classfile/verifier.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -188,6 +188,10 @@
bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class) {
Symbol* name = klass->name();
Klass* refl_magic_klass = SystemDictionary::reflect_MagicAccessorImpl_klass();
+ Klass* lambda_magic_klass = SystemDictionary::lambda_MagicLambdaImpl_klass();
+
+ bool is_reflect = refl_magic_klass != NULL && klass->is_subtype_of(refl_magic_klass);
+ bool is_lambda = lambda_magic_klass != NULL && klass->is_subtype_of(lambda_magic_klass);
return (should_verify_for(klass->class_loader(), should_verify_class) &&
// return if the class is a bootstrapping class
@@ -210,9 +214,9 @@
// sun/reflect/SerializationConstructorAccessor.
// NOTE: this is called too early in the bootstrapping process to be
// guarded by Universe::is_gte_jdk14x_version()/UseNewReflection.
- (refl_magic_klass == NULL ||
- !klass->is_subtype_of(refl_magic_klass) ||
- VerifyReflectionBytecodes)
+ // Also for lambda generated code, gte jdk8
+ (!is_reflect || VerifyReflectionBytecodes) &&
+ (!is_lambda || VerifyLambdaBytecodes)
);
}
@@ -2318,9 +2322,6 @@
types = 1 << JVM_CONSTANT_InvokeDynamic;
break;
case Bytecodes::_invokespecial:
- types = (1 << JVM_CONSTANT_InterfaceMethodref) |
- (1 << JVM_CONSTANT_Methodref);
- break;
case Bytecodes::_invokestatic:
types = (_klass->major_version() < STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION) ?
(1 << JVM_CONSTANT_Methodref) :
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -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") \
--- a/hotspot/src/share/vm/code/codeBlob.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/code/codeBlob.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -245,7 +245,7 @@
}
-void* BufferBlob::operator new(size_t s, unsigned size) {
+void* BufferBlob::operator new(size_t s, unsigned size) throw() {
void* p = CodeCache::allocate(size);
return p;
}
@@ -347,14 +347,14 @@
}
-void* RuntimeStub::operator new(size_t s, unsigned size) {
+void* RuntimeStub::operator new(size_t s, unsigned size) throw() {
void* p = CodeCache::allocate(size, true);
if (!p) fatal("Initial size of CodeCache is too small");
return p;
}
// operator new shared by all singletons:
-void* SingletonBlob::operator new(size_t s, unsigned size) {
+void* SingletonBlob::operator new(size_t s, unsigned size) throw() {
void* p = CodeCache::allocate(size, true);
if (!p) fatal("Initial size of CodeCache is too small");
return p;
--- a/hotspot/src/share/vm/code/codeBlob.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/code/codeBlob.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -209,7 +209,7 @@
BufferBlob(const char* name, int size);
BufferBlob(const char* name, int size, CodeBuffer* cb);
- void* operator new(size_t s, unsigned size);
+ void* operator new(size_t s, unsigned size) throw();
public:
// Creation
@@ -283,7 +283,7 @@
bool caller_must_gc_arguments
);
- void* operator new(size_t s, unsigned size);
+ void* operator new(size_t s, unsigned size) throw();
public:
// Creation
@@ -321,7 +321,7 @@
friend class VMStructs;
protected:
- void* operator new(size_t s, unsigned size);
+ void* operator new(size_t s, unsigned size) throw();
public:
SingletonBlob(
--- a/hotspot/src/share/vm/code/debugInfoRec.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/code/debugInfoRec.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -38,7 +38,7 @@
int _length; // number of bytes in the stream
int _hash; // hash of stream bytes (for quicker reuse)
- void* operator new(size_t ignore, DebugInformationRecorder* dir) {
+ void* operator new(size_t ignore, DebugInformationRecorder* dir) throw() {
assert(ignore == sizeof(DIR_Chunk), "");
if (dir->_next_chunk >= dir->_next_chunk_limit) {
const int CHUNK = 100;
--- a/hotspot/src/share/vm/code/nmethod.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/code/nmethod.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -93,18 +93,21 @@
#endif
bool nmethod::is_compiled_by_c1() const {
- if (compiler() == NULL || method() == NULL) return false; // can happen during debug printing
- if (is_native_method()) return false;
+ if (compiler() == NULL) {
+ return false;
+ }
return compiler()->is_c1();
}
bool nmethod::is_compiled_by_c2() const {
- if (compiler() == NULL || method() == NULL) return false; // can happen during debug printing
- if (is_native_method()) return false;
+ if (compiler() == NULL) {
+ return false;
+ }
return compiler()->is_c2();
}
bool nmethod::is_compiled_by_shark() const {
- if (is_native_method()) return false;
- assert(compiler() != NULL, "must be");
+ if (compiler() == NULL) {
+ return false;
+ }
return compiler()->is_shark();
}
@@ -800,7 +803,7 @@
}
#endif // def HAVE_DTRACE_H
-void* nmethod::operator new(size_t size, int nmethod_size) throw () {
+void* nmethod::operator new(size_t size, int nmethod_size) throw() {
// Not critical, may return null if there is too little continuous memory
return CodeCache::allocate(nmethod_size);
}
@@ -1401,6 +1404,9 @@
// nmethods aren't scanned for GC.
_oops_are_stale = true;
#endif
+ // the Method may be reclaimed by class unloading now that the
+ // nmethod is in zombie state
+ set_method(NULL);
} else {
assert(state == not_entrant, "other cases may need to be handled differently");
}
--- a/hotspot/src/share/vm/code/nmethod.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/code/nmethod.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -265,7 +265,7 @@
int comp_level);
// helper methods
- void* operator new(size_t size, int nmethod_size);
+ void* operator new(size_t size, int nmethod_size) throw();
const char* reloc_string_for(u_char* begin, u_char* end);
// Returns true if this thread changed the state of the nmethod or
--- a/hotspot/src/share/vm/code/relocInfo.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/code/relocInfo.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -677,7 +677,7 @@
}
public:
- void* operator new(size_t size, const RelocationHolder& holder) {
+ void* operator new(size_t size, const RelocationHolder& holder) throw() {
if (size > sizeof(holder._relocbuf)) guarantee_size();
assert((void* const *)holder.reloc() == &holder._relocbuf[0], "ptrs must agree");
return holder.reloc();
--- a/hotspot/src/share/vm/code/vtableStubs.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/code/vtableStubs.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -49,7 +49,7 @@
static int num_vtable_chunks = 0;
-void* VtableStub::operator new(size_t size, int code_size) {
+void* VtableStub::operator new(size_t size, int code_size) throw() {
assert(size == sizeof(VtableStub), "mismatched size");
num_vtable_chunks++;
// compute real VtableStub size (rounded to nearest word)
--- a/hotspot/src/share/vm/code/vtableStubs.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/code/vtableStubs.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -46,7 +46,7 @@
bool _is_vtable_stub; // True if vtable stub, false, is itable stub
/* code follows here */ // The vtableStub code
- void* operator new(size_t size, int code_size);
+ void* operator new(size_t size, int code_size) throw();
VtableStub(bool is_vtable_stub, int index)
: _next(NULL), _is_vtable_stub(is_vtable_stub),
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -1718,7 +1718,7 @@
CodeCache::print_summary(&s, detailed);
}
ttyLocker ttyl;
- tty->print_cr(s.as_string());
+ tty->print(s.as_string());
}
// ------------------------------------------------------------------
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -2493,11 +2493,11 @@
void G1CollectedHeap::register_concurrent_cycle_end() {
if (_concurrent_cycle_started) {
- _gc_timer_cm->register_gc_end(os::elapsed_counter());
-
if (_cm->has_aborted()) {
_gc_tracer_cm->report_concurrent_mode_failure();
}
+
+ _gc_timer_cm->register_gc_end(os::elapsed_counter());
_gc_tracer_cm->report_gc_end(_gc_timer_cm->gc_end(), _gc_timer_cm->time_partitions());
_concurrent_cycle_started = false;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -168,7 +168,15 @@
// Set up the region size and associated fields. Given that the
// policy is created before the heap, we have to set this up here,
// so it's done as soon as possible.
- HeapRegion::setup_heap_region_size(Arguments::min_heap_size());
+
+ // It would have been natural to pass initial_heap_byte_size() and
+ // max_heap_byte_size() to setup_heap_region_size() but those have
+ // not been set up at this point since they should be aligned with
+ // the region size. So, there is a circular dependency here. We base
+ // the region size on the heap size, but the heap size should be
+ // aligned with the region size. To get around this we use the
+ // unaligned values for the heap.
+ HeapRegion::setup_heap_region_size(InitialHeapSize, MaxHeapSize);
HeapRegionRemSet::setup_remset_size();
G1ErgoVerbose::initialize();
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -149,18 +149,11 @@
// many regions in the heap (based on the min heap size).
#define TARGET_REGION_NUMBER 2048
-void HeapRegion::setup_heap_region_size(uintx min_heap_size) {
- // region_size in bytes
+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)) {
- // We base the automatic calculation on the min heap size. This
- // can be problematic if the spread between min and max is quite
- // wide, imagine -Xms128m -Xmx32g. But, if we decided it based on
- // the max size, the region size might be way too large for the
- // min size. Either way, some users might have to set the region
- // size manually for some -Xms / -Xmx combos.
-
- region_size = MAX2(min_heap_size / TARGET_REGION_NUMBER,
+ size_t average_heap_size = (initial_heap_size + max_heap_size) / 2;
+ region_size = MAX2(average_heap_size / TARGET_REGION_NUMBER,
(uintx) MIN_REGION_SIZE);
}
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -361,7 +361,7 @@
// CardsPerRegion). All those fields are considered constant
// throughout the JVM's execution, therefore they should only be set
// up once during initialization time.
- static void setup_heap_region_size(uintx min_heap_size);
+ static void setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size);
enum ClaimValues {
InitialClaimValue = 0,
--- a/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -28,6 +28,7 @@
#include "gc_implementation/shared/gcTrace.hpp"
#include "gc_implementation/shared/gcWhen.hpp"
#include "gc_implementation/shared/copyFailedInfo.hpp"
+#include "runtime/os.hpp"
#include "trace/tracing.hpp"
#include "trace/traceBackend.hpp"
#if INCLUDE_ALL_GCS
@@ -54,11 +55,12 @@
}
void GCTracer::send_reference_stats_event(ReferenceType type, size_t count) const {
- EventGCReferenceStatistics e;
+ EventGCReferenceStatistics e(UNTIMED);
if (e.should_commit()) {
e.set_gcId(_shared_gc_info.id());
e.set_type((u1)type);
e.set_count(count);
+ e.set_endtime(os::elapsed_counter());
e.commit();
}
}
@@ -105,20 +107,22 @@
}
void YoungGCTracer::send_promotion_failed_event(const PromotionFailedInfo& pf_info) const {
- EventPromotionFailed e;
+ EventPromotionFailed e(UNTIMED);
if (e.should_commit()) {
e.set_gcId(_shared_gc_info.id());
e.set_data(to_trace_struct(pf_info));
e.set_thread(pf_info.thread()->thread_id());
+ e.set_endtime(os::elapsed_counter());
e.commit();
}
}
// Common to CMS and G1
void OldGCTracer::send_concurrent_mode_failure_event() {
- EventConcurrentModeFailure e;
+ EventConcurrentModeFailure e(UNTIMED);
if (e.should_commit()) {
e.set_gcId(_shared_gc_info.id());
+ e.set_endtime(os::elapsed_counter());
e.commit();
}
}
@@ -136,7 +140,7 @@
}
void G1NewTracer::send_evacuation_info_event(EvacuationInfo* info) {
- EventEvacuationInfo e;
+ EventEvacuationInfo e(UNTIMED);
if (e.should_commit()) {
e.set_gcId(_shared_gc_info.id());
e.set_cSetRegions(info->collectionset_regions());
@@ -147,15 +151,17 @@
e.set_allocRegionsUsedAfter(info->alloc_regions_used_before() + info->bytes_copied());
e.set_bytesCopied(info->bytes_copied());
e.set_regionsFreed(info->regions_freed());
+ e.set_endtime(os::elapsed_counter());
e.commit();
}
}
void G1NewTracer::send_evacuation_failed_event(const EvacuationFailedInfo& ef_info) const {
- EventEvacuationFailed e;
+ EventEvacuationFailed e(UNTIMED);
if (e.should_commit()) {
e.set_gcId(_shared_gc_info.id());
e.set_data(to_trace_struct(ef_info));
+ e.set_endtime(os::elapsed_counter());
e.commit();
}
}
@@ -189,12 +195,13 @@
void visit(const GCHeapSummary* heap_summary) const {
const VirtualSpaceSummary& heap_space = heap_summary->heap();
- EventGCHeapSummary e;
+ EventGCHeapSummary e(UNTIMED);
if (e.should_commit()) {
e.set_gcId(_id);
e.set_when((u1)_when);
e.set_heapSpace(to_trace_struct(heap_space));
e.set_heapUsed(heap_summary->used());
+ e.set_endtime(os::elapsed_counter());
e.commit();
}
}
@@ -209,7 +216,7 @@
const SpaceSummary& from_space = ps_heap_summary->from();
const SpaceSummary& to_space = ps_heap_summary->to();
- EventPSHeapSummary e;
+ EventPSHeapSummary e(UNTIMED);
if (e.should_commit()) {
e.set_gcId(_id);
e.set_when((u1)_when);
@@ -220,6 +227,7 @@
e.set_edenSpace(to_trace_struct(ps_heap_summary->eden()));
e.set_fromSpace(to_trace_struct(ps_heap_summary->from()));
e.set_toSpace(to_trace_struct(ps_heap_summary->to()));
+ e.set_endtime(os::elapsed_counter());
e.commit();
}
}
@@ -241,13 +249,14 @@
}
void GCTracer::send_meta_space_summary_event(GCWhen::Type when, const MetaspaceSummary& meta_space_summary) const {
- EventMetaspaceSummary e;
+ EventMetaspaceSummary e(UNTIMED);
if (e.should_commit()) {
e.set_gcId(_shared_gc_info.id());
e.set_when((u1) when);
e.set_metaspace(to_trace_struct(meta_space_summary.meta_space()));
e.set_dataSpace(to_trace_struct(meta_space_summary.data_space()));
e.set_classSpace(to_trace_struct(meta_space_summary.class_space()));
+ e.set_endtime(os::elapsed_counter());
e.commit();
}
}
@@ -282,8 +291,6 @@
default: /* Ignore sending this phase */ break;
}
}
-
-#undef send_phase
};
void GCTracer::send_phase_events(TimePartitions* time_partitions) const {
--- a/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -144,9 +144,9 @@
_padded_avg(0.0), _deviation(0.0), _padding(padding) {}
// Placement support
- void* operator new(size_t ignored, void* p) { return p; }
+ void* operator new(size_t ignored, void* p) throw() { return p; }
// Allocator
- void* operator new(size_t size) { return CHeapObj<mtGC>::operator new(size); }
+ void* operator new(size_t size) throw() { return CHeapObj<mtGC>::operator new(size); }
// Accessor
float padded_average() const { return _padded_avg; }
--- a/hotspot/src/share/vm/libadt/port.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/libadt/port.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, 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
@@ -163,8 +163,8 @@
extern void *safe_calloc (const char *file, unsigned line, unsigned nitems, unsigned size);
extern void *safe_realloc(const char *file, unsigned line, void *ptr, unsigned size);
extern char *safe_strdup (const char *file, unsigned line, const char *src);
-inline void *operator new( size_t size ) { return malloc(size); }
-inline void operator delete( void *ptr ) { free(ptr); }
+inline void *operator new( size_t size ) throw() { return malloc(size); }
+inline void operator delete( void *ptr ) { free(ptr); }
#endif
//-----------------------------------------------------------------------------
--- a/hotspot/src/share/vm/memory/allocation.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/memory/allocation.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -49,19 +49,19 @@
# include "os_bsd.inline.hpp"
#endif
-void* StackObj::operator new(size_t size) { ShouldNotCallThis(); return 0; }
-void StackObj::operator delete(void* p) { ShouldNotCallThis(); }
-void* StackObj::operator new [](size_t size) { ShouldNotCallThis(); return 0; }
-void StackObj::operator delete [](void* p) { ShouldNotCallThis(); }
+void* StackObj::operator new(size_t size) throw() { ShouldNotCallThis(); return 0; }
+void StackObj::operator delete(void* p) { ShouldNotCallThis(); }
+void* StackObj::operator new [](size_t size) throw() { ShouldNotCallThis(); return 0; }
+void StackObj::operator delete [](void* p) { ShouldNotCallThis(); }
-void* _ValueObj::operator new(size_t size) { ShouldNotCallThis(); return 0; }
-void _ValueObj::operator delete(void* p) { ShouldNotCallThis(); }
-void* _ValueObj::operator new [](size_t size) { ShouldNotCallThis(); return 0; }
-void _ValueObj::operator delete [](void* p) { ShouldNotCallThis(); }
+void* _ValueObj::operator new(size_t size) throw() { ShouldNotCallThis(); return 0; }
+void _ValueObj::operator delete(void* p) { ShouldNotCallThis(); }
+void* _ValueObj::operator new [](size_t size) throw() { ShouldNotCallThis(); return 0; }
+void _ValueObj::operator delete [](void* p) { ShouldNotCallThis(); }
void* MetaspaceObj::operator new(size_t size, ClassLoaderData* loader_data,
size_t word_size, bool read_only,
- MetaspaceObj::Type type, TRAPS) {
+ MetaspaceObj::Type type, TRAPS) throw() {
// Klass has it's own operator new
return Metaspace::allocate(loader_data, word_size, read_only,
type, CHECK_NULL);
@@ -80,7 +80,7 @@
st->print(" {"INTPTR_FORMAT"}", this);
}
-void* ResourceObj::operator new(size_t size, allocation_type type, MEMFLAGS flags) {
+void* ResourceObj::operator new(size_t size, allocation_type type, MEMFLAGS flags) throw() {
address res;
switch (type) {
case C_HEAP:
@@ -97,12 +97,12 @@
return res;
}
-void* ResourceObj::operator new [](size_t size, allocation_type type, MEMFLAGS flags) {
+void* ResourceObj::operator new [](size_t size, allocation_type type, MEMFLAGS flags) throw() {
return (address) operator new(size, type, flags);
}
void* ResourceObj::operator new(size_t size, const std::nothrow_t& nothrow_constant,
- allocation_type type, MEMFLAGS flags) {
+ allocation_type type, MEMFLAGS flags) throw() {
//should only call this with std::nothrow, use other operator new() otherwise
address res;
switch (type) {
@@ -121,7 +121,7 @@
}
void* ResourceObj::operator new [](size_t size, const std::nothrow_t& nothrow_constant,
- allocation_type type, MEMFLAGS flags) {
+ allocation_type type, MEMFLAGS flags) throw() {
return (address)operator new(size, nothrow_constant, type, flags);
}
@@ -370,7 +370,7 @@
//--------------------------------------------------------------------------------------
// Chunk implementation
-void* Chunk::operator new (size_t requested_size, AllocFailType alloc_failmode, size_t length) {
+void* Chunk::operator new (size_t requested_size, AllocFailType alloc_failmode, size_t length) throw() {
// requested_size is equal to sizeof(Chunk) but in order for the arena
// allocations to come out aligned as expected the size must be aligned
// to expected arena alignment.
@@ -478,18 +478,18 @@
NOT_PRODUCT(Atomic::dec(&_instance_count);)
}
-void* Arena::operator new(size_t size) {
+void* Arena::operator new(size_t size) throw() {
assert(false, "Use dynamic memory type binding");
return NULL;
}
-void* Arena::operator new (size_t size, const std::nothrow_t& nothrow_constant) {
+void* Arena::operator new (size_t size, const std::nothrow_t& nothrow_constant) throw() {
assert(false, "Use dynamic memory type binding");
return NULL;
}
// dynamic memory type binding
-void* Arena::operator new(size_t size, MEMFLAGS flags) {
+void* Arena::operator new(size_t size, MEMFLAGS flags) throw() {
#ifdef ASSERT
void* p = (void*)AllocateHeap(size, flags|otArena, CALLER_PC);
if (PrintMallocFree) trace_heap_malloc(size, "Arena-new", p);
@@ -499,7 +499,7 @@
#endif
}
-void* Arena::operator new(size_t size, const std::nothrow_t& nothrow_constant, MEMFLAGS flags) {
+void* Arena::operator new(size_t size, const std::nothrow_t& nothrow_constant, MEMFLAGS flags) throw() {
#ifdef ASSERT
void* p = os::malloc(size, flags|otArena, CALLER_PC);
if (PrintMallocFree) trace_heap_malloc(size, "Arena-new", p);
@@ -688,22 +688,22 @@
// define ALLOW_OPERATOR_NEW_USAGE for platform on which global operator new allowed.
//
#ifndef ALLOW_OPERATOR_NEW_USAGE
-void* operator new(size_t size){
+void* operator new(size_t size) throw() {
assert(false, "Should not call global operator new");
return 0;
}
-void* operator new [](size_t size){
+void* operator new [](size_t size) throw() {
assert(false, "Should not call global operator new[]");
return 0;
}
-void* operator new(size_t size, const std::nothrow_t& nothrow_constant){
+void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() {
assert(false, "Should not call global operator new");
return 0;
}
-void* operator new [](size_t size, std::nothrow_t& nothrow_constant){
+void* operator new [](size_t size, std::nothrow_t& nothrow_constant) throw() {
assert(false, "Should not call global operator new[]");
return 0;
}
--- a/hotspot/src/share/vm/memory/allocation.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/memory/allocation.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -204,12 +204,12 @@
template <MEMFLAGS F> class CHeapObj ALLOCATION_SUPER_CLASS_SPEC {
public:
- _NOINLINE_ void* operator new(size_t size, address caller_pc = 0);
+ _NOINLINE_ void* operator new(size_t size, address caller_pc = 0) throw();
_NOINLINE_ void* operator new (size_t size, const std::nothrow_t& nothrow_constant,
- address caller_pc = 0);
- _NOINLINE_ void* operator new [](size_t size, address caller_pc = 0);
+ address caller_pc = 0) throw();
+ _NOINLINE_ void* operator new [](size_t size, address caller_pc = 0) throw();
_NOINLINE_ void* operator new [](size_t size, const std::nothrow_t& nothrow_constant,
- address caller_pc = 0);
+ address caller_pc = 0) throw();
void operator delete(void* p);
void operator delete [] (void* p);
};
@@ -219,9 +219,9 @@
class StackObj ALLOCATION_SUPER_CLASS_SPEC {
private:
- void* operator new(size_t size);
+ void* operator new(size_t size) throw();
void operator delete(void* p);
- void* operator new [](size_t size);
+ void* operator new [](size_t size) throw();
void operator delete [](void* p);
};
@@ -245,9 +245,9 @@
//
class _ValueObj {
private:
- void* operator new(size_t size);
+ void* operator new(size_t size) throw();
void operator delete(void* p);
- void* operator new [](size_t size);
+ void* operator new [](size_t size) throw();
void operator delete [](void* p);
};
@@ -316,7 +316,7 @@
void* operator new(size_t size, ClassLoaderData* loader_data,
size_t word_size, bool read_only,
- Type type, Thread* thread);
+ Type type, Thread* thread) throw();
// can't use TRAPS from this header file.
void operator delete(void* p) { ShouldNotCallThis(); }
};
@@ -339,7 +339,7 @@
Chunk* _next; // Next Chunk in list
const size_t _len; // Size of this Chunk
public:
- void* operator new(size_t size, AllocFailType alloc_failmode, size_t length);
+ void* operator new(size_t size, AllocFailType alloc_failmode, size_t length) throw();
void operator delete(void* p);
Chunk(size_t length);
@@ -422,12 +422,12 @@
char* hwm() const { return _hwm; }
// new operators
- void* operator new (size_t size);
- void* operator new (size_t size, const std::nothrow_t& nothrow_constant);
+ void* operator new (size_t size) throw();
+ void* operator new (size_t size, const std::nothrow_t& nothrow_constant) throw();
// dynamic memory type tagging
- void* operator new(size_t size, MEMFLAGS flags);
- void* operator new(size_t size, const std::nothrow_t& nothrow_constant, MEMFLAGS flags);
+ void* operator new(size_t size, MEMFLAGS flags) throw();
+ void* operator new(size_t size, const std::nothrow_t& nothrow_constant, MEMFLAGS flags) throw();
void operator delete(void* p);
// Fast allocate in the arena. Common case is: pointer test + increment.
@@ -583,44 +583,44 @@
#endif // ASSERT
public:
- void* operator new(size_t size, allocation_type type, MEMFLAGS flags);
- void* operator new [](size_t size, allocation_type type, MEMFLAGS flags);
+ void* operator new(size_t size, allocation_type type, MEMFLAGS flags) throw();
+ void* operator new [](size_t size, allocation_type type, MEMFLAGS flags) throw();
void* operator new(size_t size, const std::nothrow_t& nothrow_constant,
- allocation_type type, MEMFLAGS flags);
+ allocation_type type, MEMFLAGS flags) throw();
void* operator new [](size_t size, const std::nothrow_t& nothrow_constant,
- allocation_type type, MEMFLAGS flags);
+ allocation_type type, MEMFLAGS flags) throw();
- void* operator new(size_t size, Arena *arena) {
+ void* operator new(size_t size, Arena *arena) throw() {
address res = (address)arena->Amalloc(size);
DEBUG_ONLY(set_allocation_type(res, ARENA);)
return res;
}
- void* operator new [](size_t size, Arena *arena) {
+ void* operator new [](size_t size, Arena *arena) throw() {
address res = (address)arena->Amalloc(size);
DEBUG_ONLY(set_allocation_type(res, ARENA);)
return res;
}
- void* operator new(size_t size) {
+ void* operator new(size_t size) throw() {
address res = (address)resource_allocate_bytes(size);
DEBUG_ONLY(set_allocation_type(res, RESOURCE_AREA);)
return res;
}
- void* operator new(size_t size, const std::nothrow_t& nothrow_constant) {
+ void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() {
address res = (address)resource_allocate_bytes(size, AllocFailStrategy::RETURN_NULL);
DEBUG_ONLY(if (res != NULL) set_allocation_type(res, RESOURCE_AREA);)
return res;
}
- void* operator new [](size_t size) {
+ void* operator new [](size_t size) throw() {
address res = (address)resource_allocate_bytes(size);
DEBUG_ONLY(set_allocation_type(res, RESOURCE_AREA);)
return res;
}
- void* operator new [](size_t size, const std::nothrow_t& nothrow_constant) {
+ void* operator new [](size_t size, const std::nothrow_t& nothrow_constant) throw() {
address res = (address)resource_allocate_bytes(size, AllocFailStrategy::RETURN_NULL);
DEBUG_ONLY(if (res != NULL) set_allocation_type(res, RESOURCE_AREA);)
return res;
--- a/hotspot/src/share/vm/memory/allocation.inline.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/memory/allocation.inline.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -85,7 +85,7 @@
template <MEMFLAGS F> void* CHeapObj<F>::operator new(size_t size,
- address caller_pc){
+ address caller_pc) throw() {
void* p = (void*)AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC));
#ifdef ASSERT
if (PrintMallocFree) trace_heap_malloc(size, "CHeapObj-new", p);
@@ -94,7 +94,7 @@
}
template <MEMFLAGS F> void* CHeapObj<F>::operator new (size_t size,
- const std::nothrow_t& nothrow_constant, address caller_pc) {
+ const std::nothrow_t& nothrow_constant, address caller_pc) throw() {
void* p = (void*)AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC),
AllocFailStrategy::RETURN_NULL);
#ifdef ASSERT
@@ -104,12 +104,12 @@
}
template <MEMFLAGS F> void* CHeapObj<F>::operator new [](size_t size,
- address caller_pc){
+ address caller_pc) throw() {
return CHeapObj<F>::operator new(size, caller_pc);
}
template <MEMFLAGS F> void* CHeapObj<F>::operator new [](size_t size,
- const std::nothrow_t& nothrow_constant, address caller_pc) {
+ const std::nothrow_t& nothrow_constant, address caller_pc) throw() {
return CHeapObj<F>::operator new(size, nothrow_constant, caller_pc);
}
--- a/hotspot/src/share/vm/memory/filemap.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/memory/filemap.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -55,6 +55,7 @@
" shared archive file.\n");
jio_vfprintf(defaultStream::error_stream(), msg, ap);
jio_fprintf(defaultStream::error_stream(), "\n");
+ // Do not change the text of the below message because some tests check for it.
vm_exit_during_initialization("Unable to use shared archive.", NULL);
}
--- a/hotspot/src/share/vm/memory/memRegion.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/memory/memRegion.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, 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
@@ -102,11 +102,11 @@
return MemRegion();
}
-void* MemRegion::operator new(size_t size) {
+void* MemRegion::operator new(size_t size) throw() {
return (address)AllocateHeap(size, mtGC, 0, AllocFailStrategy::RETURN_NULL);
}
-void* MemRegion::operator new [](size_t size) {
+void* MemRegion::operator new [](size_t size) throw() {
return (address)AllocateHeap(size, mtGC, 0, AllocFailStrategy::RETURN_NULL);
}
void MemRegion::operator delete(void* p) {
--- a/hotspot/src/share/vm/memory/memRegion.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/memory/memRegion.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -94,8 +94,8 @@
size_t word_size() const { return _word_size; }
bool is_empty() const { return word_size() == 0; }
- void* operator new(size_t size);
- void* operator new [](size_t size);
+ void* operator new(size_t size) throw();
+ void* operator new [](size_t size) throw();
void operator delete(void* p);
void operator delete [](void* p);
};
@@ -111,13 +111,13 @@
class MemRegionClosureRO: public MemRegionClosure {
public:
- void* operator new(size_t size, ResourceObj::allocation_type type, MEMFLAGS flags) {
+ void* operator new(size_t size, ResourceObj::allocation_type type, MEMFLAGS flags) throw() {
return ResourceObj::operator new(size, type, flags);
}
- void* operator new(size_t size, Arena *arena) {
+ void* operator new(size_t size, Arena *arena) throw() {
return ResourceObj::operator new(size, arena);
}
- void* operator new(size_t size) {
+ void* operator new(size_t size) throw() {
return ResourceObj::operator new(size);
}
--- a/hotspot/src/share/vm/oops/fieldInfo.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/oops/fieldInfo.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -240,6 +240,14 @@
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);
--- a/hotspot/src/share/vm/oops/klass.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/oops/klass.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -139,7 +139,7 @@
return NULL;
}
-void* Klass::operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) {
+void* Klass::operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) throw() {
return Metaspace::allocate(loader_data, word_size, /*read_only*/false,
MetaspaceObj::ClassType, CHECK_NULL);
}
--- a/hotspot/src/share/vm/oops/klass.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/oops/klass.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -179,7 +179,7 @@
// Constructor
Klass();
- void* operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS);
+ void* operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) throw();
public:
bool is_klass() const volatile { return true; }
--- a/hotspot/src/share/vm/oops/method.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/oops/method.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -720,11 +720,22 @@
}
}
+bool Method::is_always_compilable() const {
+ // Generated adapters must be compiled
+ if (is_method_handle_intrinsic() && is_synthetic()) {
+ assert(!is_not_c1_compilable(), "sanity check");
+ assert(!is_not_c2_compilable(), "sanity check");
+ return true;
+ }
+
+ return false;
+}
+
bool Method::is_not_compilable(int comp_level) const {
if (number_of_breakpoints() > 0)
return true;
- if (is_method_handle_intrinsic())
- return !is_synthetic(); // the generated adapters must be compiled
+ if (is_always_compilable())
+ return false;
if (comp_level == CompLevel_any)
return is_not_c1_compilable() || is_not_c2_compilable();
if (is_c1_compile(comp_level))
@@ -736,6 +747,10 @@
// call this when compiler finds that this method is not compilable
void Method::set_not_compilable(int comp_level, bool report, const char* reason) {
+ if (is_always_compilable()) {
+ // Don't mark a method which should be always compilable
+ return;
+ }
print_made_not_compilable(comp_level, /*is_osr*/ false, report, reason);
if (comp_level == CompLevel_all) {
set_not_c1_compilable();
--- a/hotspot/src/share/vm/oops/method.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/oops/method.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -796,6 +796,7 @@
void set_not_osr_compilable_quietly(int comp_level = CompLevel_all) {
set_not_osr_compilable(comp_level, false);
}
+ bool is_always_compilable() const;
private:
void print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason);
--- a/hotspot/src/share/vm/oops/symbol.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/oops/symbol.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -41,19 +41,19 @@
}
}
-void* Symbol::operator new(size_t sz, int len, TRAPS) {
+void* Symbol::operator new(size_t sz, int len, TRAPS) throw() {
int alloc_size = size(len)*HeapWordSize;
address res = (address) AllocateHeap(alloc_size, mtSymbol);
return res;
}
-void* Symbol::operator new(size_t sz, int len, Arena* arena, TRAPS) {
+void* Symbol::operator new(size_t sz, int len, Arena* arena, TRAPS) throw() {
int alloc_size = size(len)*HeapWordSize;
address res = (address)arena->Amalloc(alloc_size);
return res;
}
-void* Symbol::operator new(size_t sz, int len, ClassLoaderData* loader_data, TRAPS) {
+void* Symbol::operator new(size_t sz, int len, ClassLoaderData* loader_data, TRAPS) throw() {
address res;
int alloc_size = size(len)*HeapWordSize;
res = (address) Metaspace::allocate(loader_data, size(len), true,
--- a/hotspot/src/share/vm/oops/symbol.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/oops/symbol.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -136,9 +136,9 @@
}
Symbol(const u1* name, int length, int refcount);
- void* operator new(size_t size, int len, TRAPS);
- void* operator new(size_t size, int len, Arena* arena, TRAPS);
- void* operator new(size_t size, int len, ClassLoaderData* loader_data, TRAPS);
+ void* operator new(size_t size, int len, TRAPS) throw();
+ void* operator new(size_t size, int len, Arena* arena, TRAPS) throw();
+ void* operator new(size_t size, int len, ClassLoaderData* loader_data, TRAPS) throw();
void operator delete(void* p);
--- a/hotspot/src/share/vm/opto/block.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/block.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -112,9 +112,9 @@
// exceeds OptoLoopAlignment.
uint Block::compute_first_inst_size(uint& sum_size, uint inst_cnt,
PhaseRegAlloc* ra) {
- uint last_inst = _nodes.size();
+ uint last_inst = number_of_nodes();
for( uint j = 0; j < last_inst && inst_cnt > 0; j++ ) {
- uint inst_size = _nodes[j]->size(ra);
+ uint inst_size = get_node(j)->size(ra);
if( inst_size > 0 ) {
inst_cnt--;
uint sz = sum_size + inst_size;
@@ -131,8 +131,8 @@
}
uint Block::find_node( const Node *n ) const {
- for( uint i = 0; i < _nodes.size(); i++ ) {
- if( _nodes[i] == n )
+ for( uint i = 0; i < number_of_nodes(); i++ ) {
+ if( get_node(i) == n )
return i;
}
ShouldNotReachHere();
@@ -141,7 +141,7 @@
// Find and remove n from block list
void Block::find_remove( const Node *n ) {
- _nodes.remove(find_node(n));
+ remove_node(find_node(n));
}
// Return empty status of a block. Empty blocks contain only the head, other
@@ -154,10 +154,10 @@
}
int success_result = completely_empty;
- int end_idx = _nodes.size()-1;
+ int end_idx = number_of_nodes() - 1;
// Check for ending goto
- if ((end_idx > 0) && (_nodes[end_idx]->is_MachGoto())) {
+ if ((end_idx > 0) && (get_node(end_idx)->is_MachGoto())) {
success_result = empty_with_goto;
end_idx--;
}
@@ -170,7 +170,7 @@
// Ideal nodes are allowable in empty blocks: skip them Only MachNodes
// turn directly into code, because only MachNodes have non-trivial
// emit() functions.
- while ((end_idx > 0) && !_nodes[end_idx]->is_Mach()) {
+ while ((end_idx > 0) && !get_node(end_idx)->is_Mach()) {
end_idx--;
}
@@ -209,15 +209,15 @@
// True if block is low enough frequency or guarded by a test which
// mostly does not go here.
-bool Block::is_uncommon(PhaseCFG* cfg) const {
+bool PhaseCFG::is_uncommon(const Block* block) {
// Initial blocks must never be moved, so are never uncommon.
- if (head()->is_Root() || head()->is_Start()) return false;
+ if (block->head()->is_Root() || block->head()->is_Start()) return false;
// Check for way-low freq
- if( _freq < BLOCK_FREQUENCY(0.00001f) ) return true;
+ if(block->_freq < BLOCK_FREQUENCY(0.00001f) ) return true;
// Look for code shape indicating uncommon_trap or slow path
- if (has_uncommon_code()) return true;
+ if (block->has_uncommon_code()) return true;
const float epsilon = 0.05f;
const float guard_factor = PROB_UNLIKELY_MAG(4) / (1.f - epsilon);
@@ -225,8 +225,8 @@
uint freq_preds = 0;
uint uncommon_for_freq_preds = 0;
- for( uint i=1; i<num_preds(); i++ ) {
- Block* guard = cfg->get_block_for_node(pred(i));
+ for( uint i=1; i< block->num_preds(); i++ ) {
+ Block* guard = get_block_for_node(block->pred(i));
// Check to see if this block follows its guard 1 time out of 10000
// or less.
//
@@ -244,14 +244,14 @@
uncommon_preds++;
} else {
freq_preds++;
- if( _freq < guard->_freq * guard_factor ) {
+ if(block->_freq < guard->_freq * guard_factor ) {
uncommon_for_freq_preds++;
}
}
}
- if( num_preds() > 1 &&
+ if( block->num_preds() > 1 &&
// The block is uncommon if all preds are uncommon or
- (uncommon_preds == (num_preds()-1) ||
+ (uncommon_preds == (block->num_preds()-1) ||
// it is uncommon for all frequent preds.
uncommon_for_freq_preds == freq_preds) ) {
return true;
@@ -344,8 +344,8 @@
void Block::dump(const PhaseCFG* cfg) const {
dump_head(cfg);
- for (uint i=0; i< _nodes.size(); i++) {
- _nodes[i]->dump();
+ for (uint i=0; i< number_of_nodes(); i++) {
+ get_node(i)->dump();
}
tty->print("\n");
}
@@ -434,7 +434,7 @@
map_node_to_block(p, bb);
map_node_to_block(x, bb);
if( x != p ) { // Only for root is x == p
- bb->_nodes.push((Node*)x);
+ bb->push_node((Node*)x);
}
// Now handle predecessors
++sum; // Count 1 for self block
@@ -469,11 +469,11 @@
assert( x != proj, "" );
// Map basic block of projection
map_node_to_block(proj, pb);
- pb->_nodes.push(proj);
+ pb->push_node(proj);
}
// Insert self as a child of my predecessor block
pb->_succs.map(pb->_num_succs++, get_block_for_node(np));
- assert( pb->_nodes[ pb->_nodes.size() - pb->_num_succs ]->is_block_proj(),
+ assert( pb->get_node(pb->number_of_nodes() - pb->_num_succs)->is_block_proj(),
"too many control users, not a CFG?" );
}
}
@@ -495,7 +495,7 @@
// surrounding blocks.
float freq = in->_freq * in->succ_prob(succ_no);
// get ProjNode corresponding to the succ_no'th successor of the in block
- ProjNode* proj = in->_nodes[in->_nodes.size() - in->_num_succs + succ_no]->as_Proj();
+ ProjNode* proj = in->get_node(in->number_of_nodes() - in->_num_succs + succ_no)->as_Proj();
// create region for basic block
RegionNode* region = new (C) RegionNode(2);
region->init_req(1, proj);
@@ -507,7 +507,7 @@
Node* gto = _goto->clone(); // get a new goto node
gto->set_req(0, region);
// add it to the basic block
- block->_nodes.push(gto);
+ block->push_node(gto);
map_node_to_block(gto, block);
C->regalloc()->set_bad(gto->_idx);
// hook up successor block
@@ -527,9 +527,9 @@
// Does this block end in a multiway branch that cannot have the default case
// flipped for another case?
static bool no_flip_branch( Block *b ) {
- int branch_idx = b->_nodes.size() - b->_num_succs-1;
+ int branch_idx = b->number_of_nodes() - b->_num_succs-1;
if( branch_idx < 1 ) return false;
- Node *bra = b->_nodes[branch_idx];
+ Node *bra = b->get_node(branch_idx);
if( bra->is_Catch() )
return true;
if( bra->is_Mach() ) {
@@ -550,16 +550,16 @@
void PhaseCFG::convert_NeverBranch_to_Goto(Block *b) {
// Find true target
int end_idx = b->end_idx();
- int idx = b->_nodes[end_idx+1]->as_Proj()->_con;
+ int idx = b->get_node(end_idx+1)->as_Proj()->_con;
Block *succ = b->_succs[idx];
Node* gto = _goto->clone(); // get a new goto node
gto->set_req(0, b->head());
- Node *bp = b->_nodes[end_idx];
- b->_nodes.map(end_idx,gto); // Slam over NeverBranch
+ Node *bp = b->get_node(end_idx);
+ b->map_node(gto, end_idx); // Slam over NeverBranch
map_node_to_block(gto, b);
C->regalloc()->set_bad(gto->_idx);
- b->_nodes.pop(); // Yank projections
- b->_nodes.pop(); // Yank projections
+ b->pop_node(); // Yank projections
+ b->pop_node(); // Yank projections
b->_succs.map(0,succ); // Map only successor
b->_num_succs = 1;
// remap successor's predecessors if necessary
@@ -575,8 +575,8 @@
// Scan through block, yanking dead path from
// all regions and phis.
dead->head()->del_req(j);
- for( int k = 1; dead->_nodes[k]->is_Phi(); k++ )
- dead->_nodes[k]->del_req(j);
+ for( int k = 1; dead->get_node(k)->is_Phi(); k++ )
+ dead->get_node(k)->del_req(j);
}
// Helper function to move block bx to the slot following b_index. Return
@@ -620,7 +620,7 @@
if (e != Block::not_empty) {
if (e == Block::empty_with_goto) {
// Remove the goto, but leave the block.
- b->_nodes.pop();
+ b->pop_node();
}
// Mark this block as a connector block, which will cause it to be
// ignored in certain functions such as non_connector_successor().
@@ -663,13 +663,13 @@
// to give a fake exit path to infinite loops. At this late stage they
// need to turn into Goto's so that when you enter the infinite loop you
// indeed hang.
- if (block->_nodes[block->end_idx()]->Opcode() == Op_NeverBranch) {
+ if (block->get_node(block->end_idx())->Opcode() == Op_NeverBranch) {
convert_NeverBranch_to_Goto(block);
}
// Look for uncommon blocks and move to end.
if (!C->do_freq_based_layout()) {
- if (block->is_uncommon(this)) {
+ if (is_uncommon(block)) {
move_to_end(block, i);
last--; // No longer check for being uncommon!
if (no_flip_branch(block)) { // Fall-thru case must follow?
@@ -720,9 +720,9 @@
// exchange the true and false targets.
if (no_flip_branch(block)) {
// Find fall through case - if must fall into its target
- int branch_idx = block->_nodes.size() - block->_num_succs;
+ int branch_idx = block->number_of_nodes() - block->_num_succs;
for (uint j2 = 0; j2 < block->_num_succs; j2++) {
- const ProjNode* p = block->_nodes[branch_idx + j2]->as_Proj();
+ const ProjNode* p = block->get_node(branch_idx + j2)->as_Proj();
if (p->_con == 0) {
// successor j2 is fall through case
if (block->non_connector_successor(j2) != bnext) {
@@ -743,14 +743,14 @@
// Remove all CatchProjs
for (uint j = 0; j < block->_num_succs; j++) {
- block->_nodes.pop();
+ block->pop_node();
}
} else if (block->_num_succs == 1) {
// Block ends in a Goto?
if (bnext == bs0) {
// We fall into next block; remove the Goto
- block->_nodes.pop();
+ block->pop_node();
}
} else if(block->_num_succs == 2) { // Block ends in a If?
@@ -759,9 +759,9 @@
// be projections (in any order), the 3rd last node must be
// the IfNode (we have excluded other 2-way exits such as
// CatchNodes already).
- MachNode* iff = block->_nodes[block->_nodes.size() - 3]->as_Mach();
- ProjNode* proj0 = block->_nodes[block->_nodes.size() - 2]->as_Proj();
- ProjNode* proj1 = block->_nodes[block->_nodes.size() - 1]->as_Proj();
+ MachNode* iff = block->get_node(block->number_of_nodes() - 3)->as_Mach();
+ ProjNode* proj0 = block->get_node(block->number_of_nodes() - 2)->as_Proj();
+ ProjNode* proj1 = block->get_node(block->number_of_nodes() - 1)->as_Proj();
// Assert that proj0 and succs[0] match up. Similarly for proj1 and succs[1].
assert(proj0->raw_out(0) == block->_succs[0]->head(), "Mismatch successor 0");
@@ -833,8 +833,8 @@
iff->as_MachIf()->negate();
}
- block->_nodes.pop(); // Remove IfFalse & IfTrue projections
- block->_nodes.pop();
+ block->pop_node(); // Remove IfFalse & IfTrue projections
+ block->pop_node();
} else {
// Multi-exit block, e.g. a switch statement
@@ -895,13 +895,13 @@
// Verify sane CFG
for (uint i = 0; i < number_of_blocks(); i++) {
Block* block = get_block(i);
- uint cnt = block->_nodes.size();
+ uint cnt = block->number_of_nodes();
uint j;
for (j = 0; j < cnt; j++) {
- Node *n = block->_nodes[j];
+ Node *n = block->get_node(j);
assert(get_block_for_node(n) == block, "");
if (j >= 1 && n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx) {
- assert(j == 1 || block->_nodes[j-1]->is_Phi(), "CreateEx must be first instruction in block");
+ assert(j == 1 || block->get_node(j-1)->is_Phi(), "CreateEx must be first instruction in block");
}
for (uint k = 0; k < n->req(); k++) {
Node *def = n->in(k);
@@ -930,14 +930,14 @@
}
j = block->end_idx();
- Node* bp = (Node*)block->_nodes[block->_nodes.size() - 1]->is_block_proj();
+ Node* bp = (Node*)block->get_node(block->number_of_nodes() - 1)->is_block_proj();
assert(bp, "last instruction must be a block proj");
- assert(bp == block->_nodes[j], "wrong number of successors for this block");
+ assert(bp == block->get_node(j), "wrong number of successors for this block");
if (bp->is_Catch()) {
- while (block->_nodes[--j]->is_MachProj()) {
+ while (block->get_node(--j)->is_MachProj()) {
;
}
- assert(block->_nodes[j]->is_MachCall(), "CatchProj must follow call");
+ assert(block->get_node(j)->is_MachCall(), "CatchProj must follow call");
} else if (bp->is_Mach() && bp->as_Mach()->ideal_Opcode() == Op_If) {
assert(block->_num_succs == 2, "Conditional branch must have two targets");
}
@@ -1440,9 +1440,9 @@
Block *bnext = next(b);
Block *bs0 = b->non_connector_successor(0);
- MachNode *iff = b->_nodes[b->_nodes.size()-3]->as_Mach();
- ProjNode *proj0 = b->_nodes[b->_nodes.size()-2]->as_Proj();
- ProjNode *proj1 = b->_nodes[b->_nodes.size()-1]->as_Proj();
+ MachNode *iff = b->get_node(b->number_of_nodes() - 3)->as_Mach();
+ ProjNode *proj0 = b->get_node(b->number_of_nodes() - 2)->as_Proj();
+ ProjNode *proj1 = b->get_node(b->number_of_nodes() - 1)->as_Proj();
if (bnext == bs0) {
// Fall-thru case in succs[0], should be in succs[1]
@@ -1454,8 +1454,8 @@
b->_succs.map( 1, tbs0 );
// Flip projections to match targets
- b->_nodes.map(b->_nodes.size()-2, proj1);
- b->_nodes.map(b->_nodes.size()-1, proj0);
+ b->map_node(proj1, b->number_of_nodes() - 2);
+ b->map_node(proj0, b->number_of_nodes() - 1);
}
}
}
--- a/hotspot/src/share/vm/opto/block.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/block.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -105,15 +105,53 @@
// any optimization pass. They are created late in the game.
class Block : public CFGElement {
friend class VMStructs;
- public:
+
+private:
// Nodes in this block, in order
Node_List _nodes;
+public:
+
+ // Get the node at index 'at_index', if 'at_index' is out of bounds return NULL
+ Node* get_node(uint at_index) const {
+ return _nodes[at_index];
+ }
+
+ // Get the number of nodes in this block
+ uint number_of_nodes() const {
+ return _nodes.size();
+ }
+
+ // Map a node 'node' to index 'to_index' in the block, if the index is out of bounds the size of the node list is increased
+ void map_node(Node* node, uint to_index) {
+ _nodes.map(to_index, node);
+ }
+
+ // Insert a node 'node' at index 'at_index', moving all nodes that are on a higher index one step, if 'at_index' is out of bounds we crash
+ void insert_node(Node* node, uint at_index) {
+ _nodes.insert(at_index, node);
+ }
+
+ // Remove a node at index 'at_index'
+ void remove_node(uint at_index) {
+ _nodes.remove(at_index);
+ }
+
+ // Push a node 'node' onto the node list
+ void push_node(Node* node) {
+ _nodes.push(node);
+ }
+
+ // Pop the last node off the node list
+ Node* pop_node() {
+ return _nodes.pop();
+ }
+
// Basic blocks have a Node which defines Control for all Nodes pinned in
// this block. This Node is a RegionNode. Exception-causing Nodes
// (division, subroutines) and Phi functions are always pinned. Later,
// every Node will get pinned to some block.
- Node *head() const { return _nodes[0]; }
+ Node *head() const { return get_node(0); }
// CAUTION: num_preds() is ONE based, so that predecessor numbers match
// input edges to Regions and Phis.
@@ -274,29 +312,12 @@
// Add an instruction to an existing block. It must go after the head
// instruction and before the end instruction.
- void add_inst( Node *n ) { _nodes.insert(end_idx(),n); }
+ void add_inst( Node *n ) { insert_node(n, end_idx()); }
// Find node in block
uint find_node( const Node *n ) const;
// Find and remove n from block list
void find_remove( const Node *n );
- // helper function that adds caller save registers to MachProjNode
- void add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_policy, bool exclude_soe);
- // Schedule a call next in the block
- uint sched_call(Matcher &matcher, PhaseCFG* cfg, uint node_cnt, Node_List &worklist, GrowableArray<int> &ready_cnt, MachCallNode *mcall, VectorSet &next_call);
-
- // Perform basic-block local scheduling
- Node *select(PhaseCFG *cfg, Node_List &worklist, GrowableArray<int> &ready_cnt, VectorSet &next_call, uint sched_slot);
- void set_next_call( Node *n, VectorSet &next_call, PhaseCFG* cfg);
- void needed_for_next_call(Node *this_call, VectorSet &next_call, PhaseCFG* cfg);
- bool schedule_local(PhaseCFG *cfg, Matcher &m, GrowableArray<int> &ready_cnt, VectorSet &next_call);
- // Cleanup if any code lands between a Call and his Catch
- void call_catch_cleanup(PhaseCFG* cfg, Compile *C);
- // Detect implicit-null-check opportunities. Basically, find NULL checks
- // with suitable memory ops nearby. Use the memory op to do the NULL check.
- // I can generate a memory op if there is not one nearby.
- void implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowed_reasons);
-
// Return the empty status of a block
enum { not_empty, empty_with_goto, completely_empty };
int is_Empty() const;
@@ -328,10 +349,6 @@
// Examine block's code shape to predict if it is not commonly executed.
bool has_uncommon_code() const;
- // Use frequency calculations and code shape to predict if the block
- // is uncommon.
- bool is_uncommon(PhaseCFG* cfg) const;
-
#ifndef PRODUCT
// Debugging print of basic block
void dump_bidx(const Block* orig, outputStream* st = tty) const;
@@ -414,6 +431,27 @@
// to late. Helper for schedule_late.
Block* hoist_to_cheaper_block(Block* LCA, Block* early, Node* self);
+ bool schedule_local(Block* block, GrowableArray<int>& ready_cnt, VectorSet& next_call);
+ void set_next_call(Block* block, Node* n, VectorSet& next_call);
+ void needed_for_next_call(Block* block, Node* this_call, VectorSet& next_call);
+
+ // Perform basic-block local scheduling
+ Node* select(Block* block, Node_List& worklist, GrowableArray<int>& ready_cnt, VectorSet& next_call, uint sched_slot);
+
+ // Schedule a call next in the block
+ uint sched_call(Block* block, uint node_cnt, Node_List& worklist, GrowableArray<int>& ready_cnt, MachCallNode* mcall, VectorSet& next_call);
+
+ // Cleanup if any code lands between a Call and his Catch
+ void call_catch_cleanup(Block* block);
+
+ Node* catch_cleanup_find_cloned_def(Block* use_blk, Node* def, Block* def_blk, int n_clone_idx);
+ void catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, int n_clone_idx);
+
+ // Detect implicit-null-check opportunities. Basically, find NULL checks
+ // with suitable memory ops nearby. Use the memory op to do the NULL check.
+ // I can generate a memory op if there is not one nearby.
+ void implicit_null_check(Block* block, Node *proj, Node *val, int allowed_reasons);
+
// Perform a Depth First Search (DFS).
// Setup 'vertex' as DFS to vertex mapping.
// Setup 'semi' as vertex to DFS mapping.
@@ -530,6 +568,10 @@
return (_node_to_block_mapping.lookup(node->_idx) != NULL);
}
+ // Use frequency calculations and code shape to predict if the block
+ // is uncommon.
+ bool is_uncommon(const Block* block);
+
#ifdef ASSERT
Unique_Node_List _raw_oops;
#endif
@@ -550,7 +592,7 @@
// Insert a node into a block at index and map the node to the block
void insert(Block *b, uint idx, Node *n) {
- b->_nodes.insert( idx, n );
+ b->insert_node(n , idx);
map_node_to_block(n, b);
}
--- a/hotspot/src/share/vm/opto/buildOopMap.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/buildOopMap.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -121,8 +121,8 @@
// Given reaching-defs for this block start, compute it for this block end
void OopFlow::compute_reach( PhaseRegAlloc *regalloc, int max_reg, Dict *safehash ) {
- for( uint i=0; i<_b->_nodes.size(); i++ ) {
- Node *n = _b->_nodes[i];
+ for( uint i=0; i<_b->number_of_nodes(); i++ ) {
+ Node *n = _b->get_node(i);
if( n->jvms() ) { // Build an OopMap here?
JVMState *jvms = n->jvms();
@@ -447,8 +447,8 @@
}
// Now walk tmp_live up the block backwards, computing live
- for( int k=b->_nodes.size()-1; k>=0; k-- ) {
- Node *n = b->_nodes[k];
+ for( int k=b->number_of_nodes()-1; k>=0; k-- ) {
+ Node *n = b->get_node(k);
// KILL def'd bits
int first = regalloc->get_reg_first(n);
int second = regalloc->get_reg_second(n);
@@ -544,12 +544,12 @@
for (i = 1; i < cfg->number_of_blocks(); i++) {
Block* block = cfg->get_block(i);
uint j;
- for (j = 1; j < block->_nodes.size(); j++) {
- if (block->_nodes[j]->jvms() && (*safehash)[block->_nodes[j]] == NULL) {
+ for (j = 1; j < block->number_of_nodes(); j++) {
+ if (block->get_node(j)->jvms() && (*safehash)[block->get_node(j)] == NULL) {
break;
}
}
- if (j < block->_nodes.size()) {
+ if (j < block->number_of_nodes()) {
break;
}
}
--- a/hotspot/src/share/vm/opto/c2_globals.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -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") \
\
--- a/hotspot/src/share/vm/opto/callGenerator.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/callGenerator.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -260,7 +260,7 @@
// Because WarmInfo objects live over the entire lifetime of the
// Compile object, they are allocated into the comp_arena, which
// does not get resource marked or reset during the compile process
- void *operator new( size_t x, Compile* C ) { return C->comp_arena()->Amalloc(x); }
+ void *operator new( size_t x, Compile* C ) throw() { return C->comp_arena()->Amalloc(x); }
void operator delete( void * ) { } // fast deallocation
static WarmCallInfo* always_hot();
--- a/hotspot/src/share/vm/opto/callnode.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/callnode.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -458,7 +458,7 @@
st->print("={");
uint nf = spobj->n_fields();
if (nf > 0) {
- uint first_ind = spobj->first_index();
+ uint first_ind = spobj->first_index(mcall->jvms());
Node* fld_node = mcall->in(first_ind);
ciField* cifield;
if (iklass != NULL) {
@@ -1063,7 +1063,6 @@
int scloff = jvms->scloff();
int endoff = jvms->endoff();
assert(endoff == (int)req(), "no other states or debug info after me");
- assert(jvms->scl_size() == 0, "parsed code should not have scalar objects");
Node* top = Compile::current()->top();
for (uint i = 0; i < grow_by; i++) {
ins_req(monoff, top);
@@ -1079,32 +1078,31 @@
const int MonitorEdges = 2;
assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges");
assert(req() == jvms()->endoff(), "correct sizing");
- assert((jvms()->scl_size() == 0), "parsed code should not have scalar objects");
int nextmon = jvms()->scloff();
if (GenerateSynchronizationCode) {
- add_req(lock->box_node());
- add_req(lock->obj_node());
+ ins_req(nextmon, lock->box_node());
+ ins_req(nextmon+1, lock->obj_node());
} else {
Node* top = Compile::current()->top();
- add_req(top);
- add_req(top);
+ ins_req(nextmon, top);
+ ins_req(nextmon, top);
}
- jvms()->set_scloff(nextmon+MonitorEdges);
+ jvms()->set_scloff(nextmon + MonitorEdges);
jvms()->set_endoff(req());
}
void SafePointNode::pop_monitor() {
// Delete last monitor from debug info
- assert((jvms()->scl_size() == 0), "parsed code should not have scalar objects");
debug_only(int num_before_pop = jvms()->nof_monitors());
- const int MonitorEdges = (1<<JVMState::logMonitorEdges);
+ const int MonitorEdges = 2;
+ assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges");
int scloff = jvms()->scloff();
int endoff = jvms()->endoff();
int new_scloff = scloff - MonitorEdges;
int new_endoff = endoff - MonitorEdges;
jvms()->set_scloff(new_scloff);
jvms()->set_endoff(new_endoff);
- while (scloff > new_scloff) del_req(--scloff);
+ while (scloff > new_scloff) del_req_ordered(--scloff);
assert(jvms()->nof_monitors() == num_before_pop-1, "");
}
@@ -1169,13 +1167,12 @@
}
SafePointScalarObjectNode*
-SafePointScalarObjectNode::clone(int jvms_adj, Dict* sosn_map) const {
+SafePointScalarObjectNode::clone(Dict* sosn_map) const {
void* cached = (*sosn_map)[(void*)this];
if (cached != NULL) {
return (SafePointScalarObjectNode*)cached;
}
SafePointScalarObjectNode* res = (SafePointScalarObjectNode*)Node::clone();
- res->_first_index += jvms_adj;
sosn_map->Insert((void*)this, (void*)res);
return res;
}
--- a/hotspot/src/share/vm/opto/callnode.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/callnode.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -216,7 +216,7 @@
// Because JVMState objects live over the entire lifetime of the
// Compile object, they are allocated into the comp_arena, which
// does not get resource marked or reset during the compile process
- void *operator new( size_t x, Compile* C ) { return C->comp_arena()->Amalloc(x); }
+ void *operator new( size_t x, Compile* C ) throw() { return C->comp_arena()->Amalloc(x); }
void operator delete( void * ) { } // fast deallocation
// Create a new JVMState, ready for abstract interpretation.
@@ -449,14 +449,17 @@
// at a safepoint.
class SafePointScalarObjectNode: public TypeNode {
- uint _first_index; // First input edge index of a SafePoint node where
+ uint _first_index; // First input edge relative index of a SafePoint node where
// states of the scalarized object fields are collected.
+ // It is relative to the last (youngest) jvms->_scloff.
uint _n_fields; // Number of non-static fields of the scalarized object.
DEBUG_ONLY(AllocateNode* _alloc;)
virtual uint hash() const ; // { return NO_HASH; }
virtual uint cmp( const Node &n ) const;
+ uint first_index() const { return _first_index; }
+
public:
SafePointScalarObjectNode(const TypeOopPtr* tp,
#ifdef ASSERT
@@ -469,7 +472,10 @@
virtual const RegMask &out_RegMask() const;
virtual uint match_edge(uint idx) const;
- uint first_index() const { return _first_index; }
+ uint first_index(JVMState* jvms) const {
+ assert(jvms != NULL, "missed JVMS");
+ return jvms->scloff() + _first_index;
+ }
uint n_fields() const { return _n_fields; }
#ifdef ASSERT
@@ -485,7 +491,7 @@
// corresponds appropriately to "this" in "new_call". Assumes that
// "sosn_map" is a map, specific to the translation of "s" to "new_call",
// mapping old SafePointScalarObjectNodes to new, to avoid multiple copies.
- SafePointScalarObjectNode* clone(int jvms_adj, Dict* sosn_map) const;
+ SafePointScalarObjectNode* clone(Dict* sosn_map) const;
#ifndef PRODUCT
virtual void dump_spec(outputStream *st) const;
--- a/hotspot/src/share/vm/opto/chaitin.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/chaitin.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -301,7 +301,7 @@
// Copy kill projections after the cloned node
Node* kills = proj->clone();
kills->set_req(0, copy);
- b->_nodes.insert(idx++, kills);
+ b->insert_node(kills, idx++);
_cfg.map_node_to_block(kills, b);
new_lrg(kills, max_lrg_id++);
}
@@ -682,11 +682,11 @@
uint lr_counter = 1;
for( uint i = 0; i < _cfg.number_of_blocks(); i++ ) {
Block* block = _cfg.get_block(i);
- uint cnt = block->_nodes.size();
+ uint cnt = block->number_of_nodes();
// Handle all the normal Nodes in the block
for( uint j = 0; j < cnt; j++ ) {
- Node *n = block->_nodes[j];
+ Node *n = block->get_node(j);
// Pre-color to the zero live range, or pick virtual register
const RegMask &rm = n->out_RegMask();
_lrg_map.map(n->_idx, rm.is_NotEmpty() ? lr_counter++ : 0);
@@ -710,8 +710,8 @@
Block* block = _cfg.get_block(i);
// For all instructions
- for (uint j = 1; j < block->_nodes.size(); j++) {
- Node* n = block->_nodes[j];
+ for (uint j = 1; j < block->number_of_nodes(); j++) {
+ Node* n = block->get_node(j);
uint input_edge_start =1; // Skip control most nodes
if (n->is_Mach()) {
input_edge_start = n->as_Mach()->oper_input_base();
@@ -1604,7 +1604,7 @@
// For all instructions in block
uint last_inst = block->end_idx();
for (uint j = 1; j <= last_inst; j++) {
- Node* n = block->_nodes[j];
+ Node* n = block->get_node(j);
// Dead instruction???
assert( n->outcnt() != 0 ||// Nothing dead after post alloc
@@ -1641,7 +1641,7 @@
assert( cisc->oper_input_base() == 2, "Only adding one edge");
cisc->ins_req(1,src); // Requires a memory edge
}
- block->_nodes.map(j,cisc); // Insert into basic block
+ block->map_node(cisc, j); // Insert into basic block
n->subsume_by(cisc, C); // Correct graph
//
++_used_cisc_instructions;
@@ -1698,7 +1698,7 @@
// (where top() node is placed).
base->init_req(0, _cfg.get_root_node());
Block *startb = _cfg.get_block_for_node(C->top());
- startb->_nodes.insert(startb->find_node(C->top()), base );
+ startb->insert_node(base, startb->find_node(C->top()));
_cfg.map_node_to_block(base, startb);
assert(_lrg_map.live_range_id(base) == 0, "should not have LRG yet");
}
@@ -1743,9 +1743,9 @@
// Search the current block for an existing base-Phi
Block *b = _cfg.get_block_for_node(derived);
for( i = 1; i <= b->end_idx(); i++ ) {// Search for matching Phi
- Node *phi = b->_nodes[i];
+ Node *phi = b->get_node(i);
if( !phi->is_Phi() ) { // Found end of Phis with no match?
- b->_nodes.insert( i, base ); // Must insert created Phi here as base
+ b->insert_node(base, i); // Must insert created Phi here as base
_cfg.map_node_to_block(base, b);
new_lrg(base,maxlrg++);
break;
@@ -1786,7 +1786,7 @@
IndexSet liveout(_live->live(block));
for (uint j = block->end_idx() + 1; j > 1; j--) {
- Node* n = block->_nodes[j - 1];
+ Node* n = block->get_node(j - 1);
// Pre-split compares of loop-phis. Loop-phis form a cycle we would
// like to see in the same register. Compare uses the loop-phi and so
@@ -1979,8 +1979,8 @@
b->dump_head(&_cfg);
// For all instructions
- for( uint j = 0; j < b->_nodes.size(); j++ )
- dump(b->_nodes[j]);
+ for( uint j = 0; j < b->number_of_nodes(); j++ )
+ dump(b->get_node(j));
// Print live-out info at end of block
if( _live ) {
tty->print("Liveout: ");
@@ -2271,8 +2271,8 @@
int dump_once = 0;
// For all instructions
- for( uint j = 0; j < block->_nodes.size(); j++ ) {
- Node *n = block->_nodes[j];
+ for( uint j = 0; j < block->number_of_nodes(); j++ ) {
+ Node *n = block->get_node(j);
if (_lrg_map.find_const(n) == lidx) {
if (!dump_once++) {
tty->cr();
--- a/hotspot/src/share/vm/opto/coalesce.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/coalesce.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -54,9 +54,9 @@
for( j=0; j<b->_num_succs; j++ )
tty->print("B%d ",b->_succs[j]->_pre_order);
tty->print(" IDom: B%d/#%d\n", b->_idom ? b->_idom->_pre_order : 0, b->_dom_depth);
- uint cnt = b->_nodes.size();
+ uint cnt = b->number_of_nodes();
for( j=0; j<cnt; j++ ) {
- Node *n = b->_nodes[j];
+ Node *n = b->get_node(j);
dump( n );
tty->print("\t%s\t",n->Name());
@@ -152,7 +152,7 @@
// after the last use. Last use is really first-use on a backwards scan.
uint i = b->end_idx()-1;
while(1) {
- Node *n = b->_nodes[i];
+ Node *n = b->get_node(i);
// Check for end of virtual copies; this is also the end of the
// parallel renaming effort.
if (n->_idx < _unique) {
@@ -174,7 +174,7 @@
// the last kill. Thus it is the first kill on a backwards scan.
i = b->end_idx()-1;
while (1) {
- Node *n = b->_nodes[i];
+ Node *n = b->get_node(i);
// Check for end of virtual copies; this is also the end of the
// parallel renaming effort.
if (n->_idx < _unique) {
@@ -200,13 +200,13 @@
tmp ->set_req(idx,copy->in(idx));
copy->set_req(idx,tmp);
// Save source in temp early, before source is killed
- b->_nodes.insert(kill_src_idx,tmp);
+ b->insert_node(tmp, kill_src_idx);
_phc._cfg.map_node_to_block(tmp, b);
last_use_idx++;
}
// Insert just after last use
- b->_nodes.insert(last_use_idx+1,copy);
+ b->insert_node(copy, last_use_idx + 1);
}
void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) {
@@ -237,8 +237,8 @@
Block *b = _phc._cfg.get_block(i);
uint cnt = b->num_preds(); // Number of inputs to the Phi
- for( uint l = 1; l<b->_nodes.size(); l++ ) {
- Node *n = b->_nodes[l];
+ for( uint l = 1; l<b->number_of_nodes(); l++ ) {
+ Node *n = b->get_node(l);
// Do not use removed-copies, use copied value instead
uint ncnt = n->req();
@@ -260,7 +260,7 @@
if (_phc._lrg_map.find(n) == _phc._lrg_map.find(def)) {
n->replace_by(def);
n->set_req(cidx,NULL);
- b->_nodes.remove(l);
+ b->remove_node(l);
l--;
continue;
}
@@ -321,13 +321,13 @@
m->as_Mach()->rematerialize()) {
copy = m->clone();
// Insert the copy in the basic block, just before us
- b->_nodes.insert(l++, copy);
+ b->insert_node(copy, l++);
l += _phc.clone_projs(b, l, m, copy, _phc._lrg_map);
} else {
const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()];
copy = new (C) MachSpillCopyNode(m, *rm, *rm);
// Insert the copy in the basic block, just before us
- b->_nodes.insert(l++, copy);
+ b->insert_node(copy, l++);
}
// Insert the copy in the use-def chain
n->set_req(idx, copy);
@@ -339,7 +339,7 @@
} // End of is two-adr
// Insert a copy at a debug use for a lrg which has high frequency
- if (b->_freq < OPTO_DEBUG_SPLIT_FREQ || b->is_uncommon(&_phc._cfg)) {
+ if (b->_freq < OPTO_DEBUG_SPLIT_FREQ || _phc._cfg.is_uncommon(b)) {
// Walk the debug inputs to the node and check for lrg freq
JVMState* jvms = n->jvms();
uint debug_start = jvms ? jvms->debug_start() : 999999;
@@ -376,7 +376,7 @@
// Insert the copy in the use-def chain
n->set_req(inpidx, copy );
// Insert the copy in the basic block, just before us
- b->_nodes.insert( l++, copy );
+ b->insert_node(copy, l++);
// Extend ("register allocate") the names array for the copy.
uint max_lrg_id = _phc._lrg_map.max_lrg_id();
_phc.new_lrg(copy, max_lrg_id);
@@ -431,8 +431,8 @@
}
// Visit all the Phis in successor block
- for( uint k = 1; k<bs->_nodes.size(); k++ ) {
- Node *n = bs->_nodes[k];
+ for( uint k = 1; k<bs->number_of_nodes(); k++ ) {
+ Node *n = bs->get_node(k);
if( !n->is_Phi() ) break;
combine_these_two( n, n->in(j) );
}
@@ -442,7 +442,7 @@
// Check _this_ block for 2-address instructions and copies.
uint cnt = b->end_idx();
for( i = 1; i<cnt; i++ ) {
- Node *n = b->_nodes[i];
+ Node *n = b->get_node(i);
uint idx;
// 2-address instructions have a virtual Copy matching their input
// to their output
@@ -490,10 +490,10 @@
dst_copy->set_req( didx, src_def );
// Add copy to free list
// _phc.free_spillcopy(b->_nodes[bindex]);
- assert( b->_nodes[bindex] == dst_copy, "" );
+ assert( b->get_node(bindex) == dst_copy, "" );
dst_copy->replace_by( dst_copy->in(didx) );
dst_copy->set_req( didx, NULL);
- b->_nodes.remove(bindex);
+ b->remove_node(bindex);
if( bindex < b->_ihrp_index ) b->_ihrp_index--;
if( bindex < b->_fhrp_index ) b->_fhrp_index--;
@@ -523,8 +523,8 @@
bindex2 = b2->end_idx()-1;
}
// Get prior instruction
- assert(bindex2 < b2->_nodes.size(), "index out of bounds");
- Node *x = b2->_nodes[bindex2];
+ assert(bindex2 < b2->number_of_nodes(), "index out of bounds");
+ Node *x = b2->get_node(bindex2);
if( x == prev_copy ) { // Previous copy in copy chain?
if( prev_copy == src_copy)// Found end of chain and all interferences
break; // So break out of loop
@@ -769,14 +769,14 @@
// Conservative (but pessimistic) copy coalescing of a single block
void PhaseConservativeCoalesce::coalesce( Block *b ) {
// Bail out on infrequent blocks
- if (b->is_uncommon(&_phc._cfg)) {
+ if (_phc._cfg.is_uncommon(b)) {
return;
}
// Check this block for copies.
for( uint i = 1; i<b->end_idx(); i++ ) {
// Check for actual copies on inputs. Coalesce a copy into its
// input if use and copy's input are compatible.
- Node *copy1 = b->_nodes[i];
+ Node *copy1 = b->get_node(i);
uint idx1 = copy1->is_Copy();
if( !idx1 ) continue; // Not a copy
--- a/hotspot/src/share/vm/opto/compile.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/compile.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -1297,6 +1297,10 @@
// 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 @@
_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 @@
&& 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 @@
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;
}
@@ -2258,7 +2273,7 @@
if (block->is_connector() && !Verbose) {
continue;
}
- n = block->_nodes[0];
+ n = block->head();
if (pcs && n->_idx < pc_limit) {
tty->print("%3.3x ", pcs[n->_idx]);
} else {
@@ -2273,12 +2288,12 @@
// For all instructions
Node *delay = NULL;
- for (uint j = 0; j < block->_nodes.size(); j++) {
+ for (uint j = 0; j < block->number_of_nodes(); j++) {
if (VMThread::should_terminate()) {
cut_short = true;
break;
}
- n = block->_nodes[j];
+ n = block->get_node(j);
if (valid_bundle_info(n)) {
Bundle* bundle = node_bundling(n);
if (bundle->used_in_unconditional_delay()) {
--- a/hotspot/src/share/vm/opto/compile.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/compile.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -72,6 +72,7 @@
class StartNode;
class SafePointNode;
class JVMState;
+class Type;
class TypeData;
class TypePtr;
class TypeOopPtr;
@@ -119,6 +120,7 @@
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 @@
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 @@
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;
--- a/hotspot/src/share/vm/opto/domgraph.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/domgraph.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -211,21 +211,21 @@
uint Block_Stack::most_frequent_successor( Block *b ) {
uint freq_idx = 0;
int eidx = b->end_idx();
- Node *n = b->_nodes[eidx];
+ Node *n = b->get_node(eidx);
int op = n->is_Mach() ? n->as_Mach()->ideal_Opcode() : n->Opcode();
switch( op ) {
case Op_CountedLoopEnd:
case Op_If: { // Split frequency amongst children
float prob = n->as_MachIf()->_prob;
// Is succ[0] the TRUE branch or the FALSE branch?
- if( b->_nodes[eidx+1]->Opcode() == Op_IfFalse )
+ if( b->get_node(eidx+1)->Opcode() == Op_IfFalse )
prob = 1.0f - prob;
freq_idx = prob < PROB_FAIR; // freq=1 for succ[0] < 0.5 prob
break;
}
case Op_Catch: // Split frequency amongst children
for( freq_idx = 0; freq_idx < b->_num_succs; freq_idx++ )
- if( b->_nodes[eidx+1+freq_idx]->as_CatchProj()->_con == CatchProjNode::fall_through_index )
+ if( b->get_node(eidx+1+freq_idx)->as_CatchProj()->_con == CatchProjNode::fall_through_index )
break;
// Handle case of no fall-thru (e.g., check-cast MUST throw an exception)
if( freq_idx == b->_num_succs ) freq_idx = 0;
--- a/hotspot/src/share/vm/opto/gcm.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/gcm.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -102,12 +102,12 @@
uint j = 0;
if (pb->_num_succs != 1) { // More then 1 successor?
// Search for successor
- uint max = pb->_nodes.size();
+ uint max = pb->number_of_nodes();
assert( max > 1, "" );
uint start = max - pb->_num_succs;
// Find which output path belongs to projection
for (j = start; j < max; j++) {
- if( pb->_nodes[j] == in0 )
+ if( pb->get_node(j) == in0 )
break;
}
assert( j < max, "must find" );
@@ -1027,8 +1027,8 @@
Block* least = LCA;
double least_freq = least->_freq;
uint target = get_latency_for_node(self);
- uint start_latency = get_latency_for_node(LCA->_nodes[0]);
- uint end_latency = get_latency_for_node(LCA->_nodes[LCA->end_idx()]);
+ uint start_latency = get_latency_for_node(LCA->head());
+ uint end_latency = get_latency_for_node(LCA->get_node(LCA->end_idx()));
bool in_latency = (target <= start_latency);
const Block* root_block = get_block_for_node(_root);
@@ -1049,9 +1049,9 @@
self->dump();
tty->print_cr("# B%d: start latency for [%4d]=%d, end latency for [%4d]=%d, freq=%g",
LCA->_pre_order,
- LCA->_nodes[0]->_idx,
+ LCA->head()->_idx,
start_latency,
- LCA->_nodes[LCA->end_idx()]->_idx,
+ LCA->get_node(LCA->end_idx())->_idx,
end_latency,
least_freq);
}
@@ -1074,14 +1074,14 @@
if (mach && LCA == root_block)
break;
- uint start_lat = get_latency_for_node(LCA->_nodes[0]);
+ uint start_lat = get_latency_for_node(LCA->head());
uint end_idx = LCA->end_idx();
- uint end_lat = get_latency_for_node(LCA->_nodes[end_idx]);
+ uint end_lat = get_latency_for_node(LCA->get_node(end_idx));
double LCA_freq = LCA->_freq;
#ifndef PRODUCT
if (trace_opto_pipelining()) {
tty->print_cr("# B%d: start latency for [%4d]=%d, end latency for [%4d]=%d, freq=%g",
- LCA->_pre_order, LCA->_nodes[0]->_idx, start_lat, end_idx, end_lat, LCA_freq);
+ LCA->_pre_order, LCA->head()->_idx, start_lat, end_idx, end_lat, LCA_freq);
}
#endif
cand_cnt++;
@@ -1342,7 +1342,7 @@
Node* proj = _matcher._null_check_tests[i];
Node* val = _matcher._null_check_tests[i + 1];
Block* block = get_block_for_node(proj);
- block->implicit_null_check(this, proj, val, allowed_reasons);
+ implicit_null_check(block, proj, val, allowed_reasons);
// The implicit_null_check will only perform the transformation
// if the null branch is truly uncommon, *and* it leads to an
// uncommon trap. Combined with the too_many_traps guards
@@ -1363,7 +1363,7 @@
visited.Clear();
for (uint i = 0; i < number_of_blocks(); i++) {
Block* block = get_block(i);
- if (!block->schedule_local(this, _matcher, ready_cnt, visited)) {
+ if (!schedule_local(block, ready_cnt, visited)) {
if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) {
C->record_method_not_compilable("local schedule failed");
}
@@ -1375,7 +1375,7 @@
// clone the instructions on all paths below the Catch.
for (uint i = 0; i < number_of_blocks(); i++) {
Block* block = get_block(i);
- block->call_catch_cleanup(this, C);
+ call_catch_cleanup(block);
}
#ifndef PRODUCT
@@ -1726,7 +1726,7 @@
// Determine the probability of reaching successor 'i' from the receiver block.
float Block::succ_prob(uint i) {
int eidx = end_idx();
- Node *n = _nodes[eidx]; // Get ending Node
+ Node *n = get_node(eidx); // Get ending Node
int op = n->Opcode();
if (n->is_Mach()) {
@@ -1761,7 +1761,7 @@
float prob = n->as_MachIf()->_prob;
assert(prob >= 0.0 && prob <= 1.0, "out of range probability");
// If succ[i] is the FALSE branch, invert path info
- if( _nodes[i + eidx + 1]->Opcode() == Op_IfFalse ) {
+ if( get_node(i + eidx + 1)->Opcode() == Op_IfFalse ) {
return 1.0f - prob; // not taken
} else {
return prob; // taken
@@ -1773,7 +1773,7 @@
return 1.0f/_num_succs;
case Op_Catch: {
- const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
+ const CatchProjNode *ci = get_node(i + eidx + 1)->as_CatchProj();
if (ci->_con == CatchProjNode::fall_through_index) {
// Fall-thru path gets the lion's share.
return 1.0f - PROB_UNLIKELY_MAG(5)*_num_succs;
@@ -1810,7 +1810,7 @@
// Return the number of fall-through candidates for a block
int Block::num_fall_throughs() {
int eidx = end_idx();
- Node *n = _nodes[eidx]; // Get ending Node
+ Node *n = get_node(eidx); // Get ending Node
int op = n->Opcode();
if (n->is_Mach()) {
@@ -1834,7 +1834,7 @@
case Op_Catch: {
for (uint i = 0; i < _num_succs; i++) {
- const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
+ const CatchProjNode *ci = get_node(i + eidx + 1)->as_CatchProj();
if (ci->_con == CatchProjNode::fall_through_index) {
return 1;
}
@@ -1862,14 +1862,14 @@
// Return true if a specific successor could be fall-through target.
bool Block::succ_fall_through(uint i) {
int eidx = end_idx();
- Node *n = _nodes[eidx]; // Get ending Node
+ Node *n = get_node(eidx); // Get ending Node
int op = n->Opcode();
if (n->is_Mach()) {
if (n->is_MachNullCheck()) {
// In theory, either side can fall-thru, for simplicity sake,
// let's say only the false branch can now.
- return _nodes[i + eidx + 1]->Opcode() == Op_IfFalse;
+ return get_node(i + eidx + 1)->Opcode() == Op_IfFalse;
}
op = n->as_Mach()->ideal_Opcode();
}
@@ -1883,7 +1883,7 @@
return true;
case Op_Catch: {
- const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
+ const CatchProjNode *ci = get_node(i + eidx + 1)->as_CatchProj();
return ci->_con == CatchProjNode::fall_through_index;
}
@@ -1907,7 +1907,7 @@
// Update the probability of a two-branch to be uncommon
void Block::update_uncommon_branch(Block* ub) {
int eidx = end_idx();
- Node *n = _nodes[eidx]; // Get ending Node
+ Node *n = get_node(eidx); // Get ending Node
int op = n->as_Mach()->ideal_Opcode();
@@ -1923,7 +1923,7 @@
// If ub is the true path, make the proability small, else
// ub is the false path, and make the probability large
- bool invert = (_nodes[s + eidx + 1]->Opcode() == Op_IfFalse);
+ bool invert = (get_node(s + eidx + 1)->Opcode() == Op_IfFalse);
// Get existing probability
float p = n->as_MachIf()->_prob;
--- a/hotspot/src/share/vm/opto/generateOptoStub.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/generateOptoStub.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -61,6 +61,7 @@
JVMState* jvms = new (C) JVMState(0);
jvms->set_bci(InvocationEntryBci);
jvms->set_monoff(max_map);
+ jvms->set_scloff(max_map);
jvms->set_endoff(max_map);
{
SafePointNode *map = new (C) SafePointNode( max_map, jvms );
--- a/hotspot/src/share/vm/opto/graphKit.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -1501,6 +1501,25 @@
}
}
+bool GraphKit::can_move_pre_barrier() const {
+ BarrierSet* bs = Universe::heap()->barrier_set();
+ switch (bs->kind()) {
+ case BarrierSet::G1SATBCT:
+ case BarrierSet::G1SATBCTLogging:
+ return true; // Can move it if no safepoint
+
+ case BarrierSet::CardTableModRef:
+ case BarrierSet::CardTableExtension:
+ case BarrierSet::ModRef:
+ return true; // There is no pre-barrier
+
+ case BarrierSet::Other:
+ default :
+ ShouldNotReachHere();
+ }
+ return false;
+}
+
void GraphKit::post_barrier(Node* ctl,
Node* store,
Node* obj,
@@ -3551,6 +3570,8 @@
} else {
// In this case both val_type and alias_idx are unused.
assert(pre_val != NULL, "must be loaded already");
+ // Nothing to be done if pre_val is null.
+ if (pre_val->bottom_type() == TypePtr::NULL_PTR) return;
assert(pre_val->bottom_type()->basic_type() == T_OBJECT, "or we shouldn't be here");
}
assert(bt == T_OBJECT, "or we shouldn't be here");
@@ -3595,7 +3616,7 @@
if (do_load) {
// load original value
// alias_idx correct??
- pre_val = __ load(no_ctrl, adr, val_type, bt, alias_idx);
+ pre_val = __ load(__ ctrl(), adr, val_type, bt, alias_idx);
}
// if (pre_val != NULL)
@@ -3804,8 +3825,13 @@
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) {
@@ -3823,9 +3849,6 @@
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);
@@ -3840,3 +3863,9 @@
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)));
+}
--- a/hotspot/src/share/vm/opto/graphKit.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -695,6 +695,10 @@
void write_barrier_post(Node *store, Node* obj,
Node* adr, uint adr_idx, Node* val, bool use_precise);
+ // Allow reordering of pre-barrier with oop store and/or post-barrier.
+ // Used for load_store operations which loads old value.
+ bool can_move_pre_barrier() const;
+
// G1 pre/post barriers
void g1_write_barrier_pre(bool do_load,
Node* obj,
@@ -832,6 +836,9 @@
// 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
--- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -639,8 +639,8 @@
// reachable but are in the CFG so add them here.
for (uint i = 0; i < C->cfg()->number_of_blocks(); i++) {
Block* block = C->cfg()->get_block(i);
- for (uint s = 0; s < block->_nodes.size(); s++) {
- nodeStack.push(block->_nodes[s]);
+ for (uint s = 0; s < block->number_of_nodes(); s++) {
+ nodeStack.push(block->get_node(s));
}
}
}
@@ -713,9 +713,9 @@
tail(SUCCESSORS_ELEMENT);
head(NODES_ELEMENT);
- for (uint s = 0; s < block->_nodes.size(); s++) {
+ for (uint s = 0; s < block->number_of_nodes(); s++) {
begin_elem(NODE_ELEMENT);
- print_attr(NODE_ID_PROPERTY, get_node_id(block->_nodes[s]));
+ print_attr(NODE_ID_PROPERTY, get_node_id(block->get_node(s)));
end_elem();
}
tail(NODES_ELEMENT);
--- a/hotspot/src/share/vm/opto/ifg.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/ifg.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -319,7 +319,7 @@
// value is then removed from the live-ness set and it's inputs are
// added to the live-ness set.
for (uint j = block->end_idx() + 1; j > 1; j--) {
- Node* n = block->_nodes[j - 1];
+ Node* n = block->get_node(j - 1);
// Get value being defined
uint r = _lrg_map.live_range_id(n);
@@ -456,7 +456,7 @@
// Compute first nonphi node index
uint first_inst;
for (first_inst = 1; first_inst < last_inst; first_inst++) {
- if (!block->_nodes[first_inst]->is_Phi()) {
+ if (!block->get_node(first_inst)->is_Phi()) {
break;
}
}
@@ -464,15 +464,15 @@
// Spills could be inserted before CreateEx node which should be
// first instruction in block after Phis. Move CreateEx up.
for (uint insidx = first_inst; insidx < last_inst; insidx++) {
- Node *ex = block->_nodes[insidx];
+ Node *ex = block->get_node(insidx);
if (ex->is_SpillCopy()) {
continue;
}
if (insidx > first_inst && ex->is_Mach() && ex->as_Mach()->ideal_Opcode() == Op_CreateEx) {
// If the CreateEx isn't above all the MachSpillCopies
// then move it to the top.
- block->_nodes.remove(insidx);
- block->_nodes.insert(first_inst, ex);
+ block->remove_node(insidx);
+ block->insert_node(ex, first_inst);
}
// Stop once a CreateEx or any other node is found
break;
@@ -523,7 +523,7 @@
// to the live-ness set.
uint j;
for (j = last_inst + 1; j > 1; j--) {
- Node* n = block->_nodes[j - 1];
+ Node* n = block->get_node(j - 1);
// Get value being defined
uint r = _lrg_map.live_range_id(n);
@@ -541,7 +541,7 @@
if( !n->is_Proj() ||
// Could also be a flags-projection of a dead ADD or such.
(_lrg_map.live_range_id(def) && !liveout.member(_lrg_map.live_range_id(def)))) {
- block->_nodes.remove(j - 1);
+ block->remove_node(j - 1);
if (lrgs(r)._def == n) {
lrgs(r)._def = 0;
}
@@ -605,7 +605,7 @@
// (j - 1) is index for current instruction 'n'
Node *m = n;
for (uint i = j; i <= last_inst && m->is_SpillCopy(); ++i) {
- m = block->_nodes[i];
+ m = block->get_node(i);
}
if (m == single_use) {
lrgs(r)._area = 0.0;
@@ -772,20 +772,20 @@
// Compute high pressure indice; avoid landing in the middle of projnodes
j = hrp_index[0];
- if (j < block->_nodes.size() && j < block->end_idx() + 1) {
- Node* cur = block->_nodes[j];
+ if (j < block->number_of_nodes() && j < block->end_idx() + 1) {
+ Node* cur = block->get_node(j);
while (cur->is_Proj() || (cur->is_MachNullCheck()) || cur->is_Catch()) {
j--;
- cur = block->_nodes[j];
+ cur = block->get_node(j);
}
}
block->_ihrp_index = j;
j = hrp_index[1];
- if (j < block->_nodes.size() && j < block->end_idx() + 1) {
- Node* cur = block->_nodes[j];
+ if (j < block->number_of_nodes() && j < block->end_idx() + 1) {
+ Node* cur = block->get_node(j);
while (cur->is_Proj() || (cur->is_MachNullCheck()) || cur->is_Catch()) {
j--;
- cur = block->_nodes[j];
+ cur = block->get_node(j);
}
}
block->_fhrp_index = j;
--- a/hotspot/src/share/vm/opto/lcm.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/lcm.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -58,14 +58,14 @@
// The proj is the control projection for the not-null case.
// The val is the pointer being checked for nullness or
// decodeHeapOop_not_null node if it did not fold into address.
-void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowed_reasons) {
+void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allowed_reasons) {
// Assume if null check need for 0 offset then always needed
// Intel solaris doesn't support any null checks yet and no
// mechanism exists (yet) to set the switches at an os_cpu level
if( !ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(0)) return;
// Make sure the ptr-is-null path appears to be uncommon!
- float f = end()->as_MachIf()->_prob;
+ float f = block->end()->as_MachIf()->_prob;
if( proj->Opcode() == Op_IfTrue ) f = 1.0f - f;
if( f > PROB_UNLIKELY_MAG(4) ) return;
@@ -75,13 +75,13 @@
// Get the successor block for if the test ptr is non-null
Block* not_null_block; // this one goes with the proj
Block* null_block;
- if (_nodes[_nodes.size()-1] == proj) {
- null_block = _succs[0];
- not_null_block = _succs[1];
+ if (block->get_node(block->number_of_nodes()-1) == proj) {
+ null_block = block->_succs[0];
+ not_null_block = block->_succs[1];
} else {
- assert(_nodes[_nodes.size()-2] == proj, "proj is one or the other");
- not_null_block = _succs[0];
- null_block = _succs[1];
+ assert(block->get_node(block->number_of_nodes()-2) == proj, "proj is one or the other");
+ not_null_block = block->_succs[0];
+ null_block = block->_succs[1];
}
while (null_block->is_Empty() == Block::empty_with_goto) {
null_block = null_block->_succs[0];
@@ -93,8 +93,8 @@
// detect failure of this optimization, as in 6366351.)
{
bool found_trap = false;
- for (uint i1 = 0; i1 < null_block->_nodes.size(); i1++) {
- Node* nn = null_block->_nodes[i1];
+ for (uint i1 = 0; i1 < null_block->number_of_nodes(); i1++) {
+ Node* nn = null_block->get_node(i1);
if (nn->is_MachCall() &&
nn->as_MachCall()->entry_point() == SharedRuntime::uncommon_trap_blob()->entry_point()) {
const Type* trtype = nn->in(TypeFunc::Parms)->bottom_type();
@@ -237,20 +237,20 @@
}
// Check ctrl input to see if the null-check dominates the memory op
- Block *cb = cfg->get_block_for_node(mach);
+ Block *cb = get_block_for_node(mach);
cb = cb->_idom; // Always hoist at least 1 block
if( !was_store ) { // Stores can be hoisted only one block
- while( cb->_dom_depth > (_dom_depth + 1))
+ while( cb->_dom_depth > (block->_dom_depth + 1))
cb = cb->_idom; // Hoist loads as far as we want
// The non-null-block should dominate the memory op, too. Live
// range spilling will insert a spill in the non-null-block if it is
// needs to spill the memory op for an implicit null check.
- if (cb->_dom_depth == (_dom_depth + 1)) {
+ if (cb->_dom_depth == (block->_dom_depth + 1)) {
if (cb != not_null_block) continue;
cb = cb->_idom;
}
}
- if( cb != this ) continue;
+ if( cb != block ) continue;
// Found a memory user; see if it can be hoisted to check-block
uint vidx = 0; // Capture index of value into memop
@@ -262,8 +262,8 @@
if( is_decoden ) continue;
}
// Block of memory-op input
- Block *inb = cfg->get_block_for_node(mach->in(j));
- Block *b = this; // Start from nul check
+ Block *inb = get_block_for_node(mach->in(j));
+ Block *b = block; // Start from nul check
while( b != inb && b->_dom_depth > inb->_dom_depth )
b = b->_idom; // search upwards for input
// See if input dominates null check
@@ -272,28 +272,28 @@
}
if( j > 0 )
continue;
- Block *mb = cfg->get_block_for_node(mach);
+ Block *mb = get_block_for_node(mach);
// Hoisting stores requires more checks for the anti-dependence case.
// Give up hoisting if we have to move the store past any load.
if( was_store ) {
Block *b = mb; // Start searching here for a local load
// mach use (faulting) trying to hoist
// n might be blocker to hoisting
- while( b != this ) {
+ while( b != block ) {
uint k;
- for( k = 1; k < b->_nodes.size(); k++ ) {
- Node *n = b->_nodes[k];
+ for( k = 1; k < b->number_of_nodes(); k++ ) {
+ Node *n = b->get_node(k);
if( n->needs_anti_dependence_check() &&
n->in(LoadNode::Memory) == mach->in(StoreNode::Memory) )
break; // Found anti-dependent load
}
- if( k < b->_nodes.size() )
+ if( k < b->number_of_nodes() )
break; // Found anti-dependent load
// Make sure control does not do a merge (would have to check allpaths)
if( b->num_preds() != 2 ) break;
- b = cfg->get_block_for_node(b->pred(1)); // Move up to predecessor block
+ b = get_block_for_node(b->pred(1)); // Move up to predecessor block
}
- if( b != this ) continue;
+ if( b != block ) continue;
}
// Make sure this memory op is not already being used for a NullCheck
@@ -303,7 +303,7 @@
// Found a candidate! Pick one with least dom depth - the highest
// in the dom tree should be closest to the null check.
- if (best == NULL || cfg->get_block_for_node(mach)->_dom_depth < cfg->get_block_for_node(best)->_dom_depth) {
+ if (best == NULL || get_block_for_node(mach)->_dom_depth < get_block_for_node(best)->_dom_depth) {
best = mach;
bidx = vidx;
}
@@ -319,46 +319,45 @@
if( is_decoden ) {
// Check if we need to hoist decodeHeapOop_not_null first.
- Block *valb = cfg->get_block_for_node(val);
- if( this != valb && this->_dom_depth < valb->_dom_depth ) {
+ Block *valb = get_block_for_node(val);
+ if( block != valb && block->_dom_depth < valb->_dom_depth ) {
// Hoist it up to the end of the test block.
valb->find_remove(val);
- this->add_inst(val);
- cfg->map_node_to_block(val, this);
+ block->add_inst(val);
+ map_node_to_block(val, block);
// DecodeN on x86 may kill flags. Check for flag-killing projections
// that also need to be hoisted.
for (DUIterator_Fast jmax, j = val->fast_outs(jmax); j < jmax; j++) {
Node* n = val->fast_out(j);
if( n->is_MachProj() ) {
- cfg->get_block_for_node(n)->find_remove(n);
- this->add_inst(n);
- cfg->map_node_to_block(n, this);
+ get_block_for_node(n)->find_remove(n);
+ block->add_inst(n);
+ map_node_to_block(n, block);
}
}
}
}
// Hoist the memory candidate up to the end of the test block.
- Block *old_block = cfg->get_block_for_node(best);
+ Block *old_block = get_block_for_node(best);
old_block->find_remove(best);
- add_inst(best);
- cfg->map_node_to_block(best, this);
+ block->add_inst(best);
+ map_node_to_block(best, block);
// Move the control dependence
- if (best->in(0) && best->in(0) == old_block->_nodes[0])
- best->set_req(0, _nodes[0]);
+ if (best->in(0) && best->in(0) == old_block->head())
+ best->set_req(0, block->head());
// Check for flag-killing projections that also need to be hoisted
// Should be DU safe because no edge updates.
for (DUIterator_Fast jmax, j = best->fast_outs(jmax); j < jmax; j++) {
Node* n = best->fast_out(j);
if( n->is_MachProj() ) {
- cfg->get_block_for_node(n)->find_remove(n);
- add_inst(n);
- cfg->map_node_to_block(n, this);
+ get_block_for_node(n)->find_remove(n);
+ block->add_inst(n);
+ map_node_to_block(n, block);
}
}
- Compile *C = cfg->C;
// proj==Op_True --> ne test; proj==Op_False --> eq test.
// One of two graph shapes got matched:
// (IfTrue (If (Bool NE (CmpP ptr NULL))))
@@ -368,10 +367,10 @@
// We need to flip the projections to keep the same semantics.
if( proj->Opcode() == Op_IfTrue ) {
// Swap order of projections in basic block to swap branch targets
- Node *tmp1 = _nodes[end_idx()+1];
- Node *tmp2 = _nodes[end_idx()+2];
- _nodes.map(end_idx()+1, tmp2);
- _nodes.map(end_idx()+2, tmp1);
+ Node *tmp1 = block->get_node(block->end_idx()+1);
+ Node *tmp2 = block->get_node(block->end_idx()+2);
+ block->map_node(tmp2, block->end_idx()+1);
+ block->map_node(tmp1, block->end_idx()+2);
Node *tmp = new (C) Node(C->top()); // Use not NULL input
tmp1->replace_by(tmp);
tmp2->replace_by(tmp1);
@@ -384,8 +383,8 @@
// it as well.
Node *old_tst = proj->in(0);
MachNode *nul_chk = new (C) MachNullCheckNode(old_tst->in(0),best,bidx);
- _nodes.map(end_idx(),nul_chk);
- cfg->map_node_to_block(nul_chk, this);
+ block->map_node(nul_chk, block->end_idx());
+ map_node_to_block(nul_chk, block);
// Redirect users of old_test to nul_chk
for (DUIterator_Last i2min, i2 = old_tst->last_outs(i2min); i2 >= i2min; --i2)
old_tst->last_out(i2)->set_req(0, nul_chk);
@@ -393,8 +392,8 @@
for (uint i3 = 0; i3 < old_tst->req(); i3++)
old_tst->set_req(i3, NULL);
- cfg->latency_from_uses(nul_chk);
- cfg->latency_from_uses(best);
+ latency_from_uses(nul_chk);
+ latency_from_uses(best);
}
@@ -408,7 +407,7 @@
// remaining cases (most), choose the instruction with the greatest latency
// (that is, the most number of pseudo-cycles required to the end of the
// routine). If there is a tie, choose the instruction with the most inputs.
-Node *Block::select(PhaseCFG *cfg, Node_List &worklist, GrowableArray<int> &ready_cnt, VectorSet &next_call, uint sched_slot) {
+Node* PhaseCFG::select(Block* block, Node_List &worklist, GrowableArray<int> &ready_cnt, VectorSet &next_call, uint sched_slot) {
// If only a single entry on the stack, use it
uint cnt = worklist.size();
@@ -442,7 +441,7 @@
}
// Final call in a block must be adjacent to 'catch'
- Node *e = end();
+ Node *e = block->end();
if( e->is_Catch() && e->in(0)->in(0) == n )
continue;
@@ -468,7 +467,7 @@
Node* use = n->fast_out(j);
// The use is a conditional branch, make them adjacent
- if (use->is_MachIf() && cfg->get_block_for_node(use) == this) {
+ if (use->is_MachIf() && get_block_for_node(use) == block) {
found_machif = true;
break;
}
@@ -501,7 +500,7 @@
n_choice = 1;
}
- uint n_latency = cfg->get_latency_for_node(n);
+ uint n_latency = get_latency_for_node(n);
uint n_score = n->req(); // Many inputs get high score to break ties
// Keep best latency found
@@ -529,13 +528,13 @@
//------------------------------set_next_call----------------------------------
-void Block::set_next_call( Node *n, VectorSet &next_call, PhaseCFG* cfg) {
+void PhaseCFG::set_next_call(Block* block, Node* n, VectorSet& next_call) {
if( next_call.test_set(n->_idx) ) return;
for( uint i=0; i<n->len(); i++ ) {
Node *m = n->in(i);
if( !m ) continue; // must see all nodes in block that precede call
- if (cfg->get_block_for_node(m) == this) {
- set_next_call(m, next_call, cfg);
+ if (get_block_for_node(m) == block) {
+ set_next_call(block, m, next_call);
}
}
}
@@ -546,24 +545,26 @@
// next subroutine call get priority - basically it moves things NOT needed
// for the next call till after the call. This prevents me from trying to
// carry lots of stuff live across a call.
-void Block::needed_for_next_call(Node *this_call, VectorSet &next_call, PhaseCFG* cfg) {
+void PhaseCFG::needed_for_next_call(Block* block, Node* this_call, VectorSet& next_call) {
// Find the next control-defining Node in this block
Node* call = NULL;
for (DUIterator_Fast imax, i = this_call->fast_outs(imax); i < imax; i++) {
Node* m = this_call->fast_out(i);
- if(cfg->get_block_for_node(m) == this && // Local-block user
+ if (get_block_for_node(m) == block && // Local-block user
m != this_call && // Not self-start node
- m->is_MachCall() )
+ m->is_MachCall()) {
call = m;
break;
+ }
}
if (call == NULL) return; // No next call (e.g., block end is near)
// Set next-call for all inputs to this call
- set_next_call(call, next_call, cfg);
+ set_next_call(block, call, next_call);
}
//------------------------------add_call_kills-------------------------------------
-void Block::add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_policy, bool exclude_soe) {
+// helper function that adds caller save registers to MachProjNode
+static void add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_policy, bool exclude_soe) {
// Fill in the kill mask for the call
for( OptoReg::Name r = OptoReg::Name(0); r < _last_Mach_Reg; r=OptoReg::add(r,1) ) {
if( !regs.Member(r) ) { // Not already defined by the call
@@ -579,7 +580,7 @@
//------------------------------sched_call-------------------------------------
-uint Block::sched_call( Matcher &matcher, PhaseCFG* cfg, uint node_cnt, Node_List &worklist, GrowableArray<int> &ready_cnt, MachCallNode *mcall, VectorSet &next_call ) {
+uint PhaseCFG::sched_call(Block* block, uint node_cnt, Node_List& worklist, GrowableArray<int>& ready_cnt, MachCallNode* mcall, VectorSet& next_call) {
RegMask regs;
// Schedule all the users of the call right now. All the users are
@@ -592,18 +593,18 @@
ready_cnt.at_put(n->_idx, n_cnt);
assert( n_cnt == 0, "" );
// Schedule next to call
- _nodes.map(node_cnt++, n);
+ block->map_node(n, node_cnt++);
// Collect defined registers
regs.OR(n->out_RegMask());
// Check for scheduling the next control-definer
if( n->bottom_type() == Type::CONTROL )
// Warm up next pile of heuristic bits
- needed_for_next_call(n, next_call, cfg);
+ needed_for_next_call(block, n, next_call);
// Children of projections are now all ready
for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
Node* m = n->fast_out(j); // Get user
- if(cfg->get_block_for_node(m) != this) {
+ if(get_block_for_node(m) != block) {
continue;
}
if( m->is_Phi() ) continue;
@@ -617,14 +618,14 @@
// Act as if the call defines the Frame Pointer.
// Certainly the FP is alive and well after the call.
- regs.Insert(matcher.c_frame_pointer());
+ regs.Insert(_matcher.c_frame_pointer());
// Set all registers killed and not already defined by the call.
uint r_cnt = mcall->tf()->range()->cnt();
int op = mcall->ideal_Opcode();
- MachProjNode *proj = new (matcher.C) MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj );
- cfg->map_node_to_block(proj, this);
- _nodes.insert(node_cnt++, proj);
+ MachProjNode *proj = new (C) MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj );
+ map_node_to_block(proj, block);
+ block->insert_node(proj, node_cnt++);
// Select the right register save policy.
const char * save_policy;
@@ -633,13 +634,13 @@
case Op_CallLeaf:
case Op_CallLeafNoFP:
// Calling C code so use C calling convention
- save_policy = matcher._c_reg_save_policy;
+ save_policy = _matcher._c_reg_save_policy;
break;
case Op_CallStaticJava:
case Op_CallDynamicJava:
// Calling Java code so use Java calling convention
- save_policy = matcher._register_save_policy;
+ save_policy = _matcher._register_save_policy;
break;
default:
@@ -674,44 +675,46 @@
//------------------------------schedule_local---------------------------------
// Topological sort within a block. Someday become a real scheduler.
-bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray<int> &ready_cnt, VectorSet &next_call) {
+bool PhaseCFG::schedule_local(Block* block, GrowableArray<int>& ready_cnt, VectorSet& next_call) {
// Already "sorted" are the block start Node (as the first entry), and
// the block-ending Node and any trailing control projections. We leave
// these alone. PhiNodes and ParmNodes are made to follow the block start
// Node. Everything else gets topo-sorted.
#ifndef PRODUCT
- if (cfg->trace_opto_pipelining()) {
- tty->print_cr("# --- schedule_local B%d, before: ---", _pre_order);
- for (uint i = 0;i < _nodes.size();i++) {
+ if (trace_opto_pipelining()) {
+ tty->print_cr("# --- schedule_local B%d, before: ---", block->_pre_order);
+ for (uint i = 0;i < block->number_of_nodes(); i++) {
tty->print("# ");
- _nodes[i]->fast_dump();
+ block->get_node(i)->fast_dump();
}
tty->print_cr("#");
}
#endif
// RootNode is already sorted
- if( _nodes.size() == 1 ) return true;
+ if (block->number_of_nodes() == 1) {
+ return true;
+ }
// Move PhiNodes and ParmNodes from 1 to cnt up to the start
- uint node_cnt = end_idx();
+ uint node_cnt = block->end_idx();
uint phi_cnt = 1;
uint i;
for( i = 1; i<node_cnt; i++ ) { // Scan for Phi
- Node *n = _nodes[i];
+ Node *n = block->get_node(i);
if( n->is_Phi() || // Found a PhiNode or ParmNode
- (n->is_Proj() && n->in(0) == head()) ) {
+ (n->is_Proj() && n->in(0) == block->head()) ) {
// Move guy at 'phi_cnt' to the end; makes a hole at phi_cnt
- _nodes.map(i,_nodes[phi_cnt]);
- _nodes.map(phi_cnt++,n); // swap Phi/Parm up front
+ block->map_node(block->get_node(phi_cnt), i);
+ block->map_node(n, phi_cnt++); // swap Phi/Parm up front
} else { // All others
// Count block-local inputs to 'n'
uint cnt = n->len(); // Input count
uint local = 0;
for( uint j=0; j<cnt; j++ ) {
Node *m = n->in(j);
- if( m && cfg->get_block_for_node(m) == this && !m->is_top() )
+ if( m && get_block_for_node(m) == block && !m->is_top() )
local++; // One more block-local input
}
ready_cnt.at_put(n->_idx, local); // Count em up
@@ -723,7 +726,7 @@
for (uint prec = n->req(); prec < n->len(); prec++) {
Node* oop_store = n->in(prec);
if (oop_store != NULL) {
- assert(cfg->get_block_for_node(oop_store)->_dom_depth <= this->_dom_depth, "oop_store must dominate card-mark");
+ assert(get_block_for_node(oop_store)->_dom_depth <= block->_dom_depth, "oop_store must dominate card-mark");
}
}
}
@@ -747,16 +750,16 @@
}
}
}
- for(uint i2=i; i2<_nodes.size(); i2++ ) // Trailing guys get zapped count
- ready_cnt.at_put(_nodes[i2]->_idx, 0);
+ for(uint i2=i; i2< block->number_of_nodes(); i2++ ) // Trailing guys get zapped count
+ ready_cnt.at_put(block->get_node(i2)->_idx, 0);
// All the prescheduled guys do not hold back internal nodes
uint i3;
for(i3 = 0; i3<phi_cnt; i3++ ) { // For all pre-scheduled
- Node *n = _nodes[i3]; // Get pre-scheduled
+ Node *n = block->get_node(i3); // Get pre-scheduled
for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
Node* m = n->fast_out(j);
- if (cfg->get_block_for_node(m) == this) { // Local-block user
+ if (get_block_for_node(m) == block) { // Local-block user
int m_cnt = ready_cnt.at(m->_idx)-1;
ready_cnt.at_put(m->_idx, m_cnt); // Fix ready count
}
@@ -767,7 +770,7 @@
// Make a worklist
Node_List worklist;
for(uint i4=i3; i4<node_cnt; i4++ ) { // Put ready guys on worklist
- Node *m = _nodes[i4];
+ Node *m = block->get_node(i4);
if( !ready_cnt.at(m->_idx) ) { // Zero ready count?
if (m->is_iteratively_computed()) {
// Push induction variable increments last to allow other uses
@@ -789,15 +792,15 @@
}
// Warm up the 'next_call' heuristic bits
- needed_for_next_call(_nodes[0], next_call, cfg);
+ needed_for_next_call(block, block->head(), next_call);
#ifndef PRODUCT
- if (cfg->trace_opto_pipelining()) {
- for (uint j=0; j<_nodes.size(); j++) {
- Node *n = _nodes[j];
+ if (trace_opto_pipelining()) {
+ for (uint j=0; j< block->number_of_nodes(); j++) {
+ Node *n = block->get_node(j);
int idx = n->_idx;
tty->print("# ready cnt:%3d ", ready_cnt.at(idx));
- tty->print("latency:%3d ", cfg->get_latency_for_node(n));
+ tty->print("latency:%3d ", get_latency_for_node(n));
tty->print("%4d: %s\n", idx, n->Name());
}
}
@@ -808,7 +811,7 @@
while( worklist.size() ) { // Worklist is not ready
#ifndef PRODUCT
- if (cfg->trace_opto_pipelining()) {
+ if (trace_opto_pipelining()) {
tty->print("# ready list:");
for( uint i=0; i<worklist.size(); i++ ) { // Inspect entire worklist
Node *n = worklist[i]; // Get Node on worklist
@@ -819,13 +822,13 @@
#endif
// Select and pop a ready guy from worklist
- Node* n = select(cfg, worklist, ready_cnt, next_call, phi_cnt);
- _nodes.map(phi_cnt++,n); // Schedule him next
+ Node* n = select(block, worklist, ready_cnt, next_call, phi_cnt);
+ block->map_node(n, phi_cnt++); // Schedule him next
#ifndef PRODUCT
- if (cfg->trace_opto_pipelining()) {
+ if (trace_opto_pipelining()) {
tty->print("# select %d: %s", n->_idx, n->Name());
- tty->print(", latency:%d", cfg->get_latency_for_node(n));
+ tty->print(", latency:%d", get_latency_for_node(n));
n->dump();
if (Verbose) {
tty->print("# ready list:");
@@ -840,26 +843,26 @@
#endif
if( n->is_MachCall() ) {
MachCallNode *mcall = n->as_MachCall();
- phi_cnt = sched_call(matcher, cfg, phi_cnt, worklist, ready_cnt, mcall, next_call);
+ phi_cnt = sched_call(block, phi_cnt, worklist, ready_cnt, mcall, next_call);
continue;
}
if (n->is_Mach() && n->as_Mach()->has_call()) {
RegMask regs;
- regs.Insert(matcher.c_frame_pointer());
+ regs.Insert(_matcher.c_frame_pointer());
regs.OR(n->out_RegMask());
- MachProjNode *proj = new (matcher.C) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj );
- cfg->map_node_to_block(proj, this);
- _nodes.insert(phi_cnt++, proj);
+ MachProjNode *proj = new (C) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj );
+ map_node_to_block(proj, block);
+ block->insert_node(proj, phi_cnt++);
- add_call_kills(proj, regs, matcher._c_reg_save_policy, false);
+ add_call_kills(proj, regs, _matcher._c_reg_save_policy, false);
}
// Children are now all ready
for (DUIterator_Fast i5max, i5 = n->fast_outs(i5max); i5 < i5max; i5++) {
Node* m = n->fast_out(i5); // Get user
- if (cfg->get_block_for_node(m) != this) {
+ if (get_block_for_node(m) != block) {
continue;
}
if( m->is_Phi() ) continue;
@@ -874,9 +877,8 @@
}
}
- if( phi_cnt != end_idx() ) {
+ if( phi_cnt != block->end_idx() ) {
// did not schedule all. Retry, Bailout, or Die
- Compile* C = matcher.C;
if (C->subsume_loads() == true && !C->failing()) {
// Retry with subsume_loads == false
// If this is the first failure, the sentinel string will "stick"
@@ -888,12 +890,12 @@
}
#ifndef PRODUCT
- if (cfg->trace_opto_pipelining()) {
+ if (trace_opto_pipelining()) {
tty->print_cr("#");
tty->print_cr("# after schedule_local");
- for (uint i = 0;i < _nodes.size();i++) {
+ for (uint i = 0;i < block->number_of_nodes();i++) {
tty->print("# ");
- _nodes[i]->fast_dump();
+ block->get_node(i)->fast_dump();
}
tty->cr();
}
@@ -919,7 +921,7 @@
}
//------------------------------catch_cleanup_find_cloned_def------------------
-static Node *catch_cleanup_find_cloned_def(Block *use_blk, Node *def, Block *def_blk, PhaseCFG* cfg, int n_clone_idx) {
+Node* PhaseCFG::catch_cleanup_find_cloned_def(Block *use_blk, Node *def, Block *def_blk, int n_clone_idx) {
assert( use_blk != def_blk, "Inter-block cleanup only");
// The use is some block below the Catch. Find and return the clone of the def
@@ -945,14 +947,14 @@
// PhiNode, the PhiNode uses from the def and IT's uses need fixup.
Node_Array inputs = new Node_List(Thread::current()->resource_area());
for(uint k = 1; k < use_blk->num_preds(); k++) {
- Block* block = cfg->get_block_for_node(use_blk->pred(k));
- inputs.map(k, catch_cleanup_find_cloned_def(block, def, def_blk, cfg, n_clone_idx));
+ Block* block = get_block_for_node(use_blk->pred(k));
+ inputs.map(k, catch_cleanup_find_cloned_def(block, def, def_blk, n_clone_idx));
}
// Check to see if the use_blk already has an identical phi inserted.
// If it exists, it will be at the first position since all uses of a
// def are processed together.
- Node *phi = use_blk->_nodes[1];
+ Node *phi = use_blk->get_node(1);
if( phi->is_Phi() ) {
fixup = phi;
for (uint k = 1; k < use_blk->num_preds(); k++) {
@@ -967,8 +969,8 @@
// If an existing PhiNode was not found, make a new one.
if (fixup == NULL) {
Node *new_phi = PhiNode::make(use_blk->head(), def);
- use_blk->_nodes.insert(1, new_phi);
- cfg->map_node_to_block(new_phi, use_blk);
+ use_blk->insert_node(new_phi, 1);
+ map_node_to_block(new_phi, use_blk);
for (uint k = 1; k < use_blk->num_preds(); k++) {
new_phi->set_req(k, inputs[k]);
}
@@ -977,7 +979,7 @@
} else {
// Found the use just below the Catch. Make it use the clone.
- fixup = use_blk->_nodes[n_clone_idx];
+ fixup = use_blk->get_node(n_clone_idx);
}
return fixup;
@@ -997,36 +999,36 @@
for( uint k = 0; k < blk->_num_succs; k++ ) {
// Get clone in each successor block
Block *sb = blk->_succs[k];
- Node *clone = sb->_nodes[offset_idx+1];
+ Node *clone = sb->get_node(offset_idx+1);
assert( clone->Opcode() == use->Opcode(), "" );
// Make use-clone reference the def-clone
- catch_cleanup_fix_all_inputs(clone, def, sb->_nodes[n_clone_idx]);
+ catch_cleanup_fix_all_inputs(clone, def, sb->get_node(n_clone_idx));
}
}
//------------------------------catch_cleanup_inter_block---------------------
// Fix all input edges in use that reference "def". The use is in a different
// block than the def.
-static void catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, PhaseCFG* cfg, int n_clone_idx) {
+void PhaseCFG::catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, int n_clone_idx) {
if( !use_blk ) return; // Can happen if the use is a precedence edge
- Node *new_def = catch_cleanup_find_cloned_def(use_blk, def, def_blk, cfg, n_clone_idx);
+ Node *new_def = catch_cleanup_find_cloned_def(use_blk, def, def_blk, n_clone_idx);
catch_cleanup_fix_all_inputs(use, def, new_def);
}
//------------------------------call_catch_cleanup-----------------------------
// If we inserted any instructions between a Call and his CatchNode,
// clone the instructions on all paths below the Catch.
-void Block::call_catch_cleanup(PhaseCFG* cfg, Compile* C) {
+void PhaseCFG::call_catch_cleanup(Block* block) {
// End of region to clone
- uint end = end_idx();
- if( !_nodes[end]->is_Catch() ) return;
+ uint end = block->end_idx();
+ if( !block->get_node(end)->is_Catch() ) return;
// Start of region to clone
uint beg = end;
- while(!_nodes[beg-1]->is_MachProj() ||
- !_nodes[beg-1]->in(0)->is_MachCall() ) {
+ while(!block->get_node(beg-1)->is_MachProj() ||
+ !block->get_node(beg-1)->in(0)->is_MachCall() ) {
beg--;
assert(beg > 0,"Catch cleanup walking beyond block boundary");
}
@@ -1035,15 +1037,15 @@
// Clone along all Catch output paths. Clone area between the 'beg' and
// 'end' indices.
- for( uint i = 0; i < _num_succs; i++ ) {
- Block *sb = _succs[i];
+ for( uint i = 0; i < block->_num_succs; i++ ) {
+ Block *sb = block->_succs[i];
// Clone the entire area; ignoring the edge fixup for now.
for( uint j = end; j > beg; j-- ) {
// It is safe here to clone a node with anti_dependence
// since clones dominate on each path.
- Node *clone = _nodes[j-1]->clone();
- sb->_nodes.insert( 1, clone );
- cfg->map_node_to_block(clone, sb);
+ Node *clone = block->get_node(j-1)->clone();
+ sb->insert_node(clone, 1);
+ map_node_to_block(clone, sb);
}
}
@@ -1051,7 +1053,7 @@
// Fixup edges. Check the def-use info per cloned Node
for(uint i2 = beg; i2 < end; i2++ ) {
uint n_clone_idx = i2-beg+1; // Index of clone of n in each successor block
- Node *n = _nodes[i2]; // Node that got cloned
+ Node *n = block->get_node(i2); // Node that got cloned
// Need DU safe iterator because of edge manipulation in calls.
Unique_Node_List *out = new Unique_Node_List(Thread::current()->resource_area());
for (DUIterator_Fast j1max, j1 = n->fast_outs(j1max); j1 < j1max; j1++) {
@@ -1060,19 +1062,19 @@
uint max = out->size();
for (uint j = 0; j < max; j++) {// For all users
Node *use = out->pop();
- Block *buse = cfg->get_block_for_node(use);
+ Block *buse = get_block_for_node(use);
if( use->is_Phi() ) {
for( uint k = 1; k < use->req(); k++ )
if( use->in(k) == n ) {
- Block* block = cfg->get_block_for_node(buse->pred(k));
- Node *fixup = catch_cleanup_find_cloned_def(block, n, this, cfg, n_clone_idx);
+ Block* b = get_block_for_node(buse->pred(k));
+ Node *fixup = catch_cleanup_find_cloned_def(b, n, block, n_clone_idx);
use->set_req(k, fixup);
}
} else {
- if (this == buse) {
- catch_cleanup_intra_block(use, n, this, beg, n_clone_idx);
+ if (block == buse) {
+ catch_cleanup_intra_block(use, n, block, beg, n_clone_idx);
} else {
- catch_cleanup_inter_block(use, buse, n, this, cfg, n_clone_idx);
+ catch_cleanup_inter_block(use, buse, n, block, n_clone_idx);
}
}
} // End for all users
@@ -1081,30 +1083,30 @@
// Remove the now-dead cloned ops
for(uint i3 = beg; i3 < end; i3++ ) {
- _nodes[beg]->disconnect_inputs(NULL, C);
- _nodes.remove(beg);
+ block->get_node(beg)->disconnect_inputs(NULL, C);
+ block->remove_node(beg);
}
// If the successor blocks have a CreateEx node, move it back to the top
- for(uint i4 = 0; i4 < _num_succs; i4++ ) {
- Block *sb = _succs[i4];
+ for(uint i4 = 0; i4 < block->_num_succs; i4++ ) {
+ Block *sb = block->_succs[i4];
uint new_cnt = end - beg;
// Remove any newly created, but dead, nodes.
for( uint j = new_cnt; j > 0; j-- ) {
- Node *n = sb->_nodes[j];
+ Node *n = sb->get_node(j);
if (n->outcnt() == 0 &&
(!n->is_Proj() || n->as_Proj()->in(0)->outcnt() == 1) ){
n->disconnect_inputs(NULL, C);
- sb->_nodes.remove(j);
+ sb->remove_node(j);
new_cnt--;
}
}
// If any newly created nodes remain, move the CreateEx node to the top
if (new_cnt > 0) {
- Node *cex = sb->_nodes[1+new_cnt];
+ Node *cex = sb->get_node(1+new_cnt);
if( cex->is_Mach() && cex->as_Mach()->ideal_Opcode() == Op_CreateEx ) {
- sb->_nodes.remove(1+new_cnt);
- sb->_nodes.insert(1,cex);
+ sb->remove_node(1+new_cnt);
+ sb->insert_node(cex, 1);
}
}
}
--- a/hotspot/src/share/vm/opto/library_call.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/library_call.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -1280,6 +1280,11 @@
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);
@@ -2756,10 +2761,28 @@
newval = _gvn.makecon(TypePtr::NULL_PTR);
// Reference stores need a store barrier.
- pre_barrier(true /* do_load*/,
- control(), base, adr, alias_idx, newval, value_type->make_oopptr(),
- NULL /* pre_val*/,
- T_OBJECT);
+ if (kind == LS_xchg) {
+ // If pre-barrier must execute before the oop store, old value will require do_load here.
+ if (!can_move_pre_barrier()) {
+ pre_barrier(true /* do_load*/,
+ control(), base, adr, alias_idx, newval, value_type->make_oopptr(),
+ NULL /* pre_val*/,
+ T_OBJECT);
+ } // Else move pre_barrier to use load_store value, see below.
+ } else if (kind == LS_cmpxchg) {
+ // Same as for newval above:
+ if (_gvn.type(oldval) == TypePtr::NULL_PTR) {
+ oldval = _gvn.makecon(TypePtr::NULL_PTR);
+ }
+ // The only known value which might get overwritten is oldval.
+ pre_barrier(false /* do_load */,
+ control(), NULL, NULL, max_juint, NULL, NULL,
+ oldval /* pre_val */,
+ T_OBJECT);
+ } else {
+ ShouldNotReachHere();
+ }
+
#ifdef _LP64
if (adr->bottom_type()->is_ptr_to_narrowoop()) {
Node *newval_enc = _gvn.transform(new (C) EncodePNode(newval, newval->bottom_type()->make_narrowoop()));
@@ -2795,16 +2818,27 @@
Node* proj = _gvn.transform(new (C) SCMemProjNode(load_store));
set_memory(proj, alias_idx);
+ if (type == T_OBJECT && kind == LS_xchg) {
+#ifdef _LP64
+ if (adr->bottom_type()->is_ptr_to_narrowoop()) {
+ load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->get_ptr_type()));
+ }
+#endif
+ if (can_move_pre_barrier()) {
+ // Don't need to load pre_val. The old value is returned by load_store.
+ // The pre_barrier can execute after the xchg as long as no safepoint
+ // gets inserted between them.
+ pre_barrier(false /* do_load */,
+ control(), NULL, NULL, max_juint, NULL, NULL,
+ load_store /* pre_val */,
+ T_OBJECT);
+ }
+ }
+
// Add the trailing membar surrounding the access
insert_mem_bar(Op_MemBarCPUOrder);
insert_mem_bar(Op_MemBarAcquire);
-#ifdef _LP64
- if (type == T_OBJECT && adr->bottom_type()->is_ptr_to_narrowoop() && kind == LS_xchg) {
- load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->get_ptr_type()));
- }
-#endif
-
assert(type2size[load_store->bottom_type()->basic_type()] == type2size[rtype], "result type should match");
set_result(load_store);
return true;
--- a/hotspot/src/share/vm/opto/live.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/live.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -85,8 +85,8 @@
IndexSet* def = &_defs[block->_pre_order-1];
DEBUG_ONLY(IndexSet *def_outside = getfreeset();)
uint i;
- for (i = block->_nodes.size(); i > 1; i--) {
- Node* n = block->_nodes[i-1];
+ for (i = block->number_of_nodes(); i > 1; i--) {
+ Node* n = block->get_node(i-1);
if (n->is_Phi()) {
break;
}
@@ -112,7 +112,7 @@
#endif
// Remove anything defined by Phis and the block start instruction
for (uint k = i; k > 0; k--) {
- uint r = _names[block->_nodes[k - 1]->_idx];
+ uint r = _names[block->get_node(k - 1)->_idx];
def->insert(r);
use->remove(r);
}
@@ -124,7 +124,7 @@
// PhiNode uses go in the live-out set of prior blocks.
for (uint k = i; k > 0; k--) {
- add_liveout(p, _names[block->_nodes[k-1]->in(l)->_idx], first_pass);
+ add_liveout(p, _names[block->get_node(k-1)->in(l)->_idx], first_pass);
}
}
freeset(block);
@@ -254,10 +254,10 @@
void PhaseLive::dump( const Block *b ) const {
tty->print("Block %d: ",b->_pre_order);
tty->print("LiveOut: "); _live[b->_pre_order-1].dump();
- uint cnt = b->_nodes.size();
+ uint cnt = b->number_of_nodes();
for( uint i=0; i<cnt; i++ ) {
- tty->print("L%d/", _names[b->_nodes[i]->_idx] );
- b->_nodes[i]->dump();
+ tty->print("L%d/", _names[b->get_node(i)->_idx] );
+ b->get_node(i)->dump();
}
tty->print("\n");
}
@@ -269,7 +269,7 @@
for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
Block* block = _cfg.get_block(i);
for (uint j = block->end_idx() + 1; j > 1; j--) {
- Node* n = block->_nodes[j-1];
+ Node* n = block->get_node(j-1);
if (n->is_Phi()) {
break;
}
--- a/hotspot/src/share/vm/opto/machnode.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/machnode.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -58,7 +58,7 @@
class MachOper : public ResourceObj {
public:
// Allocate right next to the MachNodes in the same arena
- void *operator new( size_t x, Compile* C ) { return C->node_arena()->Amalloc_D(x); }
+ void *operator new( size_t x, Compile* C ) throw() { return C->node_arena()->Amalloc_D(x); }
// Opcode
virtual uint opcode() const = 0;
--- a/hotspot/src/share/vm/opto/macro.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/macro.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -72,6 +72,8 @@
int jvms_adj = new_dbg_start - old_dbg_start;
assert (new_dbg_start == newcall->req(), "argument count mismatch");
+ // SafePointScalarObject node could be referenced several times in debug info.
+ // Use Dict to record cloned nodes.
Dict* sosn_map = new Dict(cmpkey,hashkey);
for (uint i = old_dbg_start; i < oldcall->req(); i++) {
Node* old_in = oldcall->in(i);
@@ -79,8 +81,8 @@
if (old_in != NULL && old_in->is_SafePointScalarObject()) {
SafePointScalarObjectNode* old_sosn = old_in->as_SafePointScalarObject();
uint old_unique = C->unique();
- Node* new_in = old_sosn->clone(jvms_adj, sosn_map);
- if (old_unique != C->unique()) {
+ Node* new_in = old_sosn->clone(sosn_map);
+ if (old_unique != C->unique()) { // New node?
new_in->set_req(0, C->root()); // reset control edge
new_in = transform_later(new_in); // Register new node.
}
@@ -725,7 +727,11 @@
while (safepoints.length() > 0) {
SafePointNode* sfpt = safepoints.pop();
Node* mem = sfpt->memory();
- uint first_ind = sfpt->req();
+ assert(sfpt->jvms() != NULL, "missed JVMS");
+ // Fields of scalar objs are referenced only at the end
+ // of regular debuginfo at the last (youngest) JVMS.
+ // Record relative start index.
+ uint first_ind = (sfpt->req() - sfpt->jvms()->scloff());
SafePointScalarObjectNode* sobj = new (C) SafePointScalarObjectNode(res_type,
#ifdef ASSERT
alloc,
@@ -799,7 +805,7 @@
for (int i = start; i < end; i++) {
if (sfpt_done->in(i)->is_SafePointScalarObject()) {
SafePointScalarObjectNode* scobj = sfpt_done->in(i)->as_SafePointScalarObject();
- if (scobj->first_index() == sfpt_done->req() &&
+ if (scobj->first_index(jvms) == sfpt_done->req() &&
scobj->n_fields() == (uint)nfields) {
assert(scobj->alloc() == alloc, "sanity");
sfpt_done->set_req(i, res);
--- a/hotspot/src/share/vm/opto/memnode.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/memnode.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -962,6 +962,19 @@
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 @@
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 @@
}
}
-
// 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 @@
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 @@
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 @@
&& 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()) {
--- a/hotspot/src/share/vm/opto/node.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/node.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -773,6 +773,21 @@
_in[_cnt] = NULL; // NULL out emptied slot
}
+//------------------------------del_req_ordered--------------------------------
+// Delete the required edge and compact the edge array with preserved order
+void Node::del_req_ordered( uint idx ) {
+ assert( idx < _cnt, "oob");
+ assert( !VerifyHashTableKeys || _hash_lock == 0,
+ "remove node from hash table before modifying it");
+ // First remove corresponding def-use edge
+ Node *n = in(idx);
+ if (n != NULL) n->del_out((Node *)this);
+ if (idx < _cnt - 1) { // Not last edge ?
+ Copy::conjoint_words_to_lower((HeapWord*)&_in[idx+1], (HeapWord*)&_in[idx], ((_cnt-idx-1)*sizeof(Node*)));
+ }
+ _in[--_cnt] = NULL; // NULL out emptied slot
+}
+
//------------------------------ins_req----------------------------------------
// Insert a new required input at the end
void Node::ins_req( uint idx, Node *n ) {
--- a/hotspot/src/share/vm/opto/node.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/node.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -211,7 +211,7 @@
// New Operator that takes a Compile pointer, this will eventually
// be the "new" New operator.
- inline void* operator new( size_t x, Compile* C) {
+ inline void* operator new( size_t x, Compile* C) throw() {
Node* n = (Node*)C->node_arena()->Amalloc_D(x);
#ifdef ASSERT
n->_in = (Node**)n; // magic cookie for assertion check
@@ -384,6 +384,7 @@
void add_req( Node *n ); // Append a NEW required input
void add_req_batch( Node* n, uint m ); // Append m NEW required inputs (all n).
void del_req( uint idx ); // Delete required edge & compact
+ void del_req_ordered( uint idx ); // Delete required edge & compact with preserved order
void ins_req( uint i, Node *n ); // Insert a NEW required input
void set_req( uint i, Node *n ) {
assert( is_not_dead(n), "can not use dead node");
--- a/hotspot/src/share/vm/opto/output.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/output.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -57,7 +57,7 @@
// Convert Nodes to instruction bits and pass off to the VM
void Compile::Output() {
// RootNode goes
- assert( _cfg->get_root_block()->_nodes.size() == 0, "" );
+ assert( _cfg->get_root_block()->number_of_nodes() == 0, "" );
// The number of new nodes (mostly MachNop) is proportional to
// the number of java calls and inner loops which are aligned.
@@ -70,11 +70,11 @@
Block *entry = _cfg->get_block(1);
Block *broot = _cfg->get_root_block();
- const StartNode *start = entry->_nodes[0]->as_Start();
+ const StartNode *start = entry->head()->as_Start();
// Replace StartNode with prolog
MachPrologNode *prolog = new (this) MachPrologNode();
- entry->_nodes.map( 0, prolog );
+ entry->map_node(prolog, 0);
_cfg->map_node_to_block(prolog, entry);
_cfg->unmap_node_from_block(start); // start is no longer in any block
@@ -144,8 +144,8 @@
for (uint i = 0; i < _cfg->number_of_blocks(); i++) {
tty->print("\nBB#%03d:\n", i);
Block* block = _cfg->get_block(i);
- for (uint j = 0; j < block->_nodes.size(); j++) {
- Node* n = block->_nodes[j];
+ for (uint j = 0; j < block->number_of_nodes(); j++) {
+ Node* n = block->get_node(j);
OptoReg::Name reg = _regalloc->get_reg_first(n);
tty->print(" %-6s ", reg >= 0 && reg < REG_COUNT ? Matcher::regName[reg] : "");
n->dump();
@@ -226,8 +226,8 @@
// Insert call to zap runtime stub before every node with an oop map
for( uint i=0; i<_cfg->number_of_blocks(); i++ ) {
Block *b = _cfg->get_block(i);
- for ( uint j = 0; j < b->_nodes.size(); ++j ) {
- Node *n = b->_nodes[j];
+ for ( uint j = 0; j < b->number_of_nodes(); ++j ) {
+ Node *n = b->get_node(j);
// Determining if we should insert a zap-a-lot node in output.
// We do that for all nodes that has oopmap info, except for calls
@@ -256,7 +256,7 @@
}
if (insert) {
Node *zap = call_zap_node(n->as_MachSafePoint(), i);
- b->_nodes.insert( j, zap );
+ b->insert_node(zap, j);
_cfg->map_node_to_block(zap, b);
++j;
}
@@ -379,10 +379,10 @@
DEBUG_ONLY( jmp_rule[i] = 0; )
// Sum all instruction sizes to compute block size
- uint last_inst = block->_nodes.size();
+ uint last_inst = block->number_of_nodes();
uint blk_size = 0;
for (uint j = 0; j < last_inst; j++) {
- Node* nj = block->_nodes[j];
+ Node* nj = block->get_node(j);
// Handle machine instruction nodes
if (nj->is_Mach()) {
MachNode *mach = nj->as_Mach();
@@ -477,18 +477,18 @@
for (uint i = 0; i < nblocks; i++) {
Block* block = _cfg->get_block(i);
int idx = jmp_nidx[i];
- MachNode* mach = (idx == -1) ? NULL: block->_nodes[idx]->as_Mach();
+ MachNode* mach = (idx == -1) ? NULL: block->get_node(idx)->as_Mach();
if (mach != NULL && mach->may_be_short_branch()) {
#ifdef ASSERT
assert(jmp_size[i] > 0 && mach->is_MachBranch(), "sanity");
int j;
// Find the branch; ignore trailing NOPs.
- for (j = block->_nodes.size()-1; j>=0; j--) {
- Node* n = block->_nodes[j];
+ for (j = block->number_of_nodes()-1; j>=0; j--) {
+ Node* n = block->get_node(j);
if (!n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con)
break;
}
- assert(j >= 0 && j == idx && block->_nodes[j] == (Node*)mach, "sanity");
+ assert(j >= 0 && j == idx && block->get_node(j) == (Node*)mach, "sanity");
#endif
int br_size = jmp_size[i];
int br_offs = blk_starts[i] + jmp_offset[i];
@@ -522,7 +522,7 @@
diff -= nop_size;
}
adjust_block_start += diff;
- block->_nodes.map(idx, replacement);
+ block->map_node(replacement, idx);
mach->subsume_by(replacement, C);
mach = replacement;
progress = true;
@@ -639,7 +639,7 @@
new ConstantOopWriteValue(cik->java_mirror()->constant_encoding()));
Compile::set_sv_for_object_node(objs, sv);
- uint first_ind = spobj->first_index();
+ uint first_ind = spobj->first_index(sfpt->jvms());
for (uint i = 0; i < spobj->n_fields(); i++) {
Node* fld_node = sfpt->in(first_ind+i);
(void)FillLocArray(sv->field_values()->length(), sfpt, fld_node, sv->field_values(), objs);
@@ -894,7 +894,7 @@
GrowableArray<MonitorValue*> *monarray = new GrowableArray<MonitorValue*>(num_mon);
// Loop over monitors and insert into array
- for(idx = 0; idx < num_mon; idx++) {
+ for (idx = 0; idx < num_mon; idx++) {
// Grab the node that defines this monitor
Node* box_node = sfn->monitor_box(jvms, idx);
Node* obj_node = sfn->monitor_obj(jvms, idx);
@@ -902,11 +902,11 @@
// Create ScopeValue for object
ScopeValue *scval = NULL;
- if( obj_node->is_SafePointScalarObject() ) {
+ if (obj_node->is_SafePointScalarObject()) {
SafePointScalarObjectNode* spobj = obj_node->as_SafePointScalarObject();
scval = Compile::sv_for_node_id(objs, spobj->_idx);
if (scval == NULL) {
- const Type *t = obj_node->bottom_type();
+ const Type *t = spobj->bottom_type();
ciKlass* cik = t->is_oopptr()->klass();
assert(cik->is_instance_klass() ||
cik->is_array_klass(), "Not supported allocation.");
@@ -914,14 +914,14 @@
new ConstantOopWriteValue(cik->java_mirror()->constant_encoding()));
Compile::set_sv_for_object_node(objs, sv);
- uint first_ind = spobj->first_index();
+ uint first_ind = spobj->first_index(youngest_jvms);
for (uint i = 0; i < spobj->n_fields(); i++) {
Node* fld_node = sfn->in(first_ind+i);
(void)FillLocArray(sv->field_values()->length(), sfn, fld_node, sv->field_values(), objs);
}
scval = sv;
}
- } else if( !obj_node->is_Con() ) {
+ } else if (!obj_node->is_Con()) {
OptoReg::Name obj_reg = _regalloc->get_reg_first(obj_node);
if( obj_node->bottom_type()->base() == Type::NarrowOop ) {
scval = new_loc_value( _regalloc, obj_reg, Location::narrowoop );
@@ -1088,8 +1088,8 @@
for (uint i = 0; i < _cfg->number_of_blocks(); i++) {
Block* b = _cfg->get_block(i);
- for (uint j = 0; j < b->_nodes.size(); j++) {
- Node* n = b->_nodes[j];
+ for (uint j = 0; j < b->number_of_nodes(); j++) {
+ Node* n = b->get_node(j);
// If the node is a MachConstantNode evaluate the constant
// value section.
@@ -1247,14 +1247,14 @@
// Define the label at the beginning of the basic block
MacroAssembler(cb).bind(blk_labels[block->_pre_order]);
- uint last_inst = block->_nodes.size();
+ uint last_inst = block->number_of_nodes();
// Emit block normally, except for last instruction.
// Emit means "dump code bits into code buffer".
for (uint j = 0; j<last_inst; j++) {
// Get the node
- Node* n = block->_nodes[j];
+ Node* n = block->get_node(j);
// See if delay slots are supported
if (valid_bundle_info(n) &&
@@ -1308,7 +1308,7 @@
assert((padding % nop_size) == 0, "padding is not a multiple of NOP size");
int nops_cnt = padding / nop_size;
MachNode *nop = new (this) MachNopNode(nops_cnt);
- block->_nodes.insert(j++, nop);
+ block->insert_node(nop, j++);
last_inst++;
_cfg->map_node_to_block(nop, block);
nop->emit(*cb, _regalloc);
@@ -1394,7 +1394,7 @@
// Insert padding between avoid_back_to_back branches.
if (needs_padding && replacement->avoid_back_to_back()) {
MachNode *nop = new (this) MachNopNode();
- block->_nodes.insert(j++, nop);
+ block->insert_node(nop, j++);
_cfg->map_node_to_block(nop, block);
last_inst++;
nop->emit(*cb, _regalloc);
@@ -1407,7 +1407,7 @@
jmp_size[i] = new_size;
jmp_rule[i] = mach->rule();
#endif
- block->_nodes.map(j, replacement);
+ block->map_node(replacement, j);
mach->subsume_by(replacement, C);
n = replacement;
mach = replacement;
@@ -1438,7 +1438,7 @@
count++;
uint i4;
for (i4 = 0; i4 < last_inst; ++i4) {
- if (block->_nodes[i4] == oop_store) {
+ if (block->get_node(i4) == oop_store) {
break;
}
}
@@ -1548,7 +1548,7 @@
int padding = nb->alignment_padding(current_offset);
if( padding > 0 ) {
MachNode *nop = new (this) MachNopNode(padding / nop_size);
- block->_nodes.insert(block->_nodes.size(), nop);
+ block->insert_node(nop, block->number_of_nodes());
_cfg->map_node_to_block(nop, block);
nop->emit(*cb, _regalloc);
current_offset = cb->insts_size();
@@ -1655,8 +1655,8 @@
int j;
// Find the branch; ignore trailing NOPs.
- for (j = block->_nodes.size() - 1; j >= 0; j--) {
- n = block->_nodes[j];
+ for (j = block->number_of_nodes() - 1; j >= 0; j--) {
+ n = block->get_node(j);
if (!n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con) {
break;
}
@@ -1675,8 +1675,8 @@
uint call_return = call_returns[block->_pre_order];
#ifdef ASSERT
assert( call_return > 0, "no call seen for this basic block" );
- while (block->_nodes[--j]->is_MachProj()) ;
- assert(block->_nodes[j]->is_MachCall(), "CatchProj must follow call");
+ while (block->get_node(--j)->is_MachProj()) ;
+ assert(block->get_node(j)->is_MachCall(), "CatchProj must follow call");
#endif
// last instruction is a CatchNode, find it's CatchProjNodes
int nof_succs = block->_num_succs;
@@ -1782,7 +1782,7 @@
// Get the last node
Block* block = _cfg->get_block(_cfg->number_of_blocks() - 1);
- _next_node = block->_nodes[block->_nodes.size() - 1];
+ _next_node = block->get_node(block->number_of_nodes() - 1);
}
#ifndef PRODUCT
@@ -1875,7 +1875,7 @@
// Used to allow latency 0 to force an instruction to the beginning
// of the bb
uint latency = 1;
- Node *use = bb->_nodes[j];
+ Node *use = bb->get_node(j);
uint nlen = use->len();
// Walk over all the inputs
@@ -2286,7 +2286,7 @@
(OptoReg::is_valid(_regalloc->get_reg_first(n)) || op != Op_BoxLock)) ) {
// Push any trailing projections
- if( bb->_nodes[bb->_nodes.size()-1] != n ) {
+ if( bb->get_node(bb->number_of_nodes()-1) != n ) {
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
Node *foi = n->fast_out(i);
if( foi->is_Proj() )
@@ -2329,21 +2329,21 @@
_unconditional_delay_slot = NULL;
#ifdef ASSERT
- for( uint i=0; i < bb->_nodes.size(); i++ )
- assert( _uses[bb->_nodes[i]->_idx] == 0, "_use array not clean" );
+ for( uint i=0; i < bb->number_of_nodes(); i++ )
+ assert( _uses[bb->get_node(i)->_idx] == 0, "_use array not clean" );
#endif
// Force the _uses count to never go to zero for unscheduable pieces
// of the block
for( uint k = 0; k < _bb_start; k++ )
- _uses[bb->_nodes[k]->_idx] = 1;
- for( uint l = _bb_end; l < bb->_nodes.size(); l++ )
- _uses[bb->_nodes[l]->_idx] = 1;
+ _uses[bb->get_node(k)->_idx] = 1;
+ for( uint l = _bb_end; l < bb->number_of_nodes(); l++ )
+ _uses[bb->get_node(l)->_idx] = 1;
// Iterate backwards over the instructions in the block. Don't count the
// branch projections at end or the block header instructions.
for( uint j = _bb_end-1; j >= _bb_start; j-- ) {
- Node *n = bb->_nodes[j];
+ Node *n = bb->get_node(j);
if( n->is_Proj() ) continue; // Projections handled another way
// Account for all uses
@@ -2398,8 +2398,8 @@
#ifndef PRODUCT
if (_cfg->C->trace_opto_output()) {
tty->print("# Schedule BB#%03d (initial)\n", i);
- for (uint j = 0; j < bb->_nodes.size(); j++) {
- bb->_nodes[j]->dump();
+ for (uint j = 0; j < bb->number_of_nodes(); j++) {
+ bb->get_node(j)->dump();
}
}
#endif
@@ -2426,10 +2426,10 @@
}
// Leave untouched the starting instruction, any Phis, a CreateEx node
- // or Top. bb->_nodes[_bb_start] is the first schedulable instruction.
- _bb_end = bb->_nodes.size()-1;
+ // or Top. bb->get_node(_bb_start) is the first schedulable instruction.
+ _bb_end = bb->number_of_nodes()-1;
for( _bb_start=1; _bb_start <= _bb_end; _bb_start++ ) {
- Node *n = bb->_nodes[_bb_start];
+ Node *n = bb->get_node(_bb_start);
// Things not matched, like Phinodes and ProjNodes don't get scheduled.
// Also, MachIdealNodes do not get scheduled
if( !n->is_Mach() ) continue; // Skip non-machine nodes
@@ -2449,19 +2449,19 @@
// in the block), because they have delay slots we can fill. Calls all
// have their delay slots filled in the template expansions, so we don't
// bother scheduling them.
- Node *last = bb->_nodes[_bb_end];
+ Node *last = bb->get_node(_bb_end);
// Ignore trailing NOPs.
while (_bb_end > 0 && last->is_Mach() &&
last->as_Mach()->ideal_Opcode() == Op_Con) {
- last = bb->_nodes[--_bb_end];
+ last = bb->get_node(--_bb_end);
}
assert(!last->is_Mach() || last->as_Mach()->ideal_Opcode() != Op_Con, "");
if( last->is_Catch() ||
// Exclude unreachable path case when Halt node is in a separate block.
(_bb_end > 1 && last->is_Mach() && last->as_Mach()->ideal_Opcode() == Op_Halt) ) {
// There must be a prior call. Skip it.
- while( !bb->_nodes[--_bb_end]->is_MachCall() ) {
- assert( bb->_nodes[_bb_end]->is_MachProj(), "skipping projections after expected call" );
+ while( !bb->get_node(--_bb_end)->is_MachCall() ) {
+ assert( bb->get_node(_bb_end)->is_MachProj(), "skipping projections after expected call" );
}
} else if( last->is_MachNullCheck() ) {
// Backup so the last null-checked memory instruction is
@@ -2470,7 +2470,7 @@
Node *mem = last->in(1);
do {
_bb_end--;
- } while (mem != bb->_nodes[_bb_end]);
+ } while (mem != bb->get_node(_bb_end));
} else {
// Set _bb_end to point after last schedulable inst.
_bb_end++;
@@ -2499,7 +2499,7 @@
assert( _scheduled.size() == _bb_end - _bb_start, "wrong number of instructions" );
#ifdef ASSERT
for( uint l = _bb_start; l < _bb_end; l++ ) {
- Node *n = bb->_nodes[l];
+ Node *n = bb->get_node(l);
uint m;
for( m = 0; m < _bb_end-_bb_start; m++ )
if( _scheduled[m] == n )
@@ -2510,14 +2510,14 @@
// Now copy the instructions (in reverse order) back to the block
for ( uint k = _bb_start; k < _bb_end; k++ )
- bb->_nodes.map(k, _scheduled[_bb_end-k-1]);
+ bb->map_node(_scheduled[_bb_end-k-1], k);
#ifndef PRODUCT
if (_cfg->C->trace_opto_output()) {
tty->print("# Schedule BB#%03d (final)\n", i);
uint current = 0;
- for (uint j = 0; j < bb->_nodes.size(); j++) {
- Node *n = bb->_nodes[j];
+ for (uint j = 0; j < bb->number_of_nodes(); j++) {
+ Node *n = bb->get_node(j);
if( valid_bundle_info(n) ) {
Bundle *bundle = node_bundling(n);
if (bundle->instr_count() > 0 || bundle->flags() > 0) {
@@ -2579,8 +2579,8 @@
// Walk over the block backwards. Check to make sure each DEF doesn't
// kill a live value (other than the one it's supposed to). Add each
// USE to the live set.
- for( uint i = b->_nodes.size()-1; i >= _bb_start; i-- ) {
- Node *n = b->_nodes[i];
+ for( uint i = b->number_of_nodes()-1; i >= _bb_start; i-- ) {
+ Node *n = b->get_node(i);
int n_op = n->Opcode();
if( n_op == Op_MachProj && n->ideal_reg() == MachProjNode::fat_proj ) {
// Fat-proj kills a slew of registers
@@ -2711,7 +2711,7 @@
pinch->req() == 1 ) { // pinch not yet in block?
pinch->del_req(0); // yank pointer to later-def, also set flag
// Insert the pinch-point in the block just after the last use
- b->_nodes.insert(b->find_node(use)+1,pinch);
+ b->insert_node(pinch, b->find_node(use) + 1);
_bb_end++; // Increase size scheduled region in block
}
@@ -2763,10 +2763,10 @@
// it being in the current block.
bool fat_proj_seen = false;
uint last_safept = _bb_end-1;
- Node* end_node = (_bb_end-1 >= _bb_start) ? b->_nodes[last_safept] : NULL;
+ Node* end_node = (_bb_end-1 >= _bb_start) ? b->get_node(last_safept) : NULL;
Node* last_safept_node = end_node;
for( uint i = _bb_end-1; i >= _bb_start; i-- ) {
- Node *n = b->_nodes[i];
+ Node *n = b->get_node(i);
int is_def = n->outcnt(); // def if some uses prior to adding precedence edges
if( n->is_MachProj() && n->ideal_reg() == MachProjNode::fat_proj ) {
// Fat-proj kills a slew of registers
@@ -2815,7 +2815,7 @@
// Do not allow defs of new derived values to float above GC
// points unless the base is definitely available at the GC point.
- Node *m = b->_nodes[i];
+ Node *m = b->get_node(i);
// Add precedence edge from following safepoint to use of derived pointer
if( last_safept_node != end_node &&
@@ -2832,11 +2832,11 @@
if( n->jvms() ) { // Precedence edge from derived to safept
// Check if last_safept_node was moved by pinch-point insertion in anti_do_use()
- if( b->_nodes[last_safept] != last_safept_node ) {
+ if( b->get_node(last_safept) != last_safept_node ) {
last_safept = b->find_node(last_safept_node);
}
for( uint j=last_safept; j > i; j-- ) {
- Node *mach = b->_nodes[j];
+ Node *mach = b->get_node(j);
if( mach->is_Mach() && mach->as_Mach()->ideal_Opcode() == Op_AddP )
mach->add_prec( n );
}
--- a/hotspot/src/share/vm/opto/parse.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/parse.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -518,7 +518,7 @@
// 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);
--- a/hotspot/src/share/vm/opto/parse3.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/parse3.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -147,7 +147,15 @@
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 @@
}
}
}
- 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 @@
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 @@
// 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 @@
}
-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 @@
push( zerocon(T_OBJECT) );
return false;
}
- default:
- ShouldNotReachHere();
+
+ if (con_type == NULL)
+ // we cannot inline the oop, but we can use it later to narrow a type
return false;
- }
- // success
+ push_node(constant.basic_type(), makecon(con_type));
return true;
}
-
//=============================================================================
void Parse::do_anewarray() {
bool will_link;
--- a/hotspot/src/share/vm/opto/phaseX.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/phaseX.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -1648,10 +1648,10 @@
bool block_not_printed = true;
// and each instruction within a block
- uint end_index = block->_nodes.size();
+ uint end_index = block->number_of_nodes();
// block->end_idx() not valid after PhaseRegAlloc
for( uint instruction_index = 1; instruction_index < end_index; ++instruction_index ) {
- Node *n = block->_nodes.at(instruction_index);
+ Node *n = block->get_node(instruction_index);
if( n->is_Mach() ) {
MachNode *m = n->as_Mach();
int deleted_count = 0;
@@ -1673,7 +1673,7 @@
}
// Print instructions being deleted
for( int i = (deleted_count - 1); i >= 0; --i ) {
- block->_nodes.at(instruction_index-i)->as_Mach()->format(_regalloc); tty->cr();
+ block->get_node(instruction_index-i)->as_Mach()->format(_regalloc); tty->cr();
}
tty->print_cr("replaced with");
// Print new instruction
@@ -1687,11 +1687,11 @@
// the node index to live range mappings.)
uint safe_instruction_index = (instruction_index - deleted_count);
for( ; (instruction_index > safe_instruction_index); --instruction_index ) {
- block->_nodes.remove( instruction_index );
+ block->remove_node( instruction_index );
}
// install new node after safe_instruction_index
- block->_nodes.insert( safe_instruction_index + 1, m2 );
- end_index = block->_nodes.size() - 1; // Recompute new block size
+ block->insert_node(m2, safe_instruction_index + 1);
+ end_index = block->number_of_nodes() - 1; // Recompute new block size
NOT_PRODUCT( inc_peepholes(); )
}
}
--- a/hotspot/src/share/vm/opto/postaloc.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/postaloc.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -423,8 +423,8 @@
// Count of Phis in block
uint phi_dex;
- for (phi_dex = 1; phi_dex < block->_nodes.size(); phi_dex++) {
- Node* phi = block->_nodes[phi_dex];
+ for (phi_dex = 1; phi_dex < block->number_of_nodes(); phi_dex++) {
+ Node* phi = block->get_node(phi_dex);
if (!phi->is_Phi()) {
break;
}
@@ -439,7 +439,7 @@
Block* pb = _cfg.get_block_for_node(block->pred(j));
// Remove copies along phi edges
for (uint k = 1; k < phi_dex; k++) {
- elide_copy(block->_nodes[k], j, block, *blk2value[pb->_pre_order], *blk2regnd[pb->_pre_order], false);
+ elide_copy(block->get_node(k), j, block, *blk2value[pb->_pre_order], *blk2regnd[pb->_pre_order], false);
}
if (blk2value[pb->_pre_order]) { // Have a mapping on this edge?
// See if this predecessor's mappings have been used by everybody
@@ -510,7 +510,7 @@
// For all Phi's
for (j = 1; j < phi_dex; j++) {
uint k;
- Node *phi = block->_nodes[j];
+ Node *phi = block->get_node(j);
uint pidx = _lrg_map.live_range_id(phi);
OptoReg::Name preg = lrgs(_lrg_map.live_range_id(phi)).reg();
@@ -522,7 +522,7 @@
u = u ? NodeSentinel : x; // Capture unique input, or NodeSentinel for 2nd input
}
if (u != NodeSentinel) { // Junk Phi. Remove
- block->_nodes.remove(j--);
+ block->remove_node(j--);
phi_dex--;
_cfg.unmap_node_from_block(phi);
phi->replace_by(u);
@@ -552,8 +552,8 @@
}
// For all remaining instructions
- for (j = phi_dex; j < block->_nodes.size(); j++) {
- Node* n = block->_nodes[j];
+ for (j = phi_dex; j < block->number_of_nodes(); j++) {
+ Node* n = block->get_node(j);
if(n->outcnt() == 0 && // Dead?
n != C->top() && // (ignore TOP, it has no du info)
--- a/hotspot/src/share/vm/opto/reg_split.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/reg_split.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -112,17 +112,17 @@
void PhaseChaitin::insert_proj( Block *b, uint i, Node *spill, uint maxlrg ) {
// Skip intervening ProjNodes. Do not insert between a ProjNode and
// its definer.
- while( i < b->_nodes.size() &&
- (b->_nodes[i]->is_Proj() ||
- b->_nodes[i]->is_Phi() ) )
+ while( i < b->number_of_nodes() &&
+ (b->get_node(i)->is_Proj() ||
+ b->get_node(i)->is_Phi() ) )
i++;
// Do not insert between a call and his Catch
- if( b->_nodes[i]->is_Catch() ) {
+ if( b->get_node(i)->is_Catch() ) {
// Put the instruction at the top of the fall-thru block.
// Find the fall-thru projection
while( 1 ) {
- const CatchProjNode *cp = b->_nodes[++i]->as_CatchProj();
+ const CatchProjNode *cp = b->get_node(++i)->as_CatchProj();
if( cp->_con == CatchProjNode::fall_through_index )
break;
}
@@ -131,7 +131,7 @@
i = 1; // Right at start of block
}
- b->_nodes.insert(i,spill); // Insert node in block
+ b->insert_node(spill, i); // Insert node in block
_cfg.map_node_to_block(spill, b); // Update node->block mapping to reflect
// Adjust the point where we go hi-pressure
if( i <= b->_ihrp_index ) b->_ihrp_index++;
@@ -160,9 +160,9 @@
// (The implicit_null_check function ensures the use is also dominated
// by the branch-not-taken block.)
Node *be = b->end();
- if( be->is_MachNullCheck() && be->in(1) == def && def == b->_nodes[loc] ) {
+ if( be->is_MachNullCheck() && be->in(1) == def && def == b->get_node(loc)) {
// Spill goes in the branch-not-taken block
- b = b->_succs[b->_nodes[b->end_idx()+1]->Opcode() == Op_IfTrue];
+ b = b->_succs[b->get_node(b->end_idx()+1)->Opcode() == Op_IfTrue];
loc = 0; // Just past the Region
}
assert( loc >= 0, "must insert past block head" );
@@ -450,7 +450,7 @@
// Scan block for 1st use.
for( uint i = 1; i <= b->end_idx(); i++ ) {
- Node *n = b->_nodes[i];
+ Node *n = b->get_node(i);
// Ignore PHI use, these can be up or down
if (n->is_Phi()) {
continue;
@@ -647,7 +647,7 @@
// check block for appropriate phinode & update edges
for( insidx = 1; insidx <= b->end_idx(); insidx++ ) {
- n1 = b->_nodes[insidx];
+ n1 = b->get_node(insidx);
// bail if this is not a phi
phi = n1->is_Phi() ? n1->as_Phi() : NULL;
if( phi == NULL ) {
@@ -747,7 +747,7 @@
//----------Walk Instructions in the Block and Split----------
// For all non-phi instructions in the block
for( insidx = 1; insidx <= b->end_idx(); insidx++ ) {
- Node *n = b->_nodes[insidx];
+ Node *n = b->get_node(insidx);
// Find the defining Node's live range index
uint defidx = _lrg_map.find_id(n);
uint cnt = n->req();
@@ -776,7 +776,7 @@
assert(_lrg_map.find_id(n) == _lrg_map.find_id(u), "should be the same lrg");
n->replace_by(u); // Then replace with unique input
n->disconnect_inputs(NULL, C);
- b->_nodes.remove(insidx);
+ b->remove_node(insidx);
insidx--;
b->_ihrp_index--;
b->_fhrp_index--;
@@ -789,12 +789,12 @@
(b->_reg_pressure < (uint)INTPRESSURE) ||
b->_ihrp_index > 4000000 ||
b->_ihrp_index >= b->end_idx() ||
- !b->_nodes[b->_ihrp_index]->is_Proj(), "" );
+ !b->get_node(b->_ihrp_index)->is_Proj(), "" );
assert( insidx > b->_fhrp_index ||
(b->_freg_pressure < (uint)FLOATPRESSURE) ||
b->_fhrp_index > 4000000 ||
b->_fhrp_index >= b->end_idx() ||
- !b->_nodes[b->_fhrp_index]->is_Proj(), "" );
+ !b->get_node(b->_fhrp_index)->is_Proj(), "" );
// ********** Handle Crossing HRP Boundry **********
if( (insidx == b->_ihrp_index) || (insidx == b->_fhrp_index) ) {
@@ -819,7 +819,7 @@
// Insert point is just past last use or def in the block
int insert_point = insidx-1;
while( insert_point > 0 ) {
- Node *n = b->_nodes[insert_point];
+ Node *n = b->get_node(insert_point);
// Hit top of block? Quit going backwards
if (n->is_Phi()) {
break;
@@ -865,7 +865,7 @@
}
} // end if LRG is UP
} // end for all spilling live ranges
- assert( b->_nodes[insidx] == n, "got insidx set incorrectly" );
+ assert( b->get_node(insidx) == n, "got insidx set incorrectly" );
} // end if crossing HRP Boundry
// If the LRG index is oob, then this is a new spillcopy, skip it.
@@ -878,7 +878,7 @@
if (copyidx && defidx == _lrg_map.live_range_id(n->in(copyidx))) {
n->replace_by( n->in(copyidx) );
n->set_req( copyidx, NULL );
- b->_nodes.remove(insidx--);
+ b->remove_node(insidx--);
b->_ihrp_index--; // Adjust the point where we go hi-pressure
b->_fhrp_index--;
continue;
@@ -932,10 +932,10 @@
// Rematerializable? Then clone def at use site instead
// of store/load
if( def->rematerialize() ) {
- int old_size = b->_nodes.size();
+ int old_size = b->number_of_nodes();
def = split_Rematerialize( def, b, insidx, maxlrg, splits, slidx, lrg2reach, Reachblock, true );
if( !def ) return 0; // Bail out
- insidx += b->_nodes.size()-old_size;
+ insidx += b->number_of_nodes()-old_size;
}
MachNode *mach = n->is_Mach() ? n->as_Mach() : NULL;
@@ -1332,8 +1332,8 @@
// so look at the node before it.
int insert = pred->end_idx();
while (insert >= 1 &&
- pred->_nodes[insert - 1]->is_SpillCopy() &&
- _lrg_map.find(pred->_nodes[insert - 1]) >= lrgs_before_phi_split) {
+ pred->get_node(insert - 1)->is_SpillCopy() &&
+ _lrg_map.find(pred->get_node(insert - 1)) >= lrgs_before_phi_split) {
insert--;
}
def = split_Rematerialize(def, pred, insert, maxlrg, splits, slidx, lrg2reach, Reachblock, false);
@@ -1402,7 +1402,7 @@
for (bidx = 0; bidx < _cfg.number_of_blocks(); bidx++) {
b = _cfg.get_block(bidx);
for (insidx = 0; insidx <= b->end_idx(); insidx++) {
- Node *n = b->_nodes[insidx];
+ Node *n = b->get_node(insidx);
uint defidx = _lrg_map.find(n);
assert(defidx < _lrg_map.max_lrg_id(), "Bad live range index in Split");
assert(defidx < maxlrg,"Bad live range index in Split");
--- a/hotspot/src/share/vm/opto/type.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/type.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -189,6 +189,38 @@
}
+//-----------------------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 @@
}
//------------------------------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 @@
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::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 @@
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 @@
//------------------------------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);
@@ -3457,11 +3492,39 @@
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 @@
// 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 @@
(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 );
}
--- a/hotspot/src/share/vm/opto/type.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/opto/type.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -169,7 +169,7 @@
public:
- inline void* operator new( size_t x ) {
+ inline void* operator new( size_t x ) throw() {
Compile* compile = Compile::current();
compile->set_type_last_size(x);
void *temp = compile->type_arena()->Amalloc_D(x);
@@ -372,6 +372,10 @@
// 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 @@
//------------------------------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 @@
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 @@
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 @@
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;
--- a/hotspot/src/share/vm/runtime/arguments.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -1605,17 +1605,6 @@
return result;
}
-void Arguments::set_heap_base_min_address() {
- if (FLAG_IS_DEFAULT(HeapBaseMinAddress) && UseG1GC && HeapBaseMinAddress < 1*G) {
- // By default HeapBaseMinAddress is 2G on all platforms except Solaris x86.
- // G1 currently needs a lot of C-heap, so on Solaris we have to give G1
- // some extra space for the C-heap compared to other collectors.
- // Use FLAG_SET_DEFAULT here rather than FLAG_SET_ERGO to make sure that
- // code that checks for default values work correctly.
- FLAG_SET_DEFAULT(HeapBaseMinAddress, 1*G);
- }
-}
-
void Arguments::set_heap_size() {
if (!FLAG_IS_DEFAULT(DefaultMaxRAMFraction)) {
// Deprecated flag
@@ -2230,7 +2219,7 @@
// among the distinct pages.
if (ContendedPaddingWidth < 0 || ContendedPaddingWidth > 8192) {
jio_fprintf(defaultStream::error_stream(),
- "ContendedPaddingWidth=" INTX_FORMAT " must be the between %d and %d\n",
+ "ContendedPaddingWidth=" INTX_FORMAT " must be in between %d and %d\n",
ContendedPaddingWidth, 0, 8192);
status = false;
}
@@ -2239,7 +2228,7 @@
// It is sufficient to check against the largest type size.
if ((ContendedPaddingWidth % BytesPerLong) != 0) {
jio_fprintf(defaultStream::error_stream(),
- "ContendedPaddingWidth=" INTX_FORMAT " must be the multiple of %d\n",
+ "ContendedPaddingWidth=" INTX_FORMAT " must be a multiple of %d\n",
ContendedPaddingWidth, BytesPerLong);
status = false;
}
@@ -3537,8 +3526,6 @@
}
}
- set_heap_base_min_address();
-
// Set heap size based on available physical memory
set_heap_size();
--- a/hotspot/src/share/vm/runtime/arguments.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -334,8 +334,6 @@
// limits the given memory size by the maximum amount of memory this process is
// currently allowed to allocate or reserve.
static julong limit_by_allocatable_memory(julong size);
- // Setup HeapBaseMinAddress
- static void set_heap_base_min_address();
// Setup heap size
static void set_heap_size();
// Based on automatic selection criteria, should the
--- a/hotspot/src/share/vm/runtime/fprofiler.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/runtime/fprofiler.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -264,7 +264,7 @@
public:
- void* operator new(size_t size, ThreadProfiler* tp);
+ void* operator new(size_t size, ThreadProfiler* tp) throw();
void operator delete(void* p);
ProfilerNode() {
@@ -373,7 +373,7 @@
}
};
-void* ProfilerNode::operator new(size_t size, ThreadProfiler* tp){
+void* ProfilerNode::operator new(size_t size, ThreadProfiler* tp) throw() {
void* result = (void*) tp->area_top;
tp->area_top += size;
@@ -925,6 +925,8 @@
FlatProfiler::interval_print();
FlatProfiler::interval_reset();
}
+
+ FREE_C_HEAP_ARRAY(JavaThread *, threadsList, mtInternal);
} else {
// Couldn't get the threads lock, just record that rather than blocking
FlatProfiler::threads_lock_ticks += 1;
--- a/hotspot/src/share/vm/runtime/globals.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/runtime/globals.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -205,6 +205,7 @@
#define C1_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 product}", DEFAULT },
#define C1_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 pd product}", DEFAULT },
+#define C1_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 diagnostic}", DEFAULT },
#ifdef PRODUCT
#define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
#define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */
@@ -260,7 +261,7 @@
G1_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT)
#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
- C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, C1_PD_DEVELOP_FLAG_STRUCT, C1_PRODUCT_FLAG_STRUCT, C1_PD_PRODUCT_FLAG_STRUCT, C1_NOTPRODUCT_FLAG_STRUCT)
+ C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, C1_PD_DEVELOP_FLAG_STRUCT, C1_PRODUCT_FLAG_STRUCT, C1_PD_PRODUCT_FLAG_STRUCT, C1_DIAGNOSTIC_FLAG_STRUCT, C1_NOTPRODUCT_FLAG_STRUCT)
#endif
#ifdef COMPILER2
C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, C2_PD_DEVELOP_FLAG_STRUCT, C2_PRODUCT_FLAG_STRUCT, C2_PD_PRODUCT_FLAG_STRUCT, C2_DIAGNOSTIC_FLAG_STRUCT, C2_EXPERIMENTAL_FLAG_STRUCT, C2_NOTPRODUCT_FLAG_STRUCT)
--- a/hotspot/src/share/vm/runtime/globals.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -3514,6 +3514,8 @@
"Temporary flag for transition to AbstractMethodError wrapped " \
"in InvocationTargetException. See 6531596") \
\
+ develop(bool, VerifyLambdaBytecodes, false, \
+ "Force verification of jdk 8 lambda metafactory bytecodes.") \
\
develop(intx, FastSuperclassLimit, 8, \
"Depth of hardwired instanceof accelerator array") \
@@ -3647,6 +3649,9 @@
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") \
\
@@ -3685,15 +3690,9 @@
develop(bool, TraceDefaultMethods, false, \
"Trace the default method processing steps") \
\
- develop(bool, ParseAllGenericSignatures, false, \
- "Parse all generic signatures while classloading") \
- \
develop(bool, VerifyGenericSignatures, false, \
"Abort VM on erroneous or inconsistent generic signatures") \
\
- product(bool, ParseGenericDefaults, false, \
- "Parse generic signatures for default method handling") \
- \
product(bool, UseVMInterruptibleIO, false, \
"(Unstable, Solaris-specific) Thread interrupt before or with " \
"EINTR for I/O operations results in OS_INTRPT. The default value"\
--- a/hotspot/src/share/vm/runtime/globals_extension.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/runtime/globals_extension.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -57,6 +57,7 @@
#define C1_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define C1_PD_PRODUCT_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name),
+#define C1_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#ifdef PRODUCT
#define C1_DEVELOP_FLAG_MEMBER(type, name, value, doc) /* flag is constant */
#define C1_PD_DEVELOP_FLAG_MEMBER(type, name, doc) /* flag is constant */
@@ -99,7 +100,7 @@
G1_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_EXPERIMENTAL_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER, RUNTIME_MANAGEABLE_FLAG_MEMBER, RUNTIME_PRODUCT_RW_FLAG_MEMBER)
#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
- C1_FLAGS(C1_DEVELOP_FLAG_MEMBER, C1_PD_DEVELOP_FLAG_MEMBER, C1_PRODUCT_FLAG_MEMBER, C1_PD_PRODUCT_FLAG_MEMBER, C1_NOTPRODUCT_FLAG_MEMBER)
+ C1_FLAGS(C1_DEVELOP_FLAG_MEMBER, C1_PD_DEVELOP_FLAG_MEMBER, C1_PRODUCT_FLAG_MEMBER, C1_PD_PRODUCT_FLAG_MEMBER, C1_DIAGNOSTIC_FLAG_MEMBER, C1_NOTPRODUCT_FLAG_MEMBER)
#endif
#ifdef COMPILER2
C2_FLAGS(C2_DEVELOP_FLAG_MEMBER, C2_PD_DEVELOP_FLAG_MEMBER, C2_PRODUCT_FLAG_MEMBER, C2_PD_PRODUCT_FLAG_MEMBER, C2_DIAGNOSTIC_FLAG_MEMBER, C2_EXPERIMENTAL_FLAG_MEMBER, C2_NOTPRODUCT_FLAG_MEMBER)
@@ -131,6 +132,7 @@
#define C1_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define C1_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type),
+#define C1_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#ifdef PRODUCT
#define C1_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) /* flag is constant */
#define C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc) /* flag is constant */
@@ -204,6 +206,7 @@
C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
C1_PRODUCT_FLAG_MEMBER_WITH_TYPE,
C1_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE,
+ C1_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE)
#endif
#ifdef COMPILER2
--- a/hotspot/src/share/vm/runtime/handles.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/runtime/handles.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -179,11 +179,11 @@
_thread->set_last_handle_mark(previous_handle_mark());
}
-void* HandleMark::operator new(size_t size) {
+void* HandleMark::operator new(size_t size) throw() {
return AllocateHeap(size, mtThread);
}
-void* HandleMark::operator new [] (size_t size) {
+void* HandleMark::operator new [] (size_t size) throw() {
return AllocateHeap(size, mtThread);
}
--- a/hotspot/src/share/vm/runtime/handles.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/runtime/handles.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -309,8 +309,8 @@
// called in the destructor of HandleMarkCleaner
void pop_and_restore();
// overloaded operators
- void* operator new(size_t size);
- void* operator new [](size_t size);
+ void* operator new(size_t size) throw();
+ void* operator new [](size_t size) throw();
void operator delete(void* p);
void operator delete[](void* p);
};
--- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -56,7 +56,7 @@
}
private:
- inline void* operator new(size_t size, void* ptr) {
+ inline void* operator new(size_t size, void* ptr) throw() {
return ptr;
}
};
@@ -471,16 +471,6 @@
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 }
--- a/hotspot/src/share/vm/runtime/objectMonitor.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/runtime/objectMonitor.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -312,10 +312,10 @@
public:
static int Knob_Verbose;
static int Knob_SpinLimit;
- void* operator new (size_t size) {
+ void* operator new (size_t size) throw() {
return AllocateHeap(size, mtInternal);
}
- void* operator new[] (size_t size) {
+ void* operator new[] (size_t size) throw() {
return operator new (size);
}
void operator delete(void* p) {
--- a/hotspot/src/share/vm/runtime/os.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/runtime/os.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -1485,44 +1485,6 @@
return result;
}
-// Read file line by line, if line is longer than bsize,
-// skip rest of line.
-int os::get_line_chars(int fd, char* buf, const size_t bsize){
- size_t sz, i = 0;
-
- // read until EOF, EOL or buf is full
- while ((sz = (int) read(fd, &buf[i], 1)) == 1 && i < (bsize-2) && buf[i] != '\n') {
- ++i;
- }
-
- if (buf[i] == '\n') {
- // EOL reached so ignore EOL character and return
-
- buf[i] = 0;
- return (int) i;
- }
-
- buf[i+1] = 0;
-
- if (sz != 1) {
- // EOF reached. if we read chars before EOF return them and
- // return EOF on next call otherwise return EOF
-
- return (i == 0) ? -1 : (int) i;
- }
-
- // line is longer than size of buf, skip to EOL
- char ch;
- while (read(fd, &ch, 1) == 1 && ch != '\n') {
- // Do nothing
- }
-
- // return initial part of line that fits in buf.
- // If we reached EOF, it will be returned on next call.
-
- return (int) i;
-}
-
void os::SuspendedThreadTask::run() {
assert(Threads_lock->owned_by_self() || (_thread == VMThread::vm_thread()), "must have threads lock to call this");
internal_do_task();
--- a/hotspot/src/share/vm/runtime/os.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/runtime/os.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -738,10 +738,6 @@
// Hook for os specific jvm options that we don't want to abort on seeing
static bool obsolete_option(const JavaVMOption *option);
- // Read file line by line. If line is longer than bsize,
- // rest of line is skipped. Returns number of bytes read or -1 on EOF
- static int get_line_chars(int fd, char *buf, const size_t bsize);
-
// Extensions
#include "runtime/os_ext.hpp"
--- a/hotspot/src/share/vm/runtime/park.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/runtime/park.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -140,7 +140,7 @@
// well as bank access imbalance on Niagara-like platforms,
// although Niagara's hash function should help.
-void * ParkEvent::operator new (size_t sz) {
+void * ParkEvent::operator new (size_t sz) throw() {
return (void *) ((intptr_t (AllocateHeap(sz + 256, mtInternal, CALLER_PC)) + 256) & -256) ;
}
--- a/hotspot/src/share/vm/runtime/park.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/runtime/park.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, 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
@@ -166,7 +166,7 @@
// aligned on 256-byte address boundaries. This ensures that the least
// significant byte of a ParkEvent address is always 0.
- void * operator new (size_t sz) ;
+ void * operator new (size_t sz) throw();
void operator delete (void * a) ;
public:
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -1051,7 +1051,8 @@
// Find receiver for non-static call
if (bc != Bytecodes::_invokestatic &&
- bc != Bytecodes::_invokedynamic) {
+ bc != Bytecodes::_invokedynamic &&
+ bc != Bytecodes::_invokehandle) {
// This register map must be update since we need to find the receiver for
// compiled frames. The receiver might be in a register.
RegisterMap reg_map2(thread);
@@ -1078,7 +1079,7 @@
#ifdef ASSERT
// Check that the receiver klass is of the right subtype and that it is initialized for virtual calls
- if (bc != Bytecodes::_invokestatic && bc != Bytecodes::_invokedynamic) {
+ if (bc != Bytecodes::_invokestatic && bc != Bytecodes::_invokedynamic && bc != Bytecodes::_invokehandle) {
assert(receiver.not_null(), "should have thrown exception");
KlassHandle receiver_klass(THREAD, receiver->klass());
Klass* rk = constants->klass_ref_at(bytecode_index, CHECK_(nullHandle));
@@ -1240,9 +1241,9 @@
#endif
if (is_virtual) {
- assert(receiver.not_null(), "sanity check");
+ assert(receiver.not_null() || invoke_code == Bytecodes::_invokehandle, "sanity check");
bool static_bound = call_info.resolved_method()->can_be_statically_bound();
- KlassHandle h_klass(THREAD, receiver->klass());
+ KlassHandle h_klass(THREAD, invoke_code == Bytecodes::_invokehandle ? NULL : receiver->klass());
CompiledIC::compute_monomorphic_entry(callee_method, h_klass,
is_optimized, static_bound, virtual_call_info,
CHECK_(methodHandle()));
--- a/hotspot/src/share/vm/runtime/thread.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -3636,6 +3636,16 @@
CompileBroker::compilation_init();
#endif
+ if (EnableInvokeDynamic) {
+ // Pre-initialize some JSR292 core classes to avoid deadlock during class loading.
+ // It is done after compilers are initialized, because otherwise compilations of
+ // signature polymorphic MH intrinsics can be missed
+ // (see SystemDictionary::find_method_handle_intrinsic).
+ initialize_class(vmSymbols::java_lang_invoke_MethodHandle(), CHECK_0);
+ initialize_class(vmSymbols::java_lang_invoke_MemberName(), CHECK_0);
+ initialize_class(vmSymbols::java_lang_invoke_MethodHandleNatives(), CHECK_0);
+ }
+
#if INCLUDE_MANAGEMENT
Management::initialize(THREAD);
#endif // INCLUDE_MANAGEMENT
--- a/hotspot/src/share/vm/runtime/thread.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/runtime/thread.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -113,8 +113,9 @@
// Support for forcing alignment of thread objects for biased locking
void* _real_malloc_address;
public:
- void* operator new(size_t size) { return allocate(size, true); }
- void* operator new(size_t size, const std::nothrow_t& nothrow_constant) { return allocate(size, false); }
+ void* operator new(size_t size) throw() { return allocate(size, true); }
+ void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() {
+ return allocate(size, false); }
void operator delete(void* p);
protected:
--- a/hotspot/src/share/vm/services/memRecorder.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/services/memRecorder.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -53,13 +53,13 @@
}
}
- void* operator new(size_t size, const std::nothrow_t& nothrow_constant) {
+ void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() {
// the instance is part of memRecorder, needs to be tagged with 'otNMTRecorder'
// to avoid recursion
return os::malloc(size, (mtNMT | otNMTRecorder));
}
- void* operator new(size_t size) {
+ void* operator new(size_t size) throw() {
assert(false, "use nothrow version");
return NULL;
}
--- a/hotspot/src/share/vm/services/memTrackWorker.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/services/memTrackWorker.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -63,12 +63,12 @@
}
}
-void* MemTrackWorker::operator new(size_t size) {
+void* MemTrackWorker::operator new(size_t size) throw() {
assert(false, "use nothrow version");
return NULL;
}
-void* MemTrackWorker::operator new(size_t size, const std::nothrow_t& nothrow_constant) {
+void* MemTrackWorker::operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() {
return allocate(size, false, mtNMT);
}
--- a/hotspot/src/share/vm/services/memTrackWorker.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/services/memTrackWorker.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -90,8 +90,8 @@
public:
MemTrackWorker(MemSnapshot* snapshot);
~MemTrackWorker();
- _NOINLINE_ void* operator new(size_t size);
- _NOINLINE_ void* operator new(size_t size, const std::nothrow_t& nothrow_constant);
+ _NOINLINE_ void* operator new(size_t size) throw();
+ _NOINLINE_ void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw();
void start();
void run();
--- a/hotspot/src/share/vm/utilities/accessFlags.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/utilities/accessFlags.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -78,11 +78,13 @@
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 @@
{ 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; }
--- a/hotspot/src/share/vm/utilities/array.hpp Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/src/share/vm/utilities/array.hpp Fri Sep 20 19:15:59 2013 -0700
@@ -317,7 +317,7 @@
Array(const Array<T>&);
void operator=(const Array<T>&);
- void* operator new(size_t size, ClassLoaderData* loader_data, int length, bool read_only, TRAPS) {
+ void* operator new(size_t size, ClassLoaderData* loader_data, int length, bool read_only, TRAPS) throw() {
size_t word_size = Array::size(length);
return (void*) Metaspace::allocate(loader_data, word_size, read_only,
MetaspaceObj::array_type(sizeof(T)), CHECK_NULL);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/gcbarriers/G1CrashTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,84 @@
+/*
+ * 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 8023472
+ * @summary C2 optimization breaks with G1
+ *
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -Dcount=100000 G1CrashTest
+ *
+ * @author pbiswal@palantir.com
+ */
+
+public class G1CrashTest {
+ static Object[] set = new Object[11];
+
+ public static void main(String[] args) throws InterruptedException {
+ for (int j = 0; j < Integer.getInteger("count"); j++) {
+ Object key = new Object();
+ insertKey(key);
+ if (j > set.length / 2) {
+ Object[] oldKeys = set;
+ set = new Object[2 * set.length - 1];
+ for (Object o : oldKeys) {
+ if (o != null)
+ insertKey(o);
+ }
+ }
+ }
+ }
+
+ static void insertKey(Object key) {
+ int hash = key.hashCode() & 0x7fffffff;
+ int index = hash % set.length;
+ Object cur = set[index];
+ if (cur == null)
+ set[index] = key;
+ else
+ insertKeyRehash(key, index, hash, cur);
+ }
+
+ static void insertKeyRehash(Object key, int index, int hash, Object cur) {
+ int loopIndex = index;
+ int firstRemoved = -1;
+ do {
+ if (cur == "dead")
+ firstRemoved = 1;
+ index--;
+ if (index < 0)
+ index += set.length;
+ cur = set[index];
+ if (cur == null) {
+ if (firstRemoved != -1)
+ set[firstRemoved] = "dead";
+ else
+ set[index] = key;
+ return;
+ }
+ } while (index != loopIndex);
+ if (firstRemoved != -1)
+ set[firstRemoved] = null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jsr292/ConcurrentClassLoadingTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,194 @@
+/*
+ * 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 8022595
+ * @summary JSR292: deadlock during class loading of MethodHandles, MethodHandleImpl & MethodHandleNatives
+ *
+ * @run main/othervm ConcurrentClassLoadingTest
+ */
+import java.util.*;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+
+public class ConcurrentClassLoadingTest {
+ int numThreads = 0;
+ long seed = 0;
+ CyclicBarrier l;
+ Random rand;
+
+ public static void main(String[] args) throws Throwable {
+ ConcurrentClassLoadingTest test = new ConcurrentClassLoadingTest();
+ test.parseArgs(args);
+ test.run();
+ }
+
+ void parseArgs(String[] args) {
+ int i = 0;
+ while (i < args.length) {
+ String flag = args[i];
+ switch(flag) {
+ case "-seed":
+ seed = Long.parseLong(args[++i]);
+ break;
+ case "-numThreads":
+ numThreads = Integer.parseInt(args[++i]);
+ break;
+ default:
+ throw new Error("Unknown flag: " + flag);
+ }
+ ++i;
+ }
+ }
+
+ void init() {
+ if (numThreads == 0) {
+ numThreads = Runtime.getRuntime().availableProcessors();
+ }
+
+ if (seed == 0) {
+ seed = (new Random()).nextLong();
+ }
+ rand = new Random(seed);
+
+ l = new CyclicBarrier(numThreads + 1);
+
+ System.out.printf("Threads: %d\n", numThreads);
+ System.out.printf("Seed: %d\n", seed);
+ }
+
+ final List<Loader> loaders = new ArrayList<>();
+
+ void prepare() {
+ List<String> c = new ArrayList<>(Arrays.asList(classNames));
+
+ // Split classes between loading threads
+ int count = (classNames.length / numThreads) + 1;
+ for (int t = 0; t < numThreads; t++) {
+ List<String> sel = new ArrayList<>();
+
+ System.out.printf("Thread #%d:\n", t);
+ for (int i = 0; i < count; i++) {
+ if (c.size() == 0) break;
+
+ int k = rand.nextInt(c.size());
+ String elem = c.remove(k);
+ sel.add(elem);
+ System.out.printf("\t%s\n", elem);
+ }
+ loaders.add(new Loader(sel));
+ }
+
+ // Print diagnostic info when the test hangs
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ public void run() {
+ boolean alive = false;
+ for (Loader l : loaders) {
+ if (!l.isAlive()) continue;
+
+ if (!alive) {
+ System.out.println("Some threads are still alive:");
+ alive = true;
+ }
+
+ System.out.println(l.getName());
+ for (StackTraceElement elem : l.getStackTrace()) {
+ System.out.println("\t"+elem.toString());
+ }
+ }
+ }
+ });
+ }
+
+ public void run() throws Throwable {
+ init();
+ prepare();
+
+ for (Loader loader : loaders) {
+ loader.start();
+ }
+
+ l.await();
+
+ for (Loader loader : loaders) {
+ loader.join();
+ }
+ }
+
+ class Loader extends Thread {
+ List<String> classes;
+
+ public Loader(List<String> classes) {
+ this.classes = classes;
+ setDaemon(true);
+ }
+
+ @Override
+ public void run() {
+ try {
+ l.await();
+
+ for (String name : classes) {
+ Class.forName(name).getName();
+ }
+ } catch (ClassNotFoundException | BrokenBarrierException | InterruptedException e) {
+ throw new Error(e);
+ }
+ }
+ }
+
+ final static String[] classNames = {
+ "java.lang.invoke.AbstractValidatingLambdaMetafactory",
+ "java.lang.invoke.BoundMethodHandle",
+ "java.lang.invoke.CallSite",
+ "java.lang.invoke.ConstantCallSite",
+ "java.lang.invoke.DirectMethodHandle",
+ "java.lang.invoke.InnerClassLambdaMetafactory",
+ "java.lang.invoke.InvokeDynamic",
+ "java.lang.invoke.InvokeGeneric",
+ "java.lang.invoke.InvokerBytecodeGenerator",
+ "java.lang.invoke.Invokers",
+ "java.lang.invoke.LambdaConversionException",
+ "java.lang.invoke.LambdaForm",
+ "java.lang.invoke.LambdaMetafactory",
+ "java.lang.invoke.MagicLambdaImpl",
+ "java.lang.invoke.MemberName",
+ "java.lang.invoke.MethodHandle",
+ "java.lang.invoke.MethodHandleImpl",
+ "java.lang.invoke.MethodHandleInfo",
+ "java.lang.invoke.MethodHandleNatives",
+ "java.lang.invoke.MethodHandleProxies",
+ "java.lang.invoke.MethodHandles",
+ "java.lang.invoke.MethodHandleStatics",
+ "java.lang.invoke.MethodType",
+ "java.lang.invoke.MethodTypeForm",
+ "java.lang.invoke.MutableCallSite",
+ "java.lang.invoke.SerializedLambda",
+ "java.lang.invoke.SimpleMethodHandle",
+ "java.lang.invoke.SwitchPoint",
+ "java.lang.invoke.TypeConvertingMethodAdapter",
+ "java.lang.invoke.VolatileCallSite",
+ "java.lang.invoke.WrongMethodTypeException"
+ };
+}
--- a/hotspot/test/gc/TestVerifyDuringStartup.java Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/test/gc/TestVerifyDuringStartup.java Fri Sep 20 19:15:59 2013 -0700
@@ -48,7 +48,7 @@
"-XX:+VerifyDuringStartup",
"-version"});
- System.out.print("Testing:\n" + JDKToolFinder.getJDKTool("java"));
+ System.out.print("Testing:\n" + JDKToolFinder.getCurrentJDKTool("java"));
for (int i = 0; i < vmOpts.size(); i += 1) {
System.out.print(" " + vmOpts.get(i));
}
--- a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java Fri Sep 20 19:15:59 2013 -0700
@@ -51,9 +51,8 @@
output.shouldHaveExitValue(0);
} catch (RuntimeException e) {
- // Report 'passed' if CDS was turned off because we could not allocate
- // the klass metaspace at an address that would work with CDS.
- output.shouldContain("Could not allocate metaspace at a compatible address");
+ // Report 'passed' if CDS was turned off.
+ output.shouldContain("Unable to use shared archive");
output.shouldHaveExitValue(1);
}
}
--- a/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java Fri Sep 20 19:15:59 2013 -0700
@@ -69,7 +69,7 @@
"-server", "-Xshare:on", "-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=./sample.jsa", "-version");
output = new OutputAnalyzer(pb.start());
- output.shouldContain("Could not allocate metaspace at a compatible address");
+ output.shouldContain("Unable to use shared archive");
output.shouldHaveExitValue(1);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/InitialThreadOverflow/DoOverflow.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+public class DoOverflow {
+
+ static int count;
+
+ public void overflow() {
+ count+=1;
+ overflow();
+ }
+
+ public static void printIt() {
+ System.out.println("Going to overflow stack");
+ try {
+ new DoOverflow().overflow();
+ } catch(java.lang.StackOverflowError e) {
+ System.out.println("Overflow OK " + count);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/InitialThreadOverflow/invoke.cxx Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+#include <assert.h>
+#include <jni.h>
+
+#include <pthread.h>
+
+JavaVM* jvm;
+
+void *
+floobydust (void *p) {
+ JNIEnv *env;
+
+ jvm->AttachCurrentThread((void**)&env, NULL);
+
+ jclass class_id = env->FindClass ("DoOverflow");
+ assert (class_id);
+
+ jmethodID method_id = env->GetStaticMethodID(class_id, "printIt", "()V");
+ assert (method_id);
+
+ env->CallStaticVoidMethod(class_id, method_id, NULL);
+
+ jvm->DetachCurrentThread();
+}
+
+int
+main (int argc, const char** argv) {
+ JavaVMOption options[1];
+ options[0].optionString = (char*) "-Xss320k";
+
+ JavaVMInitArgs vm_args;
+ vm_args.version = JNI_VERSION_1_2;
+ vm_args.ignoreUnrecognized = JNI_TRUE;
+ vm_args.options = options;
+ vm_args.nOptions = 1;
+
+ JNIEnv* env;
+ jint result = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
+ assert(result >= 0);
+
+ pthread_t thr;
+ pthread_create(&thr, NULL, floobydust, NULL);
+ pthread_join(thr, NULL);
+
+ floobydust(NULL);
+
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/InitialThreadOverflow/testme.sh Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,73 @@
+#!/bin/sh
+
+# Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+# @test testme.sh
+# @bug 8009062
+# @summary Poor performance of JNI AttachCurrentThread after fix for 7017193
+# @compile DoOverflow.java
+# @run shell testme.sh
+
+set -x
+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
+
+if [ "${VM_OS}" != "linux" ]
+then
+ echo "Test only valid for Linux"
+ exit 0
+fi
+
+gcc_cmd=`which gcc`
+if [ "x$gcc_cmd" == "x" ]; then
+ echo "WARNING: gcc not found. Cannot execute test." 2>&1
+ exit 0;
+fi
+
+CFLAGS="-m${VM_BITS}"
+
+LD_LIBRARY_PATH=.:${COMPILEJAVA}/jre/lib/${VM_CPU}/${VM_TYPE}:/usr/lib:$LD_LIBRARY_PATH
+export LD_LIBRARY_PATH
+
+cp ${TESTSRC}${FS}invoke.cxx .
+
+# Copy the result of our @compile action:
+cp ${TESTCLASSES}${FS}DoOverflow.class .
+
+echo "Compilation flag: ${COMP_FLAG}"
+# Note pthread may not be found thus invoke creation will fail to be created.
+# Check to ensure you have a /usr/lib/libpthread.so if you don't please look
+# for /usr/lib/`uname -m`-linux-gnu version ensure to add that path to below compilation.
+
+$gcc_cmd -DLINUX ${CFLAGS} -o invoke \
+ -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \
+ -L${COMPILEJAVA}/jre/lib/${VM_CPU}/${VM_TYPE} \
+ -ljvm -lpthread invoke.cxx
+
+./invoke
+exit $?
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/LoadClass/LoadClassNegative.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,51 @@
+/*
+ * 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
+ * @key regression
+ * @bug 8020675
+ * @summary make sure there is no fatal error if a class is loaded from an invalid jar file which is in the bootclasspath
+ * @library /testlibrary
+ * @build TestForName
+ * @build LoadClassNegative
+ * @run main LoadClassNegative
+ */
+
+import java.io.File;
+import com.oracle.java.testlibrary.*;
+
+public class LoadClassNegative {
+
+ public static void main(String args[]) throws Exception {
+ String bootCP = "-Xbootclasspath/a:" + System.getProperty("test.src")
+ + File.separator + "dummy.jar";
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ bootCP,
+ "TestForName");
+
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("ClassNotFoundException");
+ output.shouldHaveExitValue(0);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/LoadClass/TestForName.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+public class TestForName {
+ public static void main(String[] args) {
+ try {
+ Class cls = Class.forName("xxx");
+ System.out.println("Class = " + cls.getName());
+ } catch (ClassNotFoundException cnfe) {
+ cnfe.printStackTrace();
+ }
+ }
+}
--- a/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java Fri Sep 20 19:15:59 2013 -0700
@@ -84,7 +84,7 @@
// there is a chance such reservation will fail
// If it does, it is NOT considered a failure of the feature,
// rather a possible expected outcome, though not likely
- output.shouldContain("Could not allocate metaspace at a compatible address");
+ output.shouldContain("Unable to use shared archive");
output.shouldHaveExitValue(1);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/contended/Options.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,103 @@
+/*
+ * 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 8006997
+ * @summary ContendedPaddingWidth should be range-checked
+ *
+ * @library /testlibrary
+ * @run main Options
+ */
+public class Options {
+
+ public static void main(String[] args) throws Exception {
+ ProcessBuilder pb;
+ OutputAnalyzer output;
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=-128", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("ContendedPaddingWidth");
+ output.shouldContain("must be in between");
+ output.shouldHaveExitValue(1);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=-8", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("ContendedPaddingWidth");
+ output.shouldContain("must be in between");
+ output.shouldHaveExitValue(1);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=-1", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("ContendedPaddingWidth");
+ output.shouldContain("must be in between");
+ output.shouldContain("must be a multiple of 8");
+ output.shouldHaveExitValue(1);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=0", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=1", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("ContendedPaddingWidth");
+ output.shouldContain("must be a multiple of 8");
+ output.shouldHaveExitValue(1);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=8", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=8184", "-version"); // 8192-8 = 8184
+ output = new OutputAnalyzer(pb.start());
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=8191", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("ContendedPaddingWidth");
+ output.shouldContain("must be a multiple of 8");
+ output.shouldHaveExitValue(1);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=8192", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=8193", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("ContendedPaddingWidth");
+ output.shouldContain("must be in between");
+ output.shouldContain("must be a multiple of 8");
+ output.shouldHaveExitValue(1);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=8200", "-version"); // 8192+8 = 8200
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("ContendedPaddingWidth");
+ output.shouldContain("must be in between");
+ output.shouldHaveExitValue(1);
+
+ }
+
+}
+
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java Fri Sep 20 17:11:32 2013 -0700
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java Fri Sep 20 19:15:59 2013 -0700
@@ -27,24 +27,43 @@
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 compile.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("compile.jdk");
+ if (binPath == null) {
+ throw new RuntimeException("System property 'compile.jdk' not set. "
+ + "This property is normally set by jtreg. "
+ + "When running test separately, set this property using "
+ + "'-Dcompile.jdk=/path/to/jdk'.");
+ }
+ binPath += File.separatorChar + "bin" + File.separatorChar + tool;
- return binPath;
- }
+ return binPath;
+ }
+ /**
+ * Returns the full path to an executable in <current jdk>/bin based
+ * on System property {@code test.jdk} (set by jtreg test suite)
+ *
+ * @return Full path to an executable in jdk/bin
+ */
+ public static String getCurrentJDKTool(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'.");
+ }
+ binPath += File.separatorChar + "bin" + File.separatorChar + tool;
+
+ return binPath;
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ctw/Makefile Fri Sep 20 19:15:59 2013 -0700
@@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ctw/README Fri Sep 20 19:15:59 2013 -0700
@@ -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 '<dir>/*' 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
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java Fri Sep 20 19:15:59 2013 -0700
@@ -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<Path> {
+
+ private final Set<Path> 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;
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java Fri Sep 20 19:15:59 2013 -0700
@@ -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<JarEntry> 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));
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java Fri Sep 20 19:15:59 2013 -0700
@@ -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<Path> ds
+ = Files.newDirectoryStream(root, "*.jar")) {
+ for (Path p : ds) {
+ new ClassPathJarEntry(p, executor).process();
+ if (isFinished()) {
+ return;
+ }
+ }
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java Fri Sep 20 19:15:59 2013 -0700
@@ -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();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java Fri Sep 20 19:15:59 2013 -0700
@@ -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<Runnable> 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();
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java Fri Sep 20 19:15:59 2013 -0700
@@ -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);
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java Fri Sep 20 19:15:59 2013 -0700
@@ -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.
+ * <p/>
+ * 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();
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java Fri Sep 20 19:15:59 2013 -0700
@@ -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, '.');
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ctw/test/Bar.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,5 @@
+public class Bar {
+ private static void staticMethod() { }
+ public void method() { }
+ protected Bar() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ctw/test/ClassesDirTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ctw/test/ClassesListTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ctw/test/CtwTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -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<String> args = new ArrayList<>();
+ args.add(javapath);
+ Collections.addAll(args, command);
+
+ return new ProcessBuilder(args.toArray(new String[args.size()]));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ctw/test/Foo.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,5 @@
+public class Foo {
+ private static void staticMethod() { }
+ public void method() { }
+ protected Foo() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ctw/test/JarDirTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -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);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ctw/test/JarsTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -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);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ctw/test/classes.lst Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,4 @@
+java.lang.String
+java.lang.Object
+Foo
+Bar
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/whitebox/Makefile Fri Sep 20 19:15:59 2013 -0700
@@ -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)
--- a/jaxp/.hgtags Fri Sep 20 17:11:32 2013 -0700
+++ b/jaxp/.hgtags Fri Sep 20 19:15:59 2013 -0700
@@ -227,3 +227,5 @@
b1ceab582fc6d795b20aaa8a3fde2eba34af9399 jdk8-b103
a22fe9bd01e6c7e7ddc7995dfc9471711692b8d1 jdk8-b104
09a46ec11f880154886c70be03aff5ab2ddf0ab7 jdk8-b105
+d3be8e3b429df917e72c1c23e7920c651219b587 jdk8-b106
+d6a32e3831aab20a9a3bc78cdc0a60aaad725c6c jdk8-b107
--- a/jaxws/.hgtags Fri Sep 20 17:11:32 2013 -0700
+++ b/jaxws/.hgtags Fri Sep 20 19:15:59 2013 -0700
@@ -227,3 +227,5 @@
6cdc6ed987801c175a1217d0d3e53c3bd69ba52e jdk8-b103
42211ab0ab1cca51a050d184634cf1db7ef81fbf jdk8-b104
88390df7ed2cf128298a02c5e6d978f0a603cd58 jdk8-b105
+6908370afe834ff01739e8ec992d4246c74b7e6e jdk8-b106
+e3c9328f75638289a342ce15fbe532f05078946e jdk8-b107
--- a/jdk/.hgtags Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/.hgtags Fri Sep 20 19:15:59 2013 -0700
@@ -228,3 +228,5 @@
f1d8d15bfcb5ada858a942f8a31f6598f23214d1 jdk8-b104
1fe211ae3d2b8cc2dfc4f58d9a6eb96418679672 jdk8-b105
c817276bd870dfe1dcc3a3dbbc092436b6907f75 jdk8-b106
+eea685b9ccaa1980e0a7e07d6a3a84bcc7e9ab82 jdk8-b107
+006aaa5f069e7dd98fccdc696866c9f8582c087c jdk8-b108
--- a/jdk/make/Makefile Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/make/Makefile Fri Sep 20 19:15:59 2013 -0700
@@ -99,7 +99,6 @@
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_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)
--- a/jdk/make/common/Defs-windows.gmk Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/make/common/Defs-windows.gmk Fri Sep 20 19:15:59 2013 -0700
@@ -78,8 +78,6 @@
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 !=
--- a/jdk/make/common/Sanity.gmk Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/make/common/Sanity.gmk Fri Sep 20 19:15:59 2013 -0700
@@ -65,7 +65,6 @@
sane-libCrun \
sane-unixccs_path \
sane-msdevtools_path \
- sane-dxsdk \
sane-compiler \
sane-cacerts \
sane-ant_version \
--- a/jdk/make/common/shared/Defs-versions.gmk Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/make/common/shared/Defs-versions.gmk Fri Sep 20 19:15:59 2013 -0700
@@ -74,9 +74,6 @@
# 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 @@
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
--- a/jdk/make/common/shared/Defs-windows.gmk Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/make/common/shared/Defs-windows.gmk Fri Sep 20 19:15:59 2013 -0700
@@ -79,7 +79,7 @@
# 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 @@
_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 @@
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))"
--- a/jdk/make/common/shared/Sanity-Settings.gmk Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/make/common/shared/Sanity-Settings.gmk Fri Sep 20 19:15:59 2013 -0700
@@ -234,10 +234,6 @@
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)
--- a/jdk/make/common/shared/Sanity.gmk Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/make/common/shared/Sanity.gmk Fri Sep 20 19:15:59 2013 -0700
@@ -143,8 +143,6 @@
_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
@@ -1301,51 +1299,6 @@
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)
######################################################
ifeq ($(PLATFORM), windows)
--- a/jdk/make/javax/sound/jsoundds/Makefile Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/make/javax/sound/jsoundds/Makefile Fri Sep 20 19:15:59 2013 -0700
@@ -55,8 +55,7 @@
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.
--- a/jdk/make/jdk_generic_profile.sh Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/make/jdk_generic_profile.sh Fri Sep 20 19:15:59 2013 -0700
@@ -80,7 +80,6 @@
# ALT_BOOTDIR
# Windows Only:
# ALT_UNIXCOMMAND_PATH
-# ALT_DXSDK_PATH
# ALT_MSVCRNN_DLL_PATH
#
#############################################################################
--- a/jdk/make/netbeans/awt2d/README Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/make/netbeans/awt2d/README Fri Sep 20 19:15:59 2013 -0700
@@ -39,7 +39,6 @@
(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 @@
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 @@
../../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 @@
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,
--- a/jdk/make/sun/awt/Makefile Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/make/sun/awt/Makefile Fri Sep 20 19:15:59 2013 -0700
@@ -564,7 +564,6 @@
-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 \
--- a/jdk/make/sun/cmm/lcms/mapfile-vers Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/make/sun/cmm/lcms/mapfile-vers Fri Sep 20 19:15:59 2013 -0700
@@ -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;
--- a/jdk/make/sun/jawt/Makefile Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/make/sun/jawt/Makefile Fri Sep 20 19:15:59 2013 -0700
@@ -69,7 +69,6 @@
# 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 \
--- a/jdk/makefiles/CompileNativeLibraries.gmk Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/makefiles/CompileNativeLibraries.gmk Fri Sep 20 19:15:59 2013 -0700
@@ -474,7 +474,6 @@
$(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
@@ -1484,8 +1483,7 @@
-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),\
@@ -2963,8 +2961,7 @@
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,\
--- a/jdk/makefiles/mapfiles/liblcms/mapfile-vers Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/makefiles/mapfiles/liblcms/mapfile-vers Fri Sep 20 19:15:59 2013 -0700
@@ -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;
--- a/jdk/src/macosx/native/sun/awt/CTextPipe.m Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/macosx/native/sun/awt/CTextPipe.m Fri Sep 20 19:15:59 2013 -0700
@@ -145,11 +145,6 @@
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 @@
}
// 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
--- a/jdk/src/share/classes/java/awt/color/ICC_Profile.java Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/share/classes/java/awt/color/ICC_Profile.java Fri Sep 20 19:15:59 2013 -0700
@@ -37,6 +37,7 @@
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 @@
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 @@
/**
* 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 @@
* 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 static ICC_Profile getInstance(byte[] data) {
ICC_Profile thisProfile;
- long theID;
+ Profile p = null;
if (ProfileDeferralMgr.deferring) {
ProfileDeferralMgr.activateProfiles();
@@ -779,32 +780,32 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
ProfileDeferralMgr.activateProfiles();
}
- CMSManager.getModule().setTagData(ID, tagSignature, tagData);
+ CMSManager.getModule().setTagData(cmmProfile, tagSignature, tagData);
}
/**
--- a/jdk/src/share/classes/java/awt/color/ICC_ProfileGray.java Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/share/classes/java/awt/color/ICC_ProfileGray.java Fri Sep 20 19:15:59 2013 -0700
@@ -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 @@
/**
* Constructs a new ICC_ProfileGray from a CMM ID.
*/
- ICC_ProfileGray(long ID) {
- super(ID);
+ ICC_ProfileGray(Profile p) {
+ super(p);
}
/**
--- a/jdk/src/share/classes/java/awt/color/ICC_ProfileRGB.java Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/share/classes/java/awt/color/ICC_ProfileRGB.java Fri Sep 20 19:15:59 2013 -0700
@@ -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 @@
* @param ID The CMM ID for the profile.
*
*/
- ICC_ProfileRGB(long ID) {
- super(ID);
+ ICC_ProfileRGB(Profile p) {
+ super(p);
}
/**
--- a/jdk/src/share/classes/sun/java2d/cmm/CMSManager.java Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/share/classes/sun/java2d/cmm/CMSManager.java Fri Sep 20 19:15:59 2013 -0700
@@ -104,53 +104,53 @@
cName = tcmm.getClass().getName();
}
- public long loadProfile(byte[] data) {
+ public Profile loadProfile(byte[] data) {
System.err.print(cName + ".loadProfile");
- long profileID = tcmm.loadProfile(data);
- System.err.printf("(ID=%x)\n", profileID);
- return profileID;
+ Profile p = tcmm.loadProfile(data);
+ System.err.printf("(ID=%s)\n", p.toString());
+ return p;
}
- public void freeProfile(long profileID) {
- System.err.printf(cName + ".freeProfile(ID=%x)\n", profileID);
- tcmm.freeProfile(profileID);
+ public void freeProfile(Profile p) {
+ System.err.printf(cName + ".freeProfile(ID=%s)\n", p.toString());
+ tcmm.freeProfile(p);
}
- public int getProfileSize(long profileID) {
- System.err.print(cName + ".getProfileSize(ID=" + profileID + ")");
- int size = tcmm.getProfileSize(profileID);
+ public int getProfileSize(Profile p) {
+ System.err.print(cName + ".getProfileSize(ID=" + p + ")");
+ int size = tcmm.getProfileSize(p);
System.err.println("=" + size);
return size;
}
- public void getProfileData(long profileID, byte[] data) {
- System.err.print(cName + ".getProfileData(ID=" + profileID + ") ");
+ public void getProfileData(Profile p, byte[] data) {
+ System.err.print(cName + ".getProfileData(ID=" + p + ") ");
System.err.println("requested " + data.length + " byte(s)");
- tcmm.getProfileData(profileID, data);
+ tcmm.getProfileData(p, data);
}
- public int getTagSize(long profileID, int tagSignature) {
+ public int getTagSize(Profile p, int tagSignature) {
System.err.printf(cName + ".getTagSize(ID=%x, TagSig=%s)",
- profileID, signatureToString(tagSignature));
- int size = tcmm.getTagSize(profileID, tagSignature);
+ p, signatureToString(tagSignature));
+ int size = tcmm.getTagSize(p, tagSignature);
System.err.println("=" + size);
return size;
}
- public void getTagData(long profileID, int tagSignature,
+ public void getTagData(Profile p, int tagSignature,
byte[] data) {
System.err.printf(cName + ".getTagData(ID=%x, TagSig=%s)",
- profileID, signatureToString(tagSignature));
+ p, signatureToString(tagSignature));
System.err.println(" requested " + data.length + " byte(s)");
- tcmm.getTagData(profileID, tagSignature, data);
+ tcmm.getTagData(p, tagSignature, data);
}
- public void setTagData(long profileID, int tagSignature,
+ public void setTagData(Profile p, int tagSignature,
byte[] data) {
- System.err.print(cName + ".setTagData(ID=" + profileID +
+ System.err.print(cName + ".setTagData(ID=" + p +
", TagSig=" + tagSignature + ")");
System.err.println(" sending " + data.length + " byte(s)");
- tcmm.setTagData(profileID, tagSignature, data);
+ tcmm.setTagData(p, tagSignature, data);
}
/* methods for creating ColorTransforms */
--- a/jdk/src/share/classes/sun/java2d/cmm/PCMM.java Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/share/classes/sun/java2d/cmm/PCMM.java Fri Sep 20 19:15:59 2013 -0700
@@ -32,13 +32,13 @@
public interface PCMM {
/* methods invoked from ICC_Profile */
- public long loadProfile(byte[] data);
- public void freeProfile(long profileID);
- public int getProfileSize(long profileID);
- public void getProfileData(long profileID, byte[] data);
- public void getTagData(long profileID, int tagSignature, byte[] data);
- public int getTagSize(long profileID, int tagSignature);
- public void setTagData(long profileID, int tagSignature, byte[] data);
+ public Profile loadProfile(byte[] data);
+ public void freeProfile(Profile p);
+ public int getProfileSize(Profile p);
+ public void getProfileData(Profile p, byte[] data);
+ public void getTagData(Profile p, int tagSignature, byte[] data);
+ public int getTagSize(Profile p, int tagSignature);
+ public void setTagData(Profile p, int tagSignature, byte[] data);
/* methods for creating ColorTransforms */
public ColorTransform createTransform(ICC_Profile profile, int renderType,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/java2d/cmm/Profile.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,43 @@
+/*
+ * 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 sun.java2d.cmm;
+
+import java.awt.color.CMMException;
+
+public class Profile {
+ private final long nativePtr;
+
+ protected Profile(long ptr) {
+ nativePtr = ptr;
+ }
+
+ protected final long getNativePtr() {
+ if (nativePtr == 0L) {
+ throw new CMMException("Invalid profile: ptr is null");
+ }
+ return nativePtr;
+ }
+}
--- a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java Fri Sep 20 19:15:59 2013 -0700
@@ -25,96 +25,139 @@
package sun.java2d.cmm.lcms;
+import java.awt.color.CMMException;
import java.awt.color.ICC_Profile;
-import java.util.Arrays;
-import java.util.HashMap;
import sun.java2d.cmm.ColorTransform;
import sun.java2d.cmm.PCMM;
+import sun.java2d.cmm.Profile;
+import sun.java2d.cmm.lcms.LCMSProfile.TagData;
public class LCMS implements PCMM {
/* methods invoked from ICC_Profile */
@Override
- public long loadProfile(byte[] data) {
- long id = loadProfileNative(data);
+ public Profile loadProfile(byte[] data) {
+ final Object disposerRef = new Object();
+
+ final long ptr = loadProfileNative(data, disposerRef);
- if (id != 0L) {
- if (profiles == null) {
- profiles = new HashMap<>();
- }
- profiles.put(id, new TagCache(id));
+ if (ptr != 0L) {
+ return new LCMSProfile(ptr, disposerRef);
}
- return id;
+ return null;
}
- private native long loadProfileNative(byte[] data);
+ private native long loadProfileNative(byte[] data, Object ref);
+
+ private LCMSProfile getLcmsProfile(Profile p) {
+ if (p instanceof LCMSProfile) {
+ return (LCMSProfile)p;
+ }
+ throw new CMMException("Invalid profile: " + p);
+ }
+
@Override
- public void freeProfile(long profileID) {
- TagCache c = profiles.remove(profileID);
- if (c != null) {
- c.clear();
+ public void freeProfile(Profile p) {
+ // we use disposer, so this method does nothing
+ }
+
+ @Override
+ public int getProfileSize(final Profile p) {
+ synchronized (p) {
+ return getProfileSizeNative(getLcmsProfile(p).getLcmsPtr());
}
- if (profiles.isEmpty()) {
- profiles = null;
- }
- freeProfileNative(profileID);
}
- private native void freeProfileNative(long profileID);
+ private native int getProfileSizeNative(long ptr);
- public native synchronized int getProfileSize(long profileID);
+ @Override
+ public void getProfileData(final Profile p, byte[] data) {
+ synchronized (p) {
+ getProfileDataNative(getLcmsProfile(p).getLcmsPtr(), data);
+ }
+ }
- public native synchronized void getProfileData(long profileID, byte[] data);
+ private native void getProfileDataNative(long ptr, byte[] data);
@Override
- public synchronized int getTagSize(long profileID, int tagSignature) {
- TagCache cache = profiles.get(profileID);
+ public int getTagSize(Profile p, int tagSignature) {
+ final LCMSProfile profile = getLcmsProfile(p);
- if (cache == null) {
- cache = new TagCache(profileID);
- profiles.put(profileID, cache);
+ synchronized (profile) {
+ TagData t = profile.getTag(tagSignature);
+ return t == null ? 0 : t.getSize();
}
-
- TagData t = cache.getTag(tagSignature);
- return t == null ? 0 : t.getSize();
}
- private static native byte[] getTagNative(long profileID, int signature);
+ static native byte[] getTagNative(long profileID, int signature);
@Override
- public synchronized void getTagData(long profileID, int tagSignature,
- byte[] data)
+ public void getTagData(Profile p, int tagSignature, byte[] data)
{
- TagCache cache = profiles.get(profileID);
+ final LCMSProfile profile = getLcmsProfile(p);
- if (cache == null) {
- cache = new TagCache(profileID);
- profiles.put(profileID, cache);
- }
-
- TagData t = cache.getTag(tagSignature);
- if (t != null) {
- t.copyDataTo(data);
+ synchronized (profile) {
+ TagData t = profile.getTag(tagSignature);
+ if (t != null) {
+ t.copyDataTo(data);
+ }
}
}
@Override
- public synchronized void setTagData(long profileID, int tagSignature, byte[] data) {
- TagCache cache = profiles.get(profileID);
+ public synchronized void setTagData(Profile p, int tagSignature, byte[] data) {
+ final LCMSProfile profile = getLcmsProfile(p);
+
+ synchronized (profile) {
+ profile.clearTagCache();
- if (cache != null) {
- cache.clear();
+ // Now we are going to update the profile with new tag data
+ // In some cases, we may change the pointer to the native
+ // profile.
+ //
+ // If we fail to write tag data for any reason, the old pointer
+ // should be used.
+ setTagDataNative(profile.getLcmsPtr(),
+ tagSignature, data);
}
- setTagDataNative(profileID, tagSignature, data);
}
- private native synchronized void setTagDataNative(long profileID, int tagSignature,
+ /**
+ * Writes supplied data as a tag into the profile.
+ * Destroys old profile, if new one was successfully
+ * created.
+ *
+ * Returns valid pointer to new profile.
+ *
+ * Throws CMMException if operation fails, preserve old profile from
+ * destruction.
+ */
+ private native void setTagDataNative(long ptr, int tagSignature,
byte[] data);
- public static native long getProfileID(ICC_Profile profile);
+ public synchronized static native LCMSProfile getProfileID(ICC_Profile profile);
+
+ /* Helper method used from LCMSColorTransfrom */
+ static long createTransform(
+ LCMSProfile[] profiles, int renderType,
+ int inFormatter, boolean isInIntPacked,
+ int outFormatter, boolean isOutIntPacked,
+ Object disposerRef)
+ {
+ long[] ptrs = new long[profiles.length];
- public static native long createNativeTransform(
+ for (int i = 0; i < profiles.length; i++) {
+ if (profiles[i] == null) throw new CMMException("Unknown profile ID");
+
+ ptrs[i] = profiles[i].getLcmsPtr();
+ }
+
+ return createNativeTransform(ptrs, renderType, inFormatter,
+ isInIntPacked, outFormatter, isOutIntPacked, disposerRef);
+ }
+
+ private static native long createNativeTransform(
long[] profileIDs, int renderType,
int inFormatter, boolean isInIntPacked,
int outFormatter, boolean isOutIntPacked,
@@ -175,59 +218,4 @@
return theLcms;
}
-
- private static class TagData {
- private int signature;
- private byte[] data;
-
- TagData(int sig, byte[] data) {
- this.signature = sig;
- this.data = data;
- }
-
- int getSize() {
- return data.length;
- }
-
- byte[] getData() {
- return Arrays.copyOf(data, data.length);
- }
-
- void copyDataTo(byte[] dst) {
- System.arraycopy(data, 0, dst, 0, data.length);
- }
-
- int getSignature() {
- return signature;
- }
- }
-
- private static class TagCache {
- private long profileID;
- private HashMap<Integer, TagData> tags;
-
- TagCache(long id) {
- profileID = id;
-
- tags = new HashMap<>();
- }
-
- TagData getTag(int sig) {
- TagData t = tags.get(sig);
- if (t == null) {
- byte[] tagData = getTagNative(profileID, sig);
- if (tagData != null) {
- t = new TagData(sig, tagData);
- tags.put(sig, t);
- }
- }
- return t;
- }
-
- void clear() {
- tags.clear();
- }
- }
-
- private static HashMap<Long, TagCache> profiles;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSProfile.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,109 @@
+/*
+ * 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 sun.java2d.cmm.lcms;
+
+import java.awt.color.CMMException;
+import java.util.Arrays;
+import java.util.HashMap;
+import sun.java2d.cmm.Profile;
+
+final class LCMSProfile extends Profile {
+ private final TagCache tagCache;
+
+ private final Object disposerReferent;
+
+ LCMSProfile(long ptr, Object ref) {
+ super(ptr);
+
+ disposerReferent = ref;
+
+ tagCache = new TagCache(this);
+ }
+
+ final long getLcmsPtr() {
+ return this.getNativePtr();
+ }
+
+ TagData getTag(int sig) {
+ return tagCache.getTag(sig);
+ }
+
+ void clearTagCache() {
+ tagCache.clear();
+ }
+
+ static class TagCache {
+ final LCMSProfile profile;
+ private HashMap<Integer, TagData> tags;
+
+ TagCache(LCMSProfile p) {
+ profile = p;
+ tags = new HashMap<>();
+ }
+
+ TagData getTag(int sig) {
+ TagData t = tags.get(sig);
+ if (t == null) {
+ byte[] tagData = LCMS.getTagNative(profile.getNativePtr(), sig);
+ if (tagData != null) {
+ t = new TagData(sig, tagData);
+ tags.put(sig, t);
+ }
+ }
+ return t;
+ }
+
+ void clear() {
+ tags.clear();
+ }
+ }
+
+ static class TagData {
+ private int signature;
+ private byte[] data;
+
+ TagData(int sig, byte[] data) {
+ this.signature = sig;
+ this.data = data;
+ }
+
+ int getSize() {
+ return data.length;
+ }
+
+ byte[] getData() {
+ return Arrays.copyOf(data, data.length);
+ }
+
+ void copyDataTo(byte[] dst) {
+ System.arraycopy(data, 0, dst, 0, data.length);
+ }
+
+ int getSignature() {
+ return signature;
+ }
+ }
+}
--- a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java Fri Sep 20 19:15:59 2013 -0700
@@ -62,7 +62,7 @@
private boolean isOutIntPacked = false;
ICC_Profile[] profiles;
- long [] profileIDs;
+ LCMSProfile[] lcmsProfiles;
int renderType;
int transformType;
@@ -84,8 +84,8 @@
/* Actually, it is not a complete transform but just part of it */
profiles = new ICC_Profile[1];
profiles[0] = profile;
- profileIDs = new long[1];
- profileIDs[0] = LCMS.getProfileID(profile);
+ lcmsProfiles = new LCMSProfile[1];
+ lcmsProfiles[0] = LCMS.getProfileID(profile);
this.renderType = (renderType == ColorTransform.Any)?
ICC_Profile.icPerceptual : renderType;
this.transformType = transformType;
@@ -105,14 +105,14 @@
size+=((LCMSTransform)transforms[i]).profiles.length;
}
profiles = new ICC_Profile[size];
- profileIDs = new long[size];
+ lcmsProfiles = new LCMSProfile[size];
int j = 0;
for (int i=0; i < transforms.length; i++) {
LCMSTransform curTrans = (LCMSTransform)transforms[i];
System.arraycopy(curTrans.profiles, 0, profiles, j,
curTrans.profiles.length);
- System.arraycopy(curTrans.profileIDs, 0, profileIDs, j,
- curTrans.profileIDs.length);
+ System.arraycopy(curTrans.lcmsProfiles, 0, lcmsProfiles, j,
+ curTrans.lcmsProfiles.length);
j += curTrans.profiles.length;
}
renderType = ((LCMSTransform)transforms[0]).renderType;
@@ -152,7 +152,7 @@
outFormatter = out.pixelType;
isOutIntPacked = out.isIntPacked;
- ID = LCMS.createNativeTransform(profileIDs, renderType,
+ ID = LCMS.createTransform(lcmsProfiles, renderType,
inFormatter, isInIntPacked,
outFormatter, isOutIntPacked,
disposerReferent);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/print/DocumentPropertiesUI.java Fri Sep 20 19:15:59 2013 -0700
@@ -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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.print;
+
+import java.awt.Window;
+import java.awt.print.PrinterJob;
+import javax.print.PrintService;
+import javax.print.ServiceUIFactory;
+import javax.print.attribute.PrintRequestAttributeSet;
+
+public abstract class DocumentPropertiesUI {
+
+ /**
+ * For Win32 doc properties sheet.
+ */
+ public static final int
+ DOCUMENTPROPERTIES_ROLE = ServiceUIFactory.RESERVED_UIROLE +100;
+
+ /**
+ * Name of (this) abstract class for Document Properties.
+ */
+ public static final String
+ DOCPROPERTIESCLASSNAME = DocumentPropertiesUI.class.getName();
+
+ /**
+ * Invokes whatever code is needed to display a native dialog
+ * with the specified owner. The owner should be the cross-platform
+ * dialog. If the user cancels the dialog the return value is null.
+ * A non-null return value is always a new attribute set (or is it?)
+ * The cross-platform dialog may need to be updated to reflect the
+ * updated properties.
+ */
+ public abstract PrintRequestAttributeSet
+ showDocumentProperties(PrinterJob job,
+ Window owner,
+ PrintService service,
+ PrintRequestAttributeSet aset);
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/print/PrinterJobWrapper.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,60 @@
+/*
+ * 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 sun.print;
+
+import java.awt.print.PrinterJob;
+import javax.print.attribute.PrintRequestAttribute;
+
+public class PrinterJobWrapper implements PrintRequestAttribute {
+
+ private static final long serialVersionUID = -8792124426995707237L;
+
+ private PrinterJob job;
+
+ public PrinterJobWrapper(PrinterJob job) {
+ this.job = job;
+ }
+
+ public PrinterJob getPrinterJob() {
+ return job;
+ }
+
+ public final Class getCategory() {
+ return PrinterJobWrapper.class;
+ }
+
+ public final String getName() {
+ return "printerjob-wrapper";
+ }
+
+ public String toString() {
+ return "printerjob-wrapper: " + job.toString();
+ }
+
+ public int hashCode() {
+ return job.hashCode();
+ }
+}
--- a/jdk/src/share/classes/sun/print/RasterPrinterJob.java Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/share/classes/sun/print/RasterPrinterJob.java Fri Sep 20 19:15:59 2013 -0700
@@ -903,6 +903,9 @@
int x = bounds.x+bounds.width/3;
int y = bounds.y+bounds.height/3;
PrintService newService;
+ // temporarily add an attribute pointing back to this job.
+ PrinterJobWrapper jobWrapper = new PrinterJobWrapper(this);
+ attributes.add(jobWrapper);
try {
newService =
ServiceUI.printDialog(gc, x, y,
@@ -915,6 +918,7 @@
DocFlavor.SERVICE_FORMATTED.PAGEABLE,
attributes);
}
+ attributes.remove(PrinterJobWrapper.class);
if (newService == null) {
return false;
--- a/jdk/src/share/classes/sun/print/ServiceDialog.java Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/share/classes/sun/print/ServiceDialog.java Fri Sep 20 19:15:59 2013 -0700
@@ -46,6 +46,7 @@
import java.awt.event.ItemListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;
+import java.awt.print.PrinterJob;
import java.io.File;
import java.io.FilePermission;
import java.io.IOException;
@@ -119,8 +120,6 @@
private AppearancePanel pnlAppearance;
private boolean isAWT = false;
-
-
static {
initResource();
}
@@ -801,9 +800,32 @@
if (dialog != null) {
dialog.show();
} else {
- // REMIND: may want to notify the user why we're
- // disabling the button
- btnProperties.setEnabled(false);
+ DocumentPropertiesUI docPropertiesUI = null;
+ try {
+ docPropertiesUI =
+ (DocumentPropertiesUI)uiFactory.getUI
+ (DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE,
+ DocumentPropertiesUI.DOCPROPERTIESCLASSNAME);
+ } catch (Exception ex) {
+ }
+ if (docPropertiesUI != null) {
+ PrinterJobWrapper wrapper = (PrinterJobWrapper)
+ asCurrent.get(PrinterJobWrapper.class);
+ if (wrapper == null) {
+ return; // should not happen, defensive only.
+ }
+ PrinterJob job = wrapper.getPrinterJob();
+ if (job == null) {
+ return; // should not happen, defensive only.
+ }
+ PrintRequestAttributeSet newAttrs =
+ docPropertiesUI.showDocumentProperties
+ (job, ServiceDialog.this, psCurrent, asCurrent);
+ if (newAttrs != null) {
+ asCurrent.addAll(newAttrs);
+ updatePanels();
+ }
+ }
}
}
}
--- a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Fri Sep 20 19:15:59 2013 -0700
@@ -930,9 +930,10 @@
* Now fill a complete buffer, or as much of one as the stream
* will give us if we are near the end.
*/
+ RELEASE_ARRAYS(env, data, src->next_input_byte);
+
GET_IO_REF(input);
- RELEASE_ARRAYS(env, data, src->next_input_byte);
ret = (*env)->CallIntMethod(env,
input,
JPEGImageReader_readInputDataID,
@@ -1017,9 +1018,11 @@
memcpy(sb->buf, src->next_input_byte, offset);
}
- GET_IO_REF(input);
RELEASE_ARRAYS(env, data, src->next_input_byte);
+
+ GET_IO_REF(input);
+
buflen = sb->bufferLength - offset;
if (buflen <= 0) {
if (!GET_ARRAYS(env, data, &(src->next_input_byte))) {
@@ -1121,9 +1124,10 @@
return;
}
+ RELEASE_ARRAYS(env, data, src->next_input_byte);
+
GET_IO_REF(input);
- RELEASE_ARRAYS(env, data, src->next_input_byte);
ret = (*env)->CallLongMethod(env,
input,
JPEGImageReader_skipInputBytesID,
@@ -2306,10 +2310,10 @@
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject output = NULL;
+ RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
+
GET_IO_REF(output);
- RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
-
(*env)->CallVoidMethod(env,
output,
JPEGImageWriter_writeOutputDataID,
@@ -2348,10 +2352,10 @@
if (datacount != 0) {
jobject output = NULL;
+ RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
+
GET_IO_REF(output);
- RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
-
(*env)->CallVoidMethod(env,
output,
JPEGImageWriter_writeOutputDataID,
--- a/jdk/src/share/native/sun/font/layout/SunLayoutEngine.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/share/native/sun/font/layout/SunLayoutEngine.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -179,6 +179,10 @@
FontInstanceAdapter fia(env, font2d, strike, mat, 72, 72, (le_int32) upem, (TTLayoutTableCache *) layoutTables);
LEErrorCode success = LE_NO_ERROR;
LayoutEngine *engine = LayoutEngine::layoutEngineFactory(&fia, script, lang, typo_flags & TYPO_MASK, success);
+ if (engine == NULL) {
+ env->SetIntField(gvdata, gvdCountFID, -1); // flag failure
+ return;
+ }
if (min < 0) min = 0; if (max < min) max = min; /* defensive coding */
// have to copy, yuck, since code does upcalls now. this will be soooo slow
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c Fri Sep 20 19:15:59 2013 -0700
@@ -94,8 +94,12 @@
# endif
#endif
+typedef struct lcmsProfile_s {
+ cmsHPROFILE pf;
+} lcmsProfile_t, *lcmsProfile_p;
+
typedef union storeID_s { /* store SProfile stuff in a Java Long */
- cmsHPROFILE pf;
+ lcmsProfile_p lcmsPf;
cmsHTRANSFORM xf;
jobject jobj;
jlong j;
@@ -106,7 +110,6 @@
jint j;
} TagSignature_t, *TagSignature_p;
-static jfieldID Trans_profileIDs_fID;
static jfieldID Trans_renderType_fID;
static jfieldID Trans_ID_fID;
static jfieldID IL_isIntPacked_fID;
@@ -118,7 +121,6 @@
static jfieldID IL_width_fID;
static jfieldID IL_height_fID;
static jfieldID IL_imageAtOnce_fID;
-static jfieldID PF_ID_fID;
JavaVM *javaVM;
@@ -145,6 +147,18 @@
return JNI_VERSION_1_6;
}
+void LCMS_freeProfile(JNIEnv *env, jlong ptr) {
+ storeID_t sProfile;
+ sProfile.j = ptr;
+
+ if (sProfile.lcmsPf != NULL) {
+ if (sProfile.lcmsPf->pf != NULL) {
+ cmsCloseProfile(sProfile.lcmsPf->pf);
+ }
+ free(sProfile.lcmsPf);
+ }
+}
+
void LCMS_freeTransform(JNIEnv *env, jlong ID)
{
storeID_t sTrans;
@@ -170,7 +184,7 @@
jlong* ids;
size = (*env)->GetArrayLength (env, profileIDs);
- ids = (*env)->GetPrimitiveArrayCritical(env, profileIDs, 0);
+ ids = (*env)->GetLongArrayElements(env, profileIDs, 0);
#ifdef _LITTLE_ENDIAN
/* Reversing data packed into int for LE archs */
@@ -186,6 +200,8 @@
iccArray = (cmsHPROFILE*) malloc(
size*2*sizeof(cmsHPROFILE));
if (iccArray == NULL) {
+ (*env)->ReleaseLongArrayElements(env, profileIDs, ids, 0);
+
J2dRlsTraceLn(J2D_TRACE_ERROR, "getXForm: iccArray == NULL");
return 0L;
}
@@ -197,7 +213,7 @@
cmsColorSpaceSignature cs;
sTrans.j = ids[i];
- icc = sTrans.pf;
+ icc = sTrans.lcmsPf->pf;
iccArray[j++] = icc;
/* Middle non-abstract profiles should be doubled before passing to
@@ -215,13 +231,15 @@
sTrans.xf = cmsCreateMultiprofileTransform(iccArray, j,
inFormatter, outFormatter, renderType, 0);
- (*env)->ReleasePrimitiveArrayCritical(env, profileIDs, ids, 0);
+ (*env)->ReleaseLongArrayElements(env, profileIDs, ids, 0);
if (sTrans.xf == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_createNativeTransform: "
"sTrans.xf == NULL");
- JNU_ThrowByName(env, "java/awt/color/CMMException",
- "Cannot get color transform");
+ if ((*env)->ExceptionOccurred(env) == NULL) {
+ JNU_ThrowByName(env, "java/awt/color/CMMException",
+ "Cannot get color transform");
+ }
} else {
Disposer_AddRecord(env, disposerRef, LCMS_freeTransform, sTrans.j);
}
@@ -236,20 +254,23 @@
/*
* Class: sun_java2d_cmm_lcms_LCMS
* Method: loadProfile
- * Signature: ([B)J
+ * Signature: ([B,Lsun/java2d/cmm/lcms/LCMSProfile;)V
*/
JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative
- (JNIEnv *env, jobject obj, jbyteArray data)
+ (JNIEnv *env, jobject obj, jbyteArray data, jobject disposerRef)
{
jbyte* dataArray;
jint dataSize;
storeID_t sProf;
+ cmsHPROFILE pf;
if (JNU_IsNull(env, data)) {
JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
return 0L;
}
+ sProf.j = 0L;
+
dataArray = (*env)->GetByteArrayElements (env, data, 0);
dataSize = (*env)->GetArrayLength (env, data);
@@ -258,22 +279,37 @@
return 0L;
}
- sProf.pf = cmsOpenProfileFromMem((const void *)dataArray,
+ pf = cmsOpenProfileFromMem((const void *)dataArray,
(cmsUInt32Number) dataSize);
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
- if (sProf.pf == NULL) {
+ if (pf == NULL) {
JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
} else {
/* Sanity check: try to save the profile in order
* to force basic validation.
*/
cmsUInt32Number pfSize = 0;
- if (!cmsSaveProfileToMem(sProf.pf, NULL, &pfSize) ||
+ if (!cmsSaveProfileToMem(pf, NULL, &pfSize) ||
pfSize < sizeof(cmsICCHeader))
{
JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
+
+ cmsCloseProfile(pf);
+ pf = NULL;
+ }
+ }
+
+ if (pf != NULL) {
+ // create profile holder
+ sProf.lcmsPf = (lcmsProfile_p)malloc(sizeof(lcmsProfile_t));
+ if (sProf.lcmsPf != NULL) {
+ // register the disposer record
+ sProf.lcmsPf->pf = pf;
+ Disposer_AddRecord(env, disposerRef, LCMS_freeProfile, sProf.j);
+ } else {
+ cmsCloseProfile(pf);
}
}
@@ -282,37 +318,17 @@
/*
* Class: sun_java2d_cmm_lcms_LCMS
- * Method: freeProfile
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative
- (JNIEnv *env, jobject obj, jlong id)
-{
- storeID_t sProf;
-
- sProf.j = id;
- if (cmsCloseProfile(sProf.pf) == 0) {
- J2dRlsTraceLn1(J2D_TRACE_ERROR, "LCMS_freeProfile: cmsCloseProfile(%d)"
- "== 0", id);
- JNU_ThrowByName(env, "java/awt/color/CMMException",
- "Cannot close profile");
- }
-
-}
-
-/*
- * Class: sun_java2d_cmm_lcms_LCMS
- * Method: getProfileSize
+ * Method: getProfileSizeNative
* Signature: (J)I
*/
-JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileSize
+JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative
(JNIEnv *env, jobject obj, jlong id)
{
storeID_t sProf;
cmsUInt32Number pfSize = 0;
sProf.j = id;
- if (cmsSaveProfileToMem(sProf.pf, NULL, &pfSize) && ((jint)pfSize > 0)) {
+ if (cmsSaveProfileToMem(sProf.lcmsPf->pf, NULL, &pfSize) && ((jint)pfSize > 0)) {
return (jint)pfSize;
} else {
JNU_ThrowByName(env, "java/awt/color/CMMException",
@@ -323,10 +339,10 @@
/*
* Class: sun_java2d_cmm_lcms_LCMS
- * Method: getProfileData
+ * Method: getProfileDataNative
* Signature: (J[B)V
*/
-JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData
+JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative
(JNIEnv *env, jobject obj, jlong id, jbyteArray data)
{
storeID_t sProf;
@@ -338,7 +354,7 @@
sProf.j = id;
// determine actual profile size
- if (!cmsSaveProfileToMem(sProf.pf, NULL, &pfSize)) {
+ if (!cmsSaveProfileToMem(sProf.lcmsPf->pf, NULL, &pfSize)) {
JNU_ThrowByName(env, "java/awt/color/CMMException",
"Can not access specified profile.");
return;
@@ -354,7 +370,7 @@
dataArray = (*env)->GetByteArrayElements (env, data, 0);
- status = cmsSaveProfileToMem(sProf.pf, dataArray, &pfSize);
+ status = cmsSaveProfileToMem(sProf.lcmsPf->pf, dataArray, &pfSize);
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
@@ -368,7 +384,7 @@
/* Get profile header info */
static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
-static cmsBool _writeCookedTag(cmsHPROFILE pfTarget, cmsTagSignature sig, jbyte *pData, jint size);
+static cmsHPROFILE _writeCookedTag(cmsHPROFILE pfTarget, cmsTagSignature sig, jbyte *pData, jint size);
/*
@@ -412,7 +428,7 @@
return NULL;
}
- status = _getHeaderInfo(sProf.pf, dataArray, bufSize);
+ status = _getHeaderInfo(sProf.lcmsPf->pf, dataArray, bufSize);
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
@@ -425,8 +441,8 @@
return data;
}
- if (cmsIsTag(sProf.pf, sig.cms)) {
- tagSize = cmsReadRawTag(sProf.pf, sig.cms, NULL, 0);
+ if (cmsIsTag(sProf.lcmsPf->pf, sig.cms)) {
+ tagSize = cmsReadRawTag(sProf.lcmsPf->pf, sig.cms, NULL, 0);
} else {
JNU_ThrowByName(env, "java/awt/color/CMMException",
"ICC profile tag not found");
@@ -449,7 +465,7 @@
return NULL;
}
- bufSize = cmsReadRawTag(sProf.pf, sig.cms, dataArray, tagSize);
+ bufSize = cmsReadRawTag(sProf.lcmsPf->pf, sig.cms, dataArray, tagSize);
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
@@ -470,8 +486,10 @@
(JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data)
{
storeID_t sProf;
+ cmsHPROFILE pfReplace = NULL;
+
TagSignature_t sig;
- cmsBool status;
+ cmsBool status = FALSE;
jbyte* dataArray;
int tagSize;
@@ -493,15 +511,24 @@
}
if (tagSig == SigHead) {
- status = _setHeaderInfo(sProf.pf, dataArray, tagSize);
+ status = _setHeaderInfo(sProf.lcmsPf->pf, dataArray, tagSize);
} else {
- status = _writeCookedTag(sProf.pf, sig.cms, dataArray, tagSize);
+ /*
+ * New strategy for generic tags: create a place holder,
+ * dump all existing tags there, dump externally supplied
+ * tag, and return the new profile to the java.
+ */
+ pfReplace = _writeCookedTag(sProf.lcmsPf->pf, sig.cms, dataArray, tagSize);
+ status = (pfReplace != NULL);
}
(*env)->ReleaseByteArrayElements(env, data, dataArray, 0);
if (!status) {
JNU_ThrowIllegalArgumentException(env, "Can not write tag data.");
+ } else if (pfReplace != NULL) {
+ cmsCloseProfile(sProf.lcmsPf->pf);
+ sProf.lcmsPf->pf = pfReplace;
}
}
@@ -624,12 +651,27 @@
/*
* Class: sun_java2d_cmm_lcms_LCMS
* Method: getProfileID
- * Signature: (Ljava/awt/color/ICC_Profile;)J
+ * Signature: (Ljava/awt/color/ICC_Profile;)Lsun/java2d/cmm/lcms/LCMSProfile
*/
-JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileID
+JNIEXPORT jobject JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileID
(JNIEnv *env, jclass cls, jobject pf)
{
- return (*env)->GetLongField (env, pf, PF_ID_fID);
+ jfieldID fid = (*env)->GetFieldID (env,
+ (*env)->GetObjectClass(env, pf),
+ "cmmProfile", "Lsun/java2d/cmm/Profile;");
+
+ jclass clsLcmsProfile = (*env)->FindClass(env,
+ "sun/java2d/cmm/lcms/LCMSProfile");
+
+ jobject cmmProfile = (*env)->GetObjectField (env, pf, fid);
+
+ if (JNU_IsNull(env, cmmProfile)) {
+ return NULL;
+ }
+ if ((*env)->IsInstanceOf(env, cmmProfile, clsLcmsProfile)) {
+ return cmmProfile;
+ }
+ return NULL;
}
/*
@@ -644,7 +686,6 @@
* corresponding classes to avoid problems with invalidating ids by class
* unloading
*/
- Trans_profileIDs_fID = (*env)->GetFieldID (env, Trans, "profileIDs", "[J");
Trans_renderType_fID = (*env)->GetFieldID (env, Trans, "renderType", "I");
Trans_ID_fID = (*env)->GetFieldID (env, Trans, "ID", "J");
@@ -658,8 +699,6 @@
IL_offset_fID = (*env)->GetFieldID (env, IL, "offset", "I");
IL_imageAtOnce_fID = (*env)->GetFieldID (env, IL, "imageAtOnce", "Z");
IL_nextRowOffset_fID = (*env)->GetFieldID (env, IL, "nextRowOffset", "I");
-
- PF_ID_fID = (*env)->GetFieldID (env, Pf, "ID", "J");
}
static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
@@ -714,76 +753,114 @@
return TRUE;
}
-static cmsBool _writeCookedTag(cmsHPROFILE pfTarget,
- cmsTagSignature sig,
+/* Returns new profile handler, if it was created successfully,
+ NULL otherwise.
+ */
+static cmsHPROFILE _writeCookedTag(const cmsHPROFILE pfTarget,
+ const cmsTagSignature sig,
jbyte *pData, jint size)
{
- cmsBool status;
cmsUInt32Number pfSize = 0;
- cmsUInt8Number* pfBuffer = NULL;
+ const cmsInt32Number tagCount = cmsGetTagCount(pfTarget);
+ cmsInt32Number i;
+ cmsHPROFILE pfSanity = NULL;
+
+ cmsICCHeader hdr = { 0 };
cmsHPROFILE p = cmsCreateProfilePlaceholder(NULL);
- if (NULL != p) {
- cmsICCHeader hdr = { 0 };
+
+ if (NULL == p) {
+ return NULL;
+ }
- /* Populate the placeholder's header according to target profile */
- hdr.flags = cmsGetHeaderFlags(pfTarget);
- hdr.renderingIntent = cmsGetHeaderRenderingIntent(pfTarget);
- hdr.manufacturer = cmsGetHeaderManufacturer(pfTarget);
- hdr.model = cmsGetHeaderModel(pfTarget);
- hdr.pcs = cmsGetPCS(pfTarget);
- hdr.colorSpace = cmsGetColorSpace(pfTarget);
- hdr.deviceClass = cmsGetDeviceClass(pfTarget);
- hdr.version = cmsGetEncodedICCversion(pfTarget);
- cmsGetHeaderAttributes(pfTarget, &hdr.attributes);
- cmsGetHeaderProfileID(pfTarget, (cmsUInt8Number*)&hdr.profileID);
+ // Populate the placeholder's header according to target profile
+ hdr.flags = cmsGetHeaderFlags(pfTarget);
+ hdr.renderingIntent = cmsGetHeaderRenderingIntent(pfTarget);
+ hdr.manufacturer = cmsGetHeaderManufacturer(pfTarget);
+ hdr.model = cmsGetHeaderModel(pfTarget);
+ hdr.pcs = cmsGetPCS(pfTarget);
+ hdr.colorSpace = cmsGetColorSpace(pfTarget);
+ hdr.deviceClass = cmsGetDeviceClass(pfTarget);
+ hdr.version = cmsGetEncodedICCversion(pfTarget);
+ cmsGetHeaderAttributes(pfTarget, &hdr.attributes);
+ cmsGetHeaderProfileID(pfTarget, (cmsUInt8Number*)&hdr.profileID);
- cmsSetHeaderFlags(p, hdr.flags);
- cmsSetHeaderManufacturer(p, hdr.manufacturer);
- cmsSetHeaderModel(p, hdr.model);
- cmsSetHeaderAttributes(p, hdr.attributes);
- cmsSetHeaderProfileID(p, (cmsUInt8Number*)&(hdr.profileID));
- cmsSetHeaderRenderingIntent(p, hdr.renderingIntent);
- cmsSetPCS(p, hdr.pcs);
- cmsSetColorSpace(p, hdr.colorSpace);
- cmsSetDeviceClass(p, hdr.deviceClass);
- cmsSetEncodedICCversion(p, hdr.version);
+ cmsSetHeaderFlags(p, hdr.flags);
+ cmsSetHeaderManufacturer(p, hdr.manufacturer);
+ cmsSetHeaderModel(p, hdr.model);
+ cmsSetHeaderAttributes(p, hdr.attributes);
+ cmsSetHeaderProfileID(p, (cmsUInt8Number*)&(hdr.profileID));
+ cmsSetHeaderRenderingIntent(p, hdr.renderingIntent);
+ cmsSetPCS(p, hdr.pcs);
+ cmsSetColorSpace(p, hdr.colorSpace);
+ cmsSetDeviceClass(p, hdr.deviceClass);
+ cmsSetEncodedICCversion(p, hdr.version);
+
+ // now write the user supplied tag
+ if (size <= 0 || !cmsWriteRawTag(p, sig, pData, size)) {
+ cmsCloseProfile(p);
+ return NULL;
+ }
+ // copy tags from the original profile
+ for (i = 0; i < tagCount; i++) {
+ cmsBool isTagReady = FALSE;
+ const cmsTagSignature s = cmsGetTagSignature(pfTarget, i);
+ const cmsInt32Number tagSize = cmsReadRawTag(pfTarget, s, NULL, 0);
- if (cmsWriteRawTag(p, sig, pData, size)) {
- if (cmsSaveProfileToMem(p, NULL, &pfSize)) {
- pfBuffer = malloc(pfSize);
- if (pfBuffer != NULL) {
- /* load raw profile data into the buffer */
- if (!cmsSaveProfileToMem(p, pfBuffer, &pfSize)) {
- free(pfBuffer);
- pfBuffer = NULL;
- }
+ if (s == sig) {
+ // skip the user supplied tag
+ continue;
+ }
+
+ // read raw tag from the original profile
+ if (tagSize > 0) {
+ cmsUInt8Number* buf = (cmsUInt8Number*)malloc(tagSize);
+ if (buf != NULL) {
+ if (tagSize == cmsReadRawTag(pfTarget, s, buf, tagSize)) {
+ // now we are ready to write the tag
+ isTagReady = cmsWriteRawTag(p, s, buf, tagSize);
}
+ free(buf);
}
}
- cmsCloseProfile(p);
+
+ if (!isTagReady) {
+ cmsCloseProfile(p);
+ return NULL;
+ }
}
- if (pfBuffer == NULL) {
- return FALSE;
+ // now we have all tags moved to the new profile.
+ // do some sanity checks: write it to a memory buffer and read again.
+ if (cmsSaveProfileToMem(p, NULL, &pfSize)) {
+ void* buf = malloc(pfSize);
+ if (buf != NULL) {
+ // load raw profile data into the buffer
+ if (cmsSaveProfileToMem(p, buf, &pfSize)) {
+ pfSanity = cmsOpenProfileFromMem(buf, pfSize);
+ }
+ free(buf);
+ }
}
- /* re-open the placeholder profile */
- p = cmsOpenProfileFromMem(pfBuffer, pfSize);
- free(pfBuffer);
- status = FALSE;
+ if (pfSanity == NULL) {
+ // for some reason, we failed to save and read the updated profile
+ // It likely indicates that the profile is not correct, so we report
+ // a failure here.
+ cmsCloseProfile(p);
+ p = NULL;
+ } else {
+ // do final check whether we can read and handle the the target tag.
+ const void* pTag = cmsReadTag(pfSanity, sig);
+ if (pTag == NULL) {
+ // the tag can not be cooked
+ cmsCloseProfile(p);
+ p = NULL;
+ }
+ cmsCloseProfile(pfSanity);
+ pfSanity = NULL;
+ }
- if (p != NULL) {
- /* Note that pCookedTag points to internal structures of the placeholder,
- * so this data is valid only while the placeholder is open.
- */
- void *pCookedTag = cmsReadTag(p, sig);
- if (pCookedTag != NULL) {
- status = cmsWriteTag(pfTarget, sig, pCookedTag);
- }
- pCookedTag = NULL;
- cmsCloseProfile(p);
- }
- return status;
+ return p;
}
--- a/jdk/src/solaris/classes/sun/font/XRTextRenderer.java Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/solaris/classes/sun/font/XRTextRenderer.java Fri Sep 20 19:15:59 2013 -0700
@@ -142,7 +142,7 @@
}
int maskFormat = containsLCDGlyphs ? XRUtils.PictStandardARGB32 : XRUtils.PictStandardA8;
- maskBuffer.compositeText(x11sd.picture, 0, maskFormat, eltList);
+ maskBuffer.compositeText(x11sd, (int) gl.getX(), (int) gl.getY(), 0, maskFormat, eltList);
eltList.clear();
} finally {
--- a/jdk/src/solaris/classes/sun/java2d/xr/XRBackendNative.java Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/solaris/classes/sun/java2d/xr/XRBackendNative.java Fri Sep 20 19:15:59 2013 -0700
@@ -267,8 +267,9 @@
private static native void
XRenderCompositeTextNative(int op, int src, int dst,
- long maskFormat, int[] eltArray,
- int[] glyphIDs, int eltCnt, int glyphCnt);
+ int srcX, int srcY, long maskFormat,
+ int[] eltArray, int[] glyphIDs, int eltCnt,
+ int glyphCnt);
public int XRenderCreateGlyphSet(int formatID) {
return XRenderCreateGlyphSetNative(getFormatPtr(formatID));
@@ -278,11 +279,11 @@
public void XRenderCompositeText(byte op, int src, int dst,
int maskFormatID,
- int src2, int src3, int dst2, int dst3,
+ int sx, int sy, int dx, int dy,
int glyphset, GrowableEltArray elts) {
GrowableIntArray glyphs = elts.getGlyphs();
- XRenderCompositeTextNative(op, src, dst, 0, elts.getArray(),
+ XRenderCompositeTextNative(op, src, dst, sx, sy, 0, elts.getArray(),
glyphs.getArray(), elts.getSize(),
glyphs.getSize());
}
--- a/jdk/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java Fri Sep 20 19:15:59 2013 -0700
@@ -285,7 +285,12 @@
if (xorEnabled) {
con.GCRectangles(dst.getXid(), dst.getGC(), rects);
} else {
- con.renderRectangles(dst.getPicture(), compRule, solidColor, rects);
+ if (rects.getSize() == 1) {
+ con.renderRectangle(dst.getPicture(), compRule, solidColor,
+ rects.getX(0), rects.getY(0), rects.getWidth(0), rects.getHeight(0));
+ } else {
+ con.renderRectangles(dst.getPicture(), compRule, solidColor, rects);
+ }
}
}
@@ -295,10 +300,10 @@
sy, 0, 0, dx, dy, w, h);
}
- public void compositeText(int dst, int glyphSet, int maskFormat,
- GrowableEltArray elts) {
- con.XRenderCompositeText(compRule, src.picture, dst, maskFormat, 0, 0,
- 0, 0, glyphSet, elts);
+ public void compositeText(XRSurfaceData dst, int sx, int sy,
+ int glyphSet, int maskFormat, GrowableEltArray elts) {
+ con.XRenderCompositeText(compRule, src.picture, dst.picture,
+ maskFormat, sx, sy, 0, 0, glyphSet, elts);
}
public XRColor getMaskColor() {
--- a/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java Fri Sep 20 19:15:59 2013 -0700
@@ -225,6 +225,9 @@
* @author Clemens Eisserer
*/
class XRPMTransformedBlit extends TransformBlit {
+ final Rectangle compositeBounds = new Rectangle();
+ final double[] srcCoords = new double[8];
+ final double[] dstCoords = new double[8];
public XRPMTransformedBlit(SurfaceType srcType, SurfaceType dstType) {
super(srcType, CompositeType.AnyAlpha, dstType);
@@ -235,61 +238,68 @@
* method is functionally equal to: Shape shp =
* xform.createTransformedShape(rect); Rectangle bounds = shp.getBounds();
* but performs significantly better.
+ * Returns true if the destination shape is parallel to x/y axis
*/
- public Rectangle getCompositeBounds(AffineTransform tr, int dstx, int dsty, int width, int height) {
- double[] compBounds = new double[8];
- compBounds[0] = dstx;
- compBounds[1] = dsty;
- compBounds[2] = dstx + width;
- compBounds[3] = dsty;
- compBounds[4] = dstx + width;
- compBounds[5] = dsty + height;
- compBounds[6] = dstx;
- compBounds[7] = dsty + height;
+ protected boolean adjustCompositeBounds(AffineTransform tr, int dstx, int dsty, int width, int height) {
+ srcCoords[0] = dstx;
+ srcCoords[1] = dsty;
+ srcCoords[2] = dstx + width;
+ srcCoords[3] = dsty;
+ srcCoords[4] = dstx + width;
+ srcCoords[5] = dsty + height;
+ srcCoords[6] = dstx;
+ srcCoords[7] = dsty + height;
+
+ tr.transform(srcCoords, 0, dstCoords, 0, 4);
- tr.transform(compBounds, 0, compBounds, 0, 4);
+ double minX = Math.min(dstCoords[0], Math.min(dstCoords[2], Math.min(dstCoords[4], dstCoords[6])));
+ double minY = Math.min(dstCoords[1], Math.min(dstCoords[3], Math.min(dstCoords[5], dstCoords[7])));
+ double maxX = Math.max(dstCoords[0], Math.max(dstCoords[2], Math.max(dstCoords[4], dstCoords[6])));
+ double maxY = Math.max(dstCoords[1], Math.max(dstCoords[3], Math.max(dstCoords[5], dstCoords[7])));
- double minX = Math.min(compBounds[0], Math.min(compBounds[2], Math.min(compBounds[4], compBounds[6])));
- double minY = Math.min(compBounds[1], Math.min(compBounds[3], Math.min(compBounds[5], compBounds[7])));
- double maxX = Math.max(compBounds[0], Math.max(compBounds[2], Math.max(compBounds[4], compBounds[6])));
- double maxY = Math.max(compBounds[1], Math.max(compBounds[3], Math.max(compBounds[5], compBounds[7])));
+ minX = Math.round(minX);
+ minY = Math.round(minY);
+ maxX = Math.round(maxX);
+ maxY = Math.round(maxY);
- minX = Math.floor(minX);
- minY = Math.floor(minY);
- maxX = Math.ceil(maxX);
- maxY = Math.ceil(maxY);
+ compositeBounds.x = (int) minX;
+ compositeBounds.y = (int) minY;
+ compositeBounds.width = (int) (maxX - minX);
+ compositeBounds.height = (int) (maxY - minY);
- return new Rectangle((int) minX, (int) minY, (int) (maxX - minX), (int) (maxY - minY));
+ boolean is0or180 = (dstCoords[1] == dstCoords[3]) && (dstCoords[2] == dstCoords[4]);
+ boolean is90or270 = (dstCoords[0] == dstCoords[2]) && (dstCoords[3] == dstCoords[5]);
+
+ return is0or180 || is90or270;
}
- public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, int srcx, int srcy,
- int dstx, int dsty, int width, int height) {
+ public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform,
+ int hint, int srcx, int srcy, int dstx, int dsty, int width, int height) {
try {
SunToolkit.awtLock();
- int filter = XRUtils.ATransOpToXRQuality(hint);
+ XRSurfaceData x11sdDst = (XRSurfaceData) dst;
+ XRSurfaceData x11sdSrc = (XRSurfaceData) src;
- XRSurfaceData x11sdDst = (XRSurfaceData) dst;
+ int filter = XRUtils.ATransOpToXRQuality(hint);
+ boolean isAxisAligned = adjustCompositeBounds(xform, dstx, dsty, width, height);
+
x11sdDst.validateAsDestination(null, clip);
- XRSurfaceData x11sdSrc = (XRSurfaceData) src;
x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);
- Rectangle bounds = getCompositeBounds(xform, dstx, dsty, width, height);
-
- AffineTransform trx = AffineTransform.getTranslateInstance((-bounds.x), (-bounds.y));
+ AffineTransform trx = AffineTransform.getTranslateInstance(-compositeBounds.x, -compositeBounds.y);
trx.concatenate(xform);
AffineTransform maskTX = (AffineTransform) trx.clone();
-
trx.translate(-srcx, -srcy);
try {
trx.invert();
} catch (NoninvertibleTransformException ex) {
trx.setToIdentity();
- System.err.println("Reseted to identity!");
}
- boolean omitMask = isMaskOmittable(trx, comp, filter);
+ boolean omitMask = (filter == XRUtils.FAST)
+ || (isAxisAligned && ((AlphaComposite) comp).getAlpha() == 1.0f);
if (!omitMask) {
XRMaskImage mask = x11sdSrc.maskBuffer.getMaskImage();
@@ -297,33 +307,17 @@
x11sdSrc.validateAsSource(trx, XRUtils.RepeatPad, filter);
int maskPicture = mask.prepareBlitMask(x11sdDst, maskTX, width, height);
x11sdDst.maskBuffer.con.renderComposite(XRCompositeManager.getInstance(x11sdSrc).getCompRule(), x11sdSrc.picture, maskPicture, x11sdDst.picture,
- 0, 0, 0, 0, bounds.x, bounds.y, bounds.width, bounds.height);
+ 0, 0, 0, 0, compositeBounds.x, compositeBounds.y, compositeBounds.width, compositeBounds.height);
} else {
int repeat = filter == XRUtils.FAST ? XRUtils.RepeatNone : XRUtils.RepeatPad;
x11sdSrc.validateAsSource(trx, repeat, filter);
- x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, 0, 0, bounds.x, bounds.y, bounds.width, bounds.height);
+ x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, 0, 0, compositeBounds.x, compositeBounds.y, compositeBounds.width, compositeBounds.height);
}
} finally {
SunToolkit.awtUnlock();
}
}
-
- /* TODO: Is mask ever omitable??? ... should be for 90 degree rotation and no shear, but we always need to use RepeatPad */
- protected static boolean isMaskOmittable(AffineTransform trx, Composite comp, int filter) {
- return (filter == XRUtils.FAST || trx.getTranslateX() == (int) trx.getTranslateX() /*
- * If
- * translate
- * is
- * integer
- * only
- */
- && trx.getTranslateY() == (int) trx.getTranslateY() && (trx.getShearX() == 0 && trx.getShearY() == 0 // Only
- // 90 degree
- // rotation
- || trx.getShearX() == -trx.getShearY())) && ((AlphaComposite) comp).getAlpha() == 1.0f; // No
- // ExtraAlpha!=1
- }
}
class XrSwToPMBlit extends Blit {
--- a/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c Fri Sep 20 19:15:59 2013 -0700
@@ -911,8 +911,9 @@
JNIEXPORT void JNICALL
Java_sun_java2d_xr_XRBackendNative_XRenderCompositeTextNative
- (JNIEnv *env, jclass cls, jint op, jint src, jint dst, jlong maskFmt,
- jintArray eltArray, jintArray glyphIDArray, jint eltCnt, jint glyphCnt) {
+ (JNIEnv *env, jclass cls, jint op, jint src, jint dst,
+ jint sx, jint sy, jlong maskFmt, jintArray eltArray,
+ jintArray glyphIDArray, jint eltCnt, jint glyphCnt) {
jint i;
jint *ids;
jint *elts;
@@ -991,7 +992,7 @@
XRenderCompositeText32(awt_display, op, (Picture) src, (Picture) dst,
(XRenderPictFormat *) jlong_to_ptr(maskFmt),
- 0, 0, 0, 0, xelts, eltCnt);
+ sx, sy, 0, 0, xelts, eltCnt);
(*env)->ReleasePrimitiveArrayCritical(env, glyphIDArray, ids, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, eltArray, elts, JNI_ABORT);
--- a/jdk/src/windows/classes/sun/awt/windows/WPrinterJob.java Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/windows/classes/sun/awt/windows/WPrinterJob.java Fri Sep 20 19:15:59 2013 -0700
@@ -179,6 +179,7 @@
private static final int SET_RES_LOW = 0x00000080;
private static final int SET_COLOR = 0x00000200;
private static final int SET_ORIENTATION = 0x00004000;
+ private static final int SET_COLLATED = 0x00008000;
/**
* Values must match those defined in wingdi.h & commdlg.h
@@ -189,10 +190,33 @@
private static final int PD_NOSELECTION = 0x00000004;
private static final int PD_COLLATE = 0x00000010;
private static final int PD_PRINTTOFILE = 0x00000020;
- private static final int DM_ORIENTATION = 0x00000001;
- private static final int DM_PRINTQUALITY = 0x00000400;
- private static final int DM_COLOR = 0x00000800;
- private static final int DM_DUPLEX = 0x00001000;
+ private static final int DM_ORIENTATION = 0x00000001;
+ private static final int DM_PAPERSIZE = 0x00000002;
+ private static final int DM_COPIES = 0x00000100;
+ private static final int DM_DEFAULTSOURCE = 0x00000200;
+ private static final int DM_PRINTQUALITY = 0x00000400;
+ private static final int DM_COLOR = 0x00000800;
+ private static final int DM_DUPLEX = 0x00001000;
+ private static final int DM_YRESOLUTION = 0x00002000;
+ private static final int DM_COLLATE = 0x00008000;
+
+ private static final short DMCOLLATE_FALSE = 0;
+ private static final short DMCOLLATE_TRUE = 1;
+
+ private static final short DMORIENT_PORTRAIT = 1;
+ private static final short DMORIENT_LANDSCAPE = 2;
+
+ private static final short DMCOLOR_MONOCHROME = 1;
+ private static final short DMCOLOR_COLOR = 2;
+
+ private static final short DMRES_DRAFT = -1;
+ private static final short DMRES_LOW = -2;
+ private static final short DMRES_MEDIUM = -3;
+ private static final short DMRES_HIGH = -4;
+
+ private static final short DMDUP_SIMPLEX = 1;
+ private static final short DMDUP_VERTICAL = 2;
+ private static final short DMDUP_HORIZONTAL = 3;
/**
* Pageable MAX pages
@@ -592,13 +616,23 @@
}
driverDoesMultipleCopies = false;
driverDoesCollation = false;
- setNativePrintService(service.getName());
+ setNativePrintServiceIfNeeded(service.getName());
}
/* associates this job with the specified native service */
private native void setNativePrintService(String name)
throws PrinterException;
+ private String lastNativeService = null;
+ private void setNativePrintServiceIfNeeded(String name)
+ throws PrinterException {
+
+ if (name != null && !(name.equals(lastNativeService))) {
+ setNativePrintService(name);
+ lastNativeService = name;
+ }
+ }
+
public PrintService getPrintService() {
if (myService == null) {
String printerName = getNativePrintService();
@@ -616,7 +650,7 @@
myService = PrintServiceLookup.lookupDefaultPrintService();
if (myService != null) {
try {
- setNativePrintService(myService.getName());
+ setNativePrintServiceIfNeeded(myService.getName());
} catch (Exception e) {
myService = null;
}
@@ -1754,8 +1788,13 @@
mAttMediaSizeName = ((Win32PrintService)myService).findPaperID(msn);
}
- private void setWin32MediaAttrib(int dmIndex, int width, int length) {
- MediaSizeName msn =
+ private void addPaperSize(PrintRequestAttributeSet aset,
+ int dmIndex, int width, int length) {
+
+ if (aset == null) {
+ return;
+ }
+ MediaSizeName msn =
((Win32PrintService)myService).findWin32Media(dmIndex);
if (msn == null) {
msn = ((Win32PrintService)myService).
@@ -1763,10 +1802,12 @@
}
if (msn != null) {
- if (attributes != null) {
- attributes.add(msn);
- }
+ aset.add(msn);
}
+ }
+
+ private void setWin32MediaAttrib(int dmIndex, int width, int length) {
+ addPaperSize(attributes, dmIndex, width, length);
mAttMediaSizeName = dmIndex;
}
@@ -1788,7 +1829,7 @@
// no equivalent predefined value
mAttMediaTray = 7; // DMBIN_AUTO
} else if (attr == MediaTray.TOP) {
- mAttMediaTray =1; // DMBIN_UPPER
+ mAttMediaTray = 1; // DMBIN_UPPER
} else {
if (attr instanceof Win32MediaTray) {
mAttMediaTray = ((Win32MediaTray)attr).winID;
@@ -1914,6 +1955,254 @@
}
}
+ private static final class DevModeValues {
+ int dmFields;
+ short copies;
+ short collate;
+ short color;
+ short duplex;
+ short orient;
+ short paper;
+ short bin;
+ short xres_quality;
+ short yres;
+ }
+
+ private void getDevModeValues(PrintRequestAttributeSet aset,
+ DevModeValues info) {
+
+ Copies c = (Copies)aset.get(Copies.class);
+ if (c != null) {
+ info.dmFields |= DM_COPIES;
+ info.copies = (short)c.getValue();
+ }
+
+ SheetCollate sc = (SheetCollate)aset.get(SheetCollate.class);
+ if (sc != null) {
+ info.dmFields |= DM_COLLATE;
+ info.collate = (sc == SheetCollate.COLLATED) ?
+ DMCOLLATE_TRUE : DMCOLLATE_FALSE;
+ }
+
+ Chromaticity ch = (Chromaticity)aset.get(Chromaticity.class);
+ if (ch != null) {
+ info.dmFields |= DM_COLOR;
+ if (ch == Chromaticity.COLOR) {
+ info.color = DMCOLOR_COLOR;
+ } else {
+ info.color = DMCOLOR_MONOCHROME;
+ }
+ }
+
+ Sides s = (Sides)aset.get(Sides.class);
+ if (s != null) {
+ info.dmFields |= DM_DUPLEX;
+ if (s == Sides.TWO_SIDED_LONG_EDGE) {
+ info.duplex = DMDUP_VERTICAL;
+ } else if (s == Sides.TWO_SIDED_SHORT_EDGE) {
+ info.duplex = DMDUP_HORIZONTAL;
+ } else { // Sides.ONE_SIDED
+ info.duplex = DMDUP_SIMPLEX;
+ }
+ }
+
+ OrientationRequested or =
+ (OrientationRequested)aset.get(OrientationRequested.class);
+ if (or != null) {
+ info.dmFields |= DM_ORIENTATION;
+ info.orient = (or == OrientationRequested.LANDSCAPE)
+ ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT;
+ }
+
+ Media m = (Media)aset.get(Media.class);
+ if (m instanceof MediaSizeName) {
+ info.dmFields |= DM_PAPERSIZE;
+ MediaSizeName msn = (MediaSizeName)m;
+ info.paper =
+ (short)((Win32PrintService)myService).findPaperID(msn);
+ }
+
+ MediaTray mt = null;
+ if (m instanceof MediaTray) {
+ mt = (MediaTray)m;
+ }
+ if (mt == null) {
+ SunAlternateMedia sam =
+ (SunAlternateMedia)aset.get(SunAlternateMedia.class);
+ if (sam != null && (sam.getMedia() instanceof MediaTray)) {
+ mt = (MediaTray)sam.getMedia();
+ }
+ }
+
+ if (mt != null) {
+ info.dmFields |= DM_DEFAULTSOURCE;
+ info.bin = (short)(((Win32PrintService)myService).findTrayID(mt));
+ }
+
+ PrintQuality q = (PrintQuality)aset.get(PrintQuality.class);
+ if (q != null) {
+ info.dmFields |= DM_PRINTQUALITY;
+ if (q == PrintQuality.DRAFT) {
+ info.xres_quality = DMRES_DRAFT;
+ } else if (q == PrintQuality.HIGH) {
+ info.xres_quality = DMRES_HIGH;
+ } else {
+ info.xres_quality = DMRES_MEDIUM;
+ }
+ }
+
+ PrinterResolution r =
+ (PrinterResolution)aset.get(PrinterResolution.class);
+ if (r != null) {
+ info.dmFields |= DM_PRINTQUALITY | DM_YRESOLUTION;
+ info.xres_quality =
+ (short)r.getCrossFeedResolution(PrinterResolution.DPI);
+ info.yres = (short)r.getFeedResolution(PrinterResolution.DPI);
+ }
+ }
+
+ /* This method is called from native to update the values in the
+ * attribute set which originates from the cross-platform dialog,
+ * but updated by the native DocumentPropertiesUI which updates the
+ * devmode. This syncs the devmode back in to the attributes so that
+ * we can update the cross-platform dialog.
+ * The attribute set here is a temporary one installed whilst this
+ * happens,
+ */
+ private final void setJobAttributes(PrintRequestAttributeSet attributes,
+ int fields, int values,
+ short copies,
+ short dmPaperSize,
+ short dmPaperWidth,
+ short dmPaperLength,
+ short dmDefaultSource,
+ short xRes,
+ short yRes) {
+
+ if (attributes == null) {
+ return;
+ }
+
+ if ((fields & DM_COPIES) != 0) {
+ attributes.add(new Copies(copies));
+ }
+
+ if ((fields & DM_COLLATE) != 0) {
+ if ((values & SET_COLLATED) != 0) {
+ attributes.add(SheetCollate.COLLATED);
+ } else {
+ attributes.add(SheetCollate.UNCOLLATED);
+ }
+ }
+
+ if ((fields & DM_ORIENTATION) != 0) {
+ if ((values & SET_ORIENTATION) != 0) {
+ attributes.add(OrientationRequested.LANDSCAPE);
+ } else {
+ attributes.add(OrientationRequested.PORTRAIT);
+ }
+ }
+
+ if ((fields & DM_COLOR) != 0) {
+ if ((values & SET_COLOR) != 0) {
+ attributes.add(Chromaticity.COLOR);
+ } else {
+ attributes.add(Chromaticity.MONOCHROME);
+ }
+ }
+
+ if ((fields & DM_PRINTQUALITY) != 0) {
+ /* value < 0 indicates quality setting.
+ * value > 0 indicates X resolution. In that case
+ * hopefully we will also find y-resolution specified.
+ * If its not, assume its the same as x-res.
+ * Maybe Java code should try to reconcile this against
+ * the printers claimed set of supported resolutions.
+ */
+ if (xRes < 0) {
+ PrintQuality quality;
+ if ((values & SET_RES_LOW) != 0) {
+ quality = PrintQuality.DRAFT;
+ } else if ((fields & SET_RES_HIGH) != 0) {
+ quality = PrintQuality.HIGH;
+ } else {
+ quality = PrintQuality.NORMAL;
+ }
+ attributes.add(quality);
+ } else if (xRes > 0 && yRes > 0) {
+ attributes.add(
+ new PrinterResolution(xRes, yRes, PrinterResolution.DPI));
+ }
+ }
+
+ if ((fields & DM_DUPLEX) != 0) {
+ Sides sides;
+ if ((values & SET_DUP_VERTICAL) != 0) {
+ sides = Sides.TWO_SIDED_LONG_EDGE;
+ } else if ((values & SET_DUP_HORIZONTAL) != 0) {
+ sides = Sides.TWO_SIDED_SHORT_EDGE;
+ } else {
+ sides = Sides.ONE_SIDED;
+ }
+ attributes.add(sides);
+ }
+
+ if ((fields & DM_PAPERSIZE) != 0) {
+ addPaperSize(attributes, dmPaperSize, dmPaperWidth, dmPaperLength);
+ }
+
+ if ((fields & DM_DEFAULTSOURCE) != 0) {
+ MediaTray tray =
+ ((Win32PrintService)myService).findMediaTray(dmDefaultSource);
+ attributes.add(new SunAlternateMedia(tray));
+ }
+ }
+
+ private native boolean showDocProperties(long hWnd,
+ PrintRequestAttributeSet aset,
+ int dmFields,
+ short copies,
+ short collate,
+ short color,
+ short duplex,
+ short orient,
+ short paper,
+ short bin,
+ short xres_quality,
+ short yres);
+
+ @SuppressWarnings("deprecation")
+ public PrintRequestAttributeSet
+ showDocumentProperties(Window owner,
+ PrintService service,
+ PrintRequestAttributeSet aset)
+ {
+ try {
+ setNativePrintServiceIfNeeded(service.getName());
+ } catch (PrinterException e) {
+ }
+ long hWnd = ((WWindowPeer)(owner.getPeer())).getHWnd();
+ DevModeValues info = new DevModeValues();
+ getDevModeValues(aset, info);
+ boolean ok =
+ showDocProperties(hWnd, aset,
+ info.dmFields,
+ info.copies,
+ info.collate,
+ info.color,
+ info.duplex,
+ info.orient,
+ info.paper,
+ info.bin,
+ info.xres_quality,
+ info.yres);
+
+ if (ok) {
+ return aset;
+ } else {
+ return null;
+ }
+ }
/* Printer Resolution. See also getXRes() and getYRes() */
private final void setResolutionDPI(int xres, int yres) {
@@ -1956,7 +2245,7 @@
}
//** END Functions called by native code for querying/updating attributes
- }
+ }
class PrintToFileErrorDialog extends Dialog implements ActionListener{
public PrintToFileErrorDialog(Frame parent, String title, String message,
--- a/jdk/src/windows/classes/sun/print/Win32MediaTray.java Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/windows/classes/sun/print/Win32MediaTray.java Fri Sep 20 19:15:59 2013 -0700
@@ -70,6 +70,10 @@
winEnumTable.add(this);
}
+ public int getDMBinID() {
+ return winID;
+ }
+
private static final String[] myStringTable ={
"Manual-Envelope",
"Automatic-Feeder",
--- a/jdk/src/windows/classes/sun/print/Win32PrintService.java Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/windows/classes/sun/print/Win32PrintService.java Fri Sep 20 19:15:59 2013 -0700
@@ -25,6 +25,8 @@
package sun.print;
+import java.awt.Window;
+import java.awt.print.PrinterJob;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
@@ -39,6 +41,7 @@
import javax.print.attribute.AttributeSetUtilities;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.HashAttributeSet;
+import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.PrintServiceAttribute;
import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.HashPrintServiceAttributeSet;
@@ -69,6 +72,7 @@
import javax.print.attribute.standard.PrinterResolution;
import javax.print.attribute.standard.SheetCollate;
import javax.print.event.PrintServiceAttributeListener;
+import sun.awt.windows.WPrinterJob;
public class Win32PrintService implements PrintService, AttributeUpdater,
SunPrinterJobService {
@@ -282,6 +286,22 @@
return 0;
}
+ public int findTrayID(MediaTray tray) {
+
+ getMediaTrays(); // make sure they are initialised.
+
+ if (tray instanceof Win32MediaTray) {
+ Win32MediaTray winTray = (Win32MediaTray)tray;
+ return winTray.getDMBinID();
+ }
+ for (int id=0; id<dmPaperBinToPrintService.length; id++) {
+ if (tray.equals(dmPaperBinToPrintService[id])) {
+ return id+1; // DMBIN_FIRST = 1;
+ }
+ }
+ return 0; // didn't find the tray
+ }
+
public MediaTray findMediaTray(int dmBin) {
if (dmBin >= 1 && dmBin <= dmPaperBinToPrintService.length) {
return dmPaperBinToPrintService[dmBin-1];
@@ -673,7 +693,6 @@
return arr2;
}
-
private PrinterIsAcceptingJobs getPrinterIsAcceptingJobs() {
if (getJobStatus(printer, 2) != 1) {
return PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS;
@@ -1596,8 +1615,76 @@
}
}
- public ServiceUIFactory getServiceUIFactory() {
- return null;
+ private Win32DocumentPropertiesUI docPropertiesUI = null;
+
+ private static class Win32DocumentPropertiesUI
+ extends DocumentPropertiesUI {
+
+ Win32PrintService service;
+
+ private Win32DocumentPropertiesUI(Win32PrintService s) {
+ service = s;
+ }
+
+ public PrintRequestAttributeSet
+ showDocumentProperties(PrinterJob job,
+ Window owner,
+ PrintService service,
+ PrintRequestAttributeSet aset) {
+
+ if (!(job instanceof WPrinterJob)) {
+ return null;
+ }
+ WPrinterJob wJob = (WPrinterJob)job;
+ return wJob.showDocumentProperties(owner, service, aset);
+ }
+ }
+
+ private synchronized DocumentPropertiesUI getDocumentPropertiesUI() {
+ return new Win32DocumentPropertiesUI(this);
+ }
+
+ private static class Win32ServiceUIFactory extends ServiceUIFactory {
+
+ Win32PrintService service;
+
+ Win32ServiceUIFactory(Win32PrintService s) {
+ service = s;
+ }
+
+ public Object getUI(int role, String ui) {
+ if (role <= ServiceUIFactory.MAIN_UIROLE) {
+ return null;
+ }
+ if (role == DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE &&
+ DocumentPropertiesUI.DOCPROPERTIESCLASSNAME.equals(ui))
+ {
+ return service.getDocumentPropertiesUI();
+ }
+ throw new IllegalArgumentException("Unsupported role");
+ }
+
+ public String[] getUIClassNamesForRole(int role) {
+
+ if (role <= ServiceUIFactory.MAIN_UIROLE) {
+ return null;
+ }
+ if (role == DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE) {
+ String[] names = new String[0];
+ names[0] = DocumentPropertiesUI.DOCPROPERTIESCLASSNAME;
+ return names;
+ }
+ throw new IllegalArgumentException("Unsupported role");
+ }
+ }
+
+ private Win32ServiceUIFactory uiFactory = null;
+
+ public synchronized ServiceUIFactory getServiceUIFactory() {
+ if (uiFactory == null) {
+ uiFactory = new Win32ServiceUIFactory(this);
+ }
+ return uiFactory;
}
public String toString() {
--- a/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -81,6 +81,7 @@
jmethodID AwtPrintControl::setNativeAttID;
jmethodID AwtPrintControl::setRangeCopiesID;
jmethodID AwtPrintControl::setResID;
+jmethodID AwtPrintControl::setJobAttributesID;
BOOL AwtPrintControl::IsSupportedLevel(HANDLE hPrinter, DWORD dwLevel) {
@@ -297,6 +298,10 @@
AwtPrintControl::setPrinterID =
env->GetMethodID(cls, "setPrinterNameAttrib", "(Ljava/lang/String;)V");
+ AwtPrintControl::setJobAttributesID =
+ env->GetMethodID(cls, "setJobAttributes",
+ "(Ljavax/print/attribute/PrintRequestAttributeSet;IISSSSSSS)V");
+
DASSERT(AwtPrintControl::driverDoesMultipleCopiesID != NULL);
DASSERT(AwtPrintControl::getPrintDCID != NULL);
DASSERT(AwtPrintControl::setPrintDCID != NULL);
@@ -327,6 +332,7 @@
DASSERT(AwtPrintControl::getSidesID != NULL);
DASSERT(AwtPrintControl::getSelectID != NULL);
DASSERT(AwtPrintControl::getPrintToFileEnabledID != NULL);
+ DASSERT(AwtPrintControl::setJobAttributesID != NULL);
CATCH_BAD_ALLOC;
--- a/jdk/src/windows/native/sun/windows/awt_PrintControl.h Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_PrintControl.h Fri Sep 20 19:15:59 2013 -0700
@@ -47,7 +47,6 @@
static jmethodID setDevmodeID;
static jmethodID getDevnamesID;
static jmethodID setDevnamesID;
-
static jmethodID getWin32MediaID;
static jmethodID setWin32MediaID;
static jmethodID getWin32MediaTrayID;
@@ -73,6 +72,7 @@
static jmethodID setNativeAttID;
static jmethodID setRangeCopiesID;
static jmethodID setResID;
+ static jmethodID setJobAttributesID;
static void initIDs(JNIEnv *env, jclass cls);
static BOOL FindPrinter(jstring printerName, LPBYTE pPrinterEnum,
--- a/jdk/src/windows/native/sun/windows/awt_PrintJob.cpp Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_PrintJob.cpp Fri Sep 20 19:15:59 2013 -0700
@@ -329,6 +329,156 @@
static int embolden(int currentWeight);
static BOOL getPrintableArea(HDC pdc, HANDLE hDevMode, RectDouble *margin);
+
+
+/************************************************************************
+ * DocumentProperties native support
+ */
+
+/* Values must match those defined in WPrinterJob.java */
+static const DWORD SET_COLOR = 0x00000200;
+static const DWORD SET_ORIENTATION = 0x00004000;
+static const DWORD SET_COLLATED = 0x00008000;
+static const DWORD SET_DUP_VERTICAL = 0x00000010;
+static const DWORD SET_DUP_HORIZONTAL = 0x00000020;
+static const DWORD SET_RES_HIGH = 0x00000040;
+static const DWORD SET_RES_LOW = 0x00000080;
+
+/*
+ * Copy DEVMODE state back into JobAttributes.
+ */
+
+static void UpdateJobAttributes(JNIEnv *env,
+ jobject wJob,
+ jobject attrSet,
+ DEVMODE *devmode) {
+
+ DWORD dmValues = 0;
+ int xRes = 0, yRes = 0;
+
+ if (devmode->dmFields & DM_COLOR) {
+ if (devmode->dmColor == DMCOLOR_COLOR) {
+ dmValues |= SET_COLOR;
+ }
+ }
+
+ if (devmode->dmFields & DM_ORIENTATION) {
+ if (devmode->dmOrientation == DMORIENT_LANDSCAPE) {
+ dmValues |= SET_ORIENTATION;
+ }
+ }
+
+ if (devmode->dmFields & DM_COLLATE &&
+ devmode->dmCollate == DMCOLLATE_TRUE) {
+ dmValues |= SET_COLLATED;
+ }
+
+ if (devmode->dmFields & DM_PRINTQUALITY) {
+ /* value < 0 indicates quality setting.
+ * value > 0 indicates X resolution. In that case
+ * hopefully we will also find y-resolution specified.
+ * If its not, assume its the same as x-res.
+ * Maybe Java code should try to reconcile this against
+ * the printers claimed set of supported resolutions.
+ */
+ if (devmode->dmPrintQuality < 0) {
+ if (devmode->dmPrintQuality == DMRES_HIGH) {
+ dmValues |= SET_RES_HIGH;
+ } else if ((devmode->dmPrintQuality == DMRES_LOW) ||
+ (devmode->dmPrintQuality == DMRES_DRAFT)) {
+ dmValues |= SET_RES_LOW;
+ }
+ /* else if (devmode->dmPrintQuality == DMRES_MEDIUM)
+ * will set to NORMAL.
+ */
+ } else {
+ xRes = devmode->dmPrintQuality;
+ yRes = (devmode->dmFields & DM_YRESOLUTION) ?
+ devmode->dmYResolution : devmode->dmPrintQuality;
+ }
+ }
+
+ if (devmode->dmFields & DM_DUPLEX) {
+ if (devmode->dmDuplex == DMDUP_HORIZONTAL) {
+ dmValues |= SET_DUP_HORIZONTAL;
+ } else if (devmode->dmDuplex == DMDUP_VERTICAL) {
+ dmValues |= SET_DUP_VERTICAL;
+ }
+ }
+
+ env->CallVoidMethod(wJob, AwtPrintControl::setJobAttributesID, attrSet,
+ devmode->dmFields, dmValues, devmode->dmCopies,
+ devmode->dmPaperSize, devmode->dmPaperWidth,
+ devmode->dmPaperLength, devmode->dmDefaultSource,
+ xRes, yRes);
+
+}
+
+JNIEXPORT jboolean JNICALL
+Java_sun_awt_windows_WPrinterJob_showDocProperties(JNIEnv *env,
+ jobject wJob,
+ jlong hWndParent,
+ jobject attrSet,
+ jint dmFields,
+ jshort copies,
+ jshort collate,
+ jshort color,
+ jshort duplex,
+ jshort orient,
+ jshort paper,
+ jshort bin,
+ jshort xres_quality,
+ jshort yres)
+{
+ TRY;
+
+ HGLOBAL hDevMode = AwtPrintControl::getPrintHDMode(env, wJob);
+ HGLOBAL hDevNames = AwtPrintControl::getPrintHDName(env, wJob);
+ DEVMODE *devmode = NULL;
+ DEVNAMES *devnames = NULL;
+ LONG rval = IDCANCEL;
+ jboolean ret = JNI_FALSE;
+
+ if (hDevMode != NULL && hDevNames != NULL) {
+ devmode = (DEVMODE *)::GlobalLock(hDevMode);
+ devnames = (DEVNAMES *)::GlobalLock(hDevNames);
+
+ LPTSTR lpdevnames = (LPTSTR)devnames;
+ // No need to call _tcsdup as we won't unlock until we are done.
+ LPTSTR printerName = lpdevnames+devnames->wDeviceOffset;
+ LPTSTR portName = lpdevnames+devnames->wOutputOffset;
+
+ HANDLE hPrinter;
+ if (::OpenPrinter(printerName, &hPrinter, NULL) == TRUE) {
+ devmode->dmFields |= dmFields;
+ devmode->dmCopies = copies;
+ devmode->dmCollate = collate;
+ devmode->dmColor = color;
+ devmode->dmDuplex = duplex;
+ devmode->dmOrientation = orient;
+ devmode->dmPrintQuality = xres_quality;
+ devmode->dmYResolution = yres;
+ devmode->dmPaperSize = paper;
+ devmode->dmDefaultSource = bin;
+
+ rval = ::DocumentProperties((HWND)hWndParent,
+ hPrinter, printerName, devmode, devmode,
+ DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT);
+ if (rval == IDOK) {
+ UpdateJobAttributes(env, wJob, attrSet, devmode);
+ ret = JNI_TRUE;
+ }
+ VERIFY(::ClosePrinter(hPrinter));
+ }
+ ::GlobalUnlock(hDevNames);
+ ::GlobalUnlock(hDevMode);
+ }
+
+ return ret;
+
+ CATCH_BAD_ALLOC_RET(0);
+}
+
/************************************************************************
* WPageDialog native methods
*/
@@ -732,7 +882,6 @@
memset(&pd, 0, sizeof(PRINTDLG));
pd.lStructSize = sizeof(PRINTDLG);
pd.Flags = PD_RETURNDEFAULT | PD_RETURNDC;
-
if (::PrintDlg(&pd)) {
printDC = pd.hDC;
hDevMode = pd.hDevMode;
@@ -792,8 +941,19 @@
jint imgPixelWid = GetDeviceCaps(printDC, HORZRES);
jint imgPixelHgt = GetDeviceCaps(printDC, VERTRES);
+ // The DC may be obtained when we first selected the printer as a
+ // result of a call to setNativePrintService.
+ // If the Devmode was obtained later on from the DocumentProperties dialog
+ // the DC won't have been updated and its settings may be for PORTRAIT.
+ // This may happen in other cases too, but was observed for the above.
+ // To get a DC compatible with this devmode we should really call
+ // CreateDC() again to get a DC for the devmode we are using.
+ // The changes for that are a lot more risk, so to minimise that
+ // risk, assume its not LANDSCAPE unless width > height, even if the
+ // devmode says its LANDSCAPE.
// if the values were obtained from a rotated device, swap.
- if (getOrientationFromDevMode2(hDevMode) == DMORIENT_LANDSCAPE) {
+ if ((getOrientationFromDevMode2(hDevMode) == DMORIENT_LANDSCAPE) &&
+ (imgPixelWid > imgPixelHgt)) {
jint tmp;
tmp = xPixelRes;
xPixelRes = yPixelRes;
@@ -941,6 +1101,9 @@
setBooleanField(env, self, DRIVER_COLLATE_STR, JNI_FALSE);
}
+ if (dmFields & DM_COPIES) {
+ setBooleanField(env, self, DRIVER_COPIES_STR, JNI_TRUE);
+ }
}
CATCH_BAD_ALLOC;
--- a/jdk/test/ProblemList.txt Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/test/ProblemList.txt Fri Sep 20 19:15:59 2013 -0700
@@ -166,6 +166,13 @@
# 8021186
jdk/lambda/vm/DefaultMethodsTest.java generic-all
+# 8024423 - JVMTI: GetLoadedClasses doesn't enumerate anonymous classes
+demo/jvmti/hprof/HeapAllTest.java generic-all
+demo/jvmti/hprof/HeapBinaryFormatTest.java generic-all
+demo/jvmti/hprof/HeapDumpTest.java generic-all
+demo/jvmti/hprof/OptionsTest.java generic-all
+demo/jvmti/hprof/StackMapTableTest.java generic-all
+
############################################################################
# jdk_net
--- a/jdk/test/javax/imageio/plugins/jpeg/JpegWriterLeakTest.java Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/test/javax/imageio/plugins/jpeg/JpegWriterLeakTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 8020983
+ * @bug 8020983 8024697
* @summary Test verifies that jpeg writer instances are collected
* even if destroy() or reset() methods is not invoked.
*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/java2d/cmm/ProfileOp/DisposalCrashTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -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<ICC_Profile> queue = new ReferenceQueue<>();
+ static final Vector<Reference<? extends ICC_Profile>> 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<ICC_Profile> ref = new WeakReference<>(p, queue);
+
+ v.add(ref);
+
+ return p;
+ }
+}
--- a/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java Fri Sep 20 17:11:32 2013 -0700
+++ b/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -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 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 @@
}
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 @@
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 @@
}
}
+ 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();
--- a/langtools/.hgtags Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/.hgtags Fri Sep 20 19:15:59 2013 -0700
@@ -227,3 +227,5 @@
76cfe7c61f2575ea5400845b8e80dab6f4b1d7d0 jdk8-b103
dd4a00c220c6e14d9b2ce93a2bd436a1d04f0d03 jdk8-b104
375834b5cf086dd7ce9e49f602d81bb51d3e0fa9 jdk8-b105
+fcd768844b9926c5f994292ec6350c20cc7c0f76 jdk8-b106
+3f274927ec1863544b8214262ab02b7de2970da6 jdk8-b107
--- a/langtools/README Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/README Fri Sep 20 19:15:59 2013 -0700
@@ -32,7 +32,7 @@
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
--- a/langtools/make/netbeans/langtools/build.xml Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/make/netbeans/langtools/build.xml Fri Sep 20 19:15:59 2013 -0700
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -55,10 +55,18 @@
description="Build one or all langtools tools"
/>
+ <condition property="bootstrap" value="bootstrap-" else="">
+ <isset property="langtools.tool.bootstrap"/>
+ </condition>
+
+ <condition property="bcp" value="${build.bootstrap.dir}/classes" else="${build.classes.dir}">
+ <isset property="langtools.tool.bootstrap"/>
+ </condition>
+
<target name="-build-tool" if="langtools.tool.name">
- <echo level="info" message="Building ${langtools.tool.name}"/>
+ <echo level="info" message="Building ${bootstrap}${langtools.tool.name}"/>
<echo level="verbose" message="(Unset langtools.tool.name to build all tools)"/>
- <antcall target="build-${langtools.tool.name}"/>
+ <antcall target="build-${bootstrap}${langtools.tool.name}"/>
</target>
<target name="-build-all" unless="langtools.tool.name">
@@ -89,8 +97,9 @@
<target name="run" depends="-check-target.java.home,build,-def-run,-get-tool-and-args"
description="run tool">
- <echo level="info" message="Run ${langtools.tool.name} with args ${langtools.tool.args}"/>
- <run mainclass="com.sun.tools.${langtools.tool.name}.Main" args="${langtools.tool.args}"/>
+ <echo level="info" message="${bcp}"/>
+ <echo level="info" message="Run ${bootstrap}${langtools.tool.name} with args ${langtools.tool.args}"/>
+ <run bcp="${bcp}" mainclass="com.sun.tools.${langtools.tool.name}.Main" args="${langtools.tool.args}"/>
</target>
<!-- Run a selected class. (action: run.single; shift-F6) -->
@@ -136,9 +145,9 @@
<!-- Debug tool in NetBeans. -->
<target name="debug" depends="-check-target.java.home,-def-run,-def-start-debugger,-get-tool-and-args,build" if="netbeans.home">
- <echo level="info" message="Debug ${langtools.tool.name} with args ${langtools.tool.args}"/>
+ <echo level="info" message="Debug ${boostrap}${langtools.tool.name} with args ${langtools.tool.args}"/>
<start-debugger/>
- <run mainclass="com.sun.tools.${langtools.tool.name}.Main" args="${langtools.tool.args}" jpda.jvmargs="${jpda.jvmargs}"/>
+ <run bcp="${bcp}" mainclass="com.sun.tools.${langtools.tool.name}.Main" args="${langtools.tool.args}" jpda.jvmargs="${jpda.jvmargs}"/>
</target>
<!-- Debug a selected class . -->
@@ -207,6 +216,7 @@
<target name="-get-tool-if-set" depends="-def-select-tool">
<select-tool
toolproperty="langtools.tool.name"
+ bootstrapproperty="langtools.tool.bootstrap"
propertyfile="${langtools.properties}"
askIfUnset="false"
/>
@@ -216,6 +226,7 @@
<select-tool
toolproperty="langtools.tool.name"
argsproperty="langtools.tool.args"
+ bootstrapproperty="langtools.tool.bootstrap"
propertyfile="${langtools.properties}"
askIfUnset="true"
/>
@@ -226,10 +237,12 @@
<macrodef name="run">
<attribute name="mainclass"/>
<attribute name="args" default=""/>
+ <attribute name="bcp" default="${build.classes.dir}"/>
<attribute name="jpda.jvmargs" default=""/>
+
<sequential>
<java fork="true" jvm="${target.java}" classname="@{mainclass}">
- <jvmarg line="-Xbootclasspath/p:${build.classes.dir}"/>
+ <jvmarg line="-Xbootclasspath/p:${bcp}"/>
<jvmarg line="@{jpda.jvmargs}"/>
<arg line="@{args}"/>
</java>
--- a/langtools/make/tools/anttasks/SelectToolTask.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/make/tools/anttasks/SelectToolTask.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -43,6 +43,7 @@
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.EnumSet;
import java.util.List;
import java.util.Properties;
import javax.swing.JButton;
@@ -71,6 +72,31 @@
* is invoked to allow the user to set or reset values for use in property mode.
*/
public class SelectToolTask extends Task {
+
+ enum ToolChoices {
+ NONE(""),
+ JAVAC("javac"),
+ JAVADOC("javadoc"),
+ JAVAH("javah"),
+ JAVAP("javap");
+
+ String toolName;
+ boolean bootstrap;
+
+ ToolChoices(String toolName) {
+ this(toolName, false);
+ }
+
+ ToolChoices(String toolName, boolean boostrap) {
+ this.toolName = toolName;
+ }
+
+ @Override
+ public String toString() {
+ return toolName;
+ }
+ }
+
/**
* Set the location of the private properties file used to keep the retain
* user preferences for this repository.
@@ -97,6 +123,14 @@
}
/**
+ * Set the name of the property which will be set to the execution args of the
+ * selected tool, if any. The args default to an empty string.
+ */
+ public void setBootstrapProperty(String bootstrapProperty) {
+ this.bootstrapProperty = bootstrapProperty;
+ }
+
+ /**
* Specify whether or not to pop up a dialog if the user has not specified
* a default value for a property.
*/
@@ -110,6 +144,7 @@
Properties props = readProperties(propertyFile);
toolName = props.getProperty("tool.name");
+ toolBootstrap = props.getProperty("tool.bootstrap") != null;
if (toolName != null) {
toolArgs = props.getProperty(toolName + ".args", "");
}
@@ -123,6 +158,8 @@
// finally, return required values, if any
if (toolProperty != null && !(toolName == null || toolName.equals(""))) {
p.setProperty(toolProperty, toolName);
+ if (toolBootstrap)
+ p.setProperty(bootstrapProperty, "true");
if (argsProperty != null && toolArgs != null)
p.setProperty(argsProperty, toolArgs);
@@ -134,14 +171,20 @@
JOptionPane p = createPane(guiProps);
p.createDialog("Select Tool").setVisible(true);
- toolName = (String) toolChoice.getSelectedItem();
+ toolName = ((ToolChoices)toolChoice.getSelectedItem()).toolName;
toolArgs = argsField.getText();
-
+ toolBootstrap = bootstrapCheckbox.isSelected();
if (defaultCheck.isSelected()) {
if (toolName.equals("")) {
fileProps.remove("tool.name");
+ fileProps.remove("tool.bootstrap");
} else {
fileProps.put("tool.name", toolName);
+ if (toolBootstrap) {
+ fileProps.put("tool.bootstrap", "true");
+ } else {
+ fileProps.remove("tool.bootstrap");
+ }
fileProps.put(toolName + ".args", toolArgs);
}
writeProperties(propertyFile, fileProps);
@@ -154,32 +197,38 @@
lc.insets.right = 10;
lc.insets.bottom = 3;
GridBagConstraints fc = new GridBagConstraints();
- fc.anchor = GridBagConstraints.WEST;
fc.gridx = 1;
- fc.gridwidth = GridBagConstraints.REMAINDER;
+ fc.gridwidth = GridBagConstraints.NONE;
fc.insets.bottom = 3;
+ JPanel toolPane = new JPanel(new GridBagLayout());
+
JLabel toolLabel = new JLabel("Tool:");
body.add(toolLabel, lc);
- String[] toolChoices = { "apt", "javac", "javadoc", "javah", "javap" };
- if (true || toolProperty == null) {
- // include empty value in setup mode
- List<String> l = new ArrayList<String>(Arrays.asList(toolChoices));
- l.add(0, "");
- toolChoices = l.toArray(new String[l.size()]);
- }
- toolChoice = new JComboBox(toolChoices);
+ EnumSet<ToolChoices> toolChoices = toolProperty == null ?
+ EnumSet.allOf(ToolChoices.class) : EnumSet.range(ToolChoices.JAVAC, ToolChoices.JAVAP);
+ toolChoice = new JComboBox(toolChoices.toArray());
if (toolName != null)
- toolChoice.setSelectedItem(toolName);
+ toolChoice.setSelectedItem(ToolChoices.valueOf(toolName.toUpperCase()));
toolChoice.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
- String tn = (String) e.getItem();
+ String tn = ((ToolChoices)e.getItem()).toolName;
argsField.setText(getDefaultArgsForTool(props, tn));
if (toolProperty != null)
okButton.setEnabled(!tn.equals(""));
}
});
- body.add(toolChoice, fc);
+ GridBagConstraints checkConstraint = new GridBagConstraints();
+ fc.anchor = GridBagConstraints.EAST;
+
+ GridBagConstraints toolConstraint = new GridBagConstraints();
+ fc.anchor = GridBagConstraints.WEST;
+
+ toolPane.add(toolChoice, toolConstraint);
+ bootstrapCheckbox = new JCheckBox("bootstrap", toolBootstrap);
+ toolPane.add(bootstrapCheckbox, checkConstraint);
+
+ body.add(toolPane, fc);
argsField = new JTextField(getDefaultArgsForTool(props, toolName), 40);
if (toolProperty == null || argsProperty != null) {
@@ -190,7 +239,7 @@
public void focusGained(FocusEvent e) {
}
public void focusLost(FocusEvent e) {
- String toolName = (String) toolChoice.getSelectedItem();
+ String toolName = ((ToolChoices)toolChoice.getSelectedItem()).toolName;
if (toolName.length() > 0)
props.put(toolName + ".args", argsField.getText());
}
@@ -271,16 +320,19 @@
// Ant task parameters
private boolean askIfUnset;
private String toolProperty;
+ private String bootstrapProperty;
private String argsProperty;
private File propertyFile;
// GUI components
private JComboBox toolChoice;
+ private JCheckBox bootstrapCheckbox;
private JTextField argsField;
private JCheckBox defaultCheck;
private JButton okButton;
// Result values for the client
private String toolName;
+ private boolean toolBootstrap;
private String toolArgs;
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java Fri Sep 20 19:15:59 2013 -0700
@@ -157,7 +157,7 @@
addAllProfilesLink(div);
}
body.addContent(div);
- if (configuration.showProfiles) {
+ if (configuration.showProfiles && configuration.profilePackages.size() > 0) {
Content profileSummary = configuration.getResource("doclet.Profiles");
addProfilesList(profileSummary, body);
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java Fri Sep 20 19:15:59 2013 -0700
@@ -118,7 +118,7 @@
if (prev != null) {
Content prevLink = getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.Kind.CLASS, prev.asClassDoc())
- .label(configuration.getText("doclet.Prev_Class")).strong(true));
+ .label(prevclassLabel).strong(true));
li = HtmlTree.LI(prevLink);
}
else
@@ -136,7 +136,7 @@
if (next != null) {
Content nextLink = getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.Kind.CLASS, next.asClassDoc())
- .label(configuration.getText("doclet.Next_Class")).strong(true));
+ .label(nextclassLabel).strong(true));
li = HtmlTree.LI(nextLink);
}
else
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java Fri Sep 20 19:15:59 2013 -0700
@@ -126,7 +126,7 @@
if (prev != null) {
Content prevLink = getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.Kind.CLASS, prev)
- .label(configuration.getText("doclet.Prev_Class")).strong(true));
+ .label(prevclassLabel).strong(true));
li = HtmlTree.LI(prevLink);
}
else
@@ -144,7 +144,7 @@
if (next != null) {
Content nextLink = getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.Kind.CLASS, next)
- .label(configuration.getText("doclet.Next_Class")).strong(true));
+ .label(nextclassLabel).strong(true));
li = HtmlTree.LI(nextLink);
}
else
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java Fri Sep 20 19:15:59 2013 -0700
@@ -205,13 +205,20 @@
* {@inheritDoc}
*/
protected void generateProfileFiles() throws Exception {
- if (configuration.showProfiles) {
+ if (configuration.showProfiles && configuration.profilePackages.size() > 0) {
ProfileIndexFrameWriter.generate(configuration);
Profile prevProfile = null, nextProfile;
+ String profileName;
for (int i = 1; i < configuration.profiles.getProfileCount(); i++) {
- ProfilePackageIndexFrameWriter.generate(configuration, Profile.lookup(i).name);
+ profileName = Profile.lookup(i).name;
+ // Generate profile package pages only if there are any packages
+ // in a profile to be documented. The profilePackages map will not
+ // contain an entry for the profile if there are no packages to be documented.
+ if (!configuration.shouldDocumentProfile(profileName))
+ continue;
+ ProfilePackageIndexFrameWriter.generate(configuration, profileName);
PackageDoc[] packages = configuration.profilePackages.get(
- Profile.lookup(i).name);
+ profileName);
PackageDoc prev = null, next;
for (int j = 0; j < packages.length; j++) {
// if -nodeprecated option is set and the package is marked as
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Fri Sep 20 19:15:59 2013 -0700
@@ -406,10 +406,7 @@
Content htmlDocType = DocType.TRANSITIONAL;
Content htmlComment = new Comment(configuration.getText("doclet.New_Page"));
Content head = new HtmlTree(HtmlTag.HEAD);
- if (!configuration.notimestamp) {
- Content headComment = new Comment(getGeneratedByString());
- head.addContent(headComment);
- }
+ head.addContent(getGeneratedBy(!configuration.notimestamp));
if (configuration.charset.length() > 0) {
Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE,
configuration.charset);
@@ -502,16 +499,17 @@
if (!configuration.nonavbar) {
String allClassesId = "allclasses_";
HtmlTree navDiv = new HtmlTree(HtmlTag.DIV);
+ Content skipNavLinks = configuration.getResource("doclet.Skip_navigation_links");
if (header) {
body.addContent(HtmlConstants.START_OF_TOP_NAVBAR);
navDiv.addStyle(HtmlStyle.topNav);
allClassesId += "navbar_top";
Content a = getMarkerAnchor("navbar_top");
+ //WCAG - Hyperlinks should contain text or an image with alt text - for AT tools
navDiv.addContent(a);
- Content skipLinkContent = getHyperLink(DocLink.fragment("skip-navbar_top"),
- HtmlTree.EMPTY,
- configuration.getText("doclet.Skip_navigation_links"),
- "");
+ Content skipLinkContent = HtmlTree.DIV(HtmlStyle.skipNav, getHyperLink(
+ DocLink.fragment("skip-navbar_top"), skipNavLinks,
+ skipNavLinks.toString(), ""));
navDiv.addContent(skipLinkContent);
} else {
body.addContent(HtmlConstants.START_OF_BOTTOM_NAVBAR);
@@ -519,10 +517,9 @@
allClassesId += "navbar_bottom";
Content a = getMarkerAnchor("navbar_bottom");
navDiv.addContent(a);
- Content skipLinkContent = getHyperLink(DocLink.fragment("skip-navbar_bottom"),
- HtmlTree.EMPTY,
- configuration.getText("doclet.Skip_navigation_links"),
- "");
+ Content skipLinkContent = HtmlTree.DIV(HtmlStyle.skipNav, getHyperLink(
+ DocLink.fragment("skip-navbar_bottom"), skipNavLinks,
+ skipNavLinks.toString(), ""));
navDiv.addContent(skipLinkContent);
}
if (header) {
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java Fri Sep 20 19:15:59 2013 -0700
@@ -130,10 +130,14 @@
String profileName;
for (int i = 1; i < configuration.profiles.getProfileCount(); i++) {
profileName = Profile.lookup(i).name;
- Content profileLinkContent = getTargetProfileLink("classFrame",
- new StringContent(profileName), profileName);
- Content li = HtmlTree.LI(profileLinkContent);
- ul.addContent(li);
+ // If the profile has valid packages to be documented, add it to the
+ // profiles list on overview-summary.html page.
+ if (configuration.shouldDocumentProfile(profileName)) {
+ Content profileLinkContent = getTargetProfileLink("classFrame",
+ new StringContent(profileName), profileName);
+ Content li = HtmlTree.LI(profileLinkContent);
+ ul.addContent(li);
+ }
}
profilesDiv.addContent(ul);
Content div = HtmlTree.DIV(HtmlStyle.contentContainer, profilesDiv);
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java Fri Sep 20 19:15:59 2013 -0700
@@ -88,8 +88,13 @@
Content div = HtmlTree.DIV(HtmlStyle.indexContainer, heading);
HtmlTree ul = new HtmlTree(HtmlTag.UL);
ul.setTitle(profilesLabel);
+ String profileName;
for (int i = 1; i < profiles.getProfileCount(); i++) {
- ul.addContent(getProfile(i));
+ profileName = (Profile.lookup(i)).name;
+ // If the profile has valid packages to be documented, add it to the
+ // left-frame generated for profile index.
+ if (configuration.shouldDocumentProfile(profileName))
+ ul.addContent(getProfile(profileName));
}
div.addContent(ul);
body.addContent(div);
@@ -98,13 +103,12 @@
/**
* Gets each profile name as a separate link.
*
- * @param profile the profile being documented
+ * @param profileName the profile being documented
* @return content for the profile link
*/
- protected Content getProfile(int profile) {
+ protected Content getProfile(String profileName) {
Content profileLinkContent;
Content profileLabel;
- String profileName = (Profile.lookup(profile)).name;
profileLabel = new StringContent(profileName);
profileLinkContent = getHyperLink(DocPaths.profileFrame(profileName), profileLabel, "",
"packageListFrame");
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileWriterImpl.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileWriterImpl.java Fri Sep 20 19:15:59 2013 -0700
@@ -138,6 +138,7 @@
"classFrame", new StringContent(pkg.name()), profile.name);
Content heading = HtmlTree.HEADING(HtmlTag.H3, pkgName);
HtmlTree li = HtmlTree.LI(HtmlStyle.blockList, heading);
+ addPackageDeprecationInfo(li, pkg);
return li;
}
@@ -175,6 +176,30 @@
}
/**
+ * Add the profile package deprecation information to the documentation tree.
+ *
+ * @param li the content tree to which the deprecation information will be added
+ * @param pkg the PackageDoc that is added
+ */
+ public void addPackageDeprecationInfo(Content li, PackageDoc pkg) {
+ Tag[] deprs;
+ if (Util.isDeprecated(pkg)) {
+ deprs = pkg.tags("deprecated");
+ HtmlTree deprDiv = new HtmlTree(HtmlTag.DIV);
+ deprDiv.addStyle(HtmlStyle.deprecatedContent);
+ Content deprPhrase = HtmlTree.SPAN(HtmlStyle.strong, deprecatedPhrase);
+ deprDiv.addContent(deprPhrase);
+ if (deprs.length > 0) {
+ Tag[] commentTags = deprs[0].inlineTags();
+ if (commentTags.length > 0) {
+ addInlineDeprecatedComment(pkg, deprs[0], deprDiv);
+ }
+ }
+ li.addContent(deprDiv);
+ }
+ }
+
+ /**
* Get "PREV PROFILE" link in the navigation bar.
*
* @return a content tree for the previous link
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java Fri Sep 20 19:15:59 2013 -0700
@@ -191,10 +191,7 @@
Content htmlDocType = DocType.FRAMESET;
Content htmlComment = new Comment(configuration.getText("doclet.New_Page"));
Content head = new HtmlTree(HtmlTag.HEAD);
- if (! noTimeStamp) {
- Content headComment = new Comment(getGeneratedByString());
- head.addContent(headComment);
- }
+ head.addContent(getGeneratedBy(!noTimeStamp));
if (configuration.charset.length() > 0) {
Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE,
configuration.charset);
@@ -210,9 +207,13 @@
write(htmlDocument);
}
- protected String getGeneratedByString() {
- Calendar calendar = new GregorianCalendar(TimeZone.getDefault());
- Date today = calendar.getTime();
- return "Generated by javadoc ("+ ConfigurationImpl.BUILD_DATE + ") on " + today;
+ protected Comment getGeneratedBy(boolean timestamp) {
+ String text = "Generated by javadoc"; // marker string, deliberately not localized
+ if (timestamp) {
+ Calendar calendar = new GregorianCalendar(TimeZone.getDefault());
+ Date today = calendar.getTime();
+ text += " ("+ ConfigurationImpl.BUILD_DATE + ") on " + today;
+ }
+ return new Comment(text);
}
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlStyle.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlStyle.java Fri Sep 20 19:15:59 2013 -0700
@@ -68,6 +68,7 @@
packageSummary,
rowColor,
serializedFormContainer,
+ skipNav,
sourceContainer,
sourceLineNo,
strong,
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java Fri Sep 20 19:15:59 2013 -0700
@@ -203,27 +203,27 @@
useLabel = getResource("doclet.navClassUse");
prevLabel = getResource("doclet.Prev");
nextLabel = getResource("doclet.Next");
- prevclassLabel = getResource("doclet.Prev_Class");
- nextclassLabel = getResource("doclet.Next_Class");
+ prevclassLabel = getNonBreakResource("doclet.Prev_Class");
+ nextclassLabel = getNonBreakResource("doclet.Next_Class");
summaryLabel = getResource("doclet.Summary");
detailLabel = getResource("doclet.Detail");
framesLabel = getResource("doclet.Frames");
- noframesLabel = getResource("doclet.No_Frames");
+ noframesLabel = getNonBreakResource("doclet.No_Frames");
treeLabel = getResource("doclet.Tree");
classLabel = getResource("doclet.Class");
deprecatedLabel = getResource("doclet.navDeprecated");
deprecatedPhrase = getResource("doclet.Deprecated");
- allclassesLabel = getResource("doclet.All_Classes");
- allpackagesLabel = getResource("doclet.All_Packages");
- allprofilesLabel = getResource("doclet.All_Profiles");
+ allclassesLabel = getNonBreakResource("doclet.All_Classes");
+ allpackagesLabel = getNonBreakResource("doclet.All_Packages");
+ allprofilesLabel = getNonBreakResource("doclet.All_Profiles");
indexLabel = getResource("doclet.Index");
helpLabel = getResource("doclet.Help");
seeLabel = getResource("doclet.See");
descriptionLabel = getResource("doclet.Description");
- prevpackageLabel = getResource("doclet.Prev_Package");
- nextpackageLabel = getResource("doclet.Next_Package");
- prevprofileLabel = getResource("doclet.Prev_Profile");
- nextprofileLabel = getResource("doclet.Next_Profile");
+ prevpackageLabel = getNonBreakResource("doclet.Prev_Package");
+ nextpackageLabel = getNonBreakResource("doclet.Next_Package");
+ prevprofileLabel = getNonBreakResource("doclet.Prev_Profile");
+ nextprofileLabel = getNonBreakResource("doclet.Next_Profile");
packagesLabel = getResource("doclet.Packages");
profilesLabel = getResource("doclet.Profiles");
methodDetailsLabel = getResource("doclet.Method_Detail");
@@ -257,6 +257,27 @@
}
/**
+ * Get the configuration string as a content, replacing spaces
+ * with non-breaking spaces.
+ *
+ * @param key the key to look for in the configuration file
+ * @return a content tree for the text
+ */
+ public Content getNonBreakResource(String key) {
+ String text = configuration.getText(key);
+ Content c = configuration.newContent();
+ int start = 0;
+ int p;
+ while ((p = text.indexOf(" ", start)) != -1) {
+ c.addContent(text.substring(start, p));
+ c.addContent(RawHtml.nbsp);
+ start = p + 1;
+ }
+ c.addContent(text.substring(start));
+ return c;
+ }
+
+ /**
* Get the configuration string as a content.
*
* @param key the key to look for in the configuration file
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java Fri Sep 20 19:15:59 2013 -0700
@@ -383,35 +383,52 @@
DocErrorReporter reporter);
private void initProfiles() throws IOException {
+ if (profilespath.isEmpty())
+ return;
+
profiles = Profiles.read(new File(profilespath));
- // Generate profiles documentation only is profilespath is set and if
- // profiles is not null and profiles count is 1 or more.
- showProfiles = (!profilespath.isEmpty() && profiles != null &&
- profiles.getProfileCount() > 0);
- }
+
+ // Group the packages to be documented by the lowest profile (if any)
+ // in which each appears
+ Map<Profile, List<PackageDoc>> interimResults =
+ new EnumMap<Profile, List<PackageDoc>>(Profile.class);
+ for (Profile p: Profile.values())
+ interimResults.put(p, new ArrayList<PackageDoc>());
- private void initProfilePackages() throws IOException {
- profilePackages = new HashMap<String,PackageDoc[]>();
- ArrayList<PackageDoc> results;
- Map<String,PackageDoc> packageIndex = new HashMap<String,PackageDoc>();
- for (int i = 0; i < packages.length; i++) {
- PackageDoc pkg = packages[i];
- packageIndex.put(pkg.name(), pkg);
+ for (PackageDoc pkg: packages) {
+ if (nodeprecated && Util.isDeprecated(pkg)) {
+ continue;
+ }
+ // the getProfile method takes a type name, not a package name,
+ // but isn't particularly fussy about the simple name -- so just use *
+ int i = profiles.getProfile(pkg.name().replace(".", "/") + "/*");
+ Profile p = Profile.lookup(i);
+ if (p != null) {
+ List<PackageDoc> pkgs = interimResults.get(p);
+ pkgs.add(pkg);
+ }
}
- for (int i = 1; i < profiles.getProfileCount(); i++) {
- Set<String> profPkgs = profiles.getPackages(i);
- results = new ArrayList<PackageDoc>();
- for (String packageName : profPkgs) {
- packageName = packageName.replace("/", ".");
- PackageDoc profPkg = packageIndex.get(packageName);
- if (profPkg != null) {
- results.add(profPkg);
- }
- }
- Collections.sort(results);
- PackageDoc[] profilePkgs = results.toArray(new PackageDoc[]{});
- profilePackages.put(Profile.lookup(i).name, profilePkgs);
+
+ // Build the profilePackages structure used by the doclet
+ profilePackages = new HashMap<String,PackageDoc[]>();
+ List<PackageDoc> prev = Collections.<PackageDoc>emptyList();
+ int size;
+ for (Map.Entry<Profile,List<PackageDoc>> e: interimResults.entrySet()) {
+ Profile p = e.getKey();
+ List<PackageDoc> pkgs = e.getValue();
+ pkgs.addAll(prev); // each profile contains all lower profiles
+ Collections.sort(pkgs);
+ size = pkgs.size();
+ // For a profile, if there are no packages to be documented, do not add
+ // it to profilePackages map.
+ if (size > 0)
+ profilePackages.put(p.name, pkgs.toArray(new PackageDoc[pkgs.size()]));
+ prev = pkgs;
}
+
+ // Generate profiles documentation if any profile contains any
+ // of the packages to be documented.
+ showProfiles = !prev.isEmpty();
}
private void initPackageArray() {
@@ -534,13 +551,10 @@
public void setOptions() throws Fault {
initPackageArray();
setOptions(root.options());
- if (!profilespath.isEmpty()) {
- try {
- initProfiles();
- initProfilePackages();
- } catch (Exception e) {
- throw new DocletAbortException(e);
- }
+ try {
+ initProfiles();
+ } catch (Exception e) {
+ throw new DocletAbortException(e);
}
setSpecificDocletOptions(root.options());
}
@@ -713,6 +727,17 @@
}
/**
+ * Check the validity of the given profile. Return false if there are no
+ * valid packages to be documented for the profile.
+ *
+ * @param profileName the profile that needs to be validated.
+ * @return true if the profile has valid packages to be documented.
+ */
+ public boolean shouldDocumentProfile(String profileName) {
+ return profilePackages.containsKey(profileName);
+ }
+
+ /**
* Check the validity of the given Source or Output File encoding on this
* platform.
*
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css Fri Sep 20 19:15:59 2013 -0700
@@ -180,6 +180,12 @@
margin: auto 5px;
border:1px solid #c9aa44;
}
+.skipNav {
+ position:absolute;
+ top:auto;
+ left:-9999px;
+ overflow:hidden;
+ }
/*
Page header and footer styles
*/
@@ -372,7 +378,6 @@
overflow:hidden;
padding:0px;
margin:0px;
- white-space:pre;
}
caption a:link, caption a:hover, caption a:active, caption a:visited {
color:#FFFFFF;
@@ -381,35 +386,32 @@
white-space:nowrap;
padding-top:8px;
padding-left:8px;
- display:block;
+ display:inline-block;
float:left;
background-image:url(resources/titlebar.gif);
- height:18px;
}
.contentContainer ul.blockList li.blockList caption span.activeTableTab span {
white-space:nowrap;
padding-top:8px;
padding-left:8px;
- display:block;
+ display:inline-block;
float:left;
background-image:url(resources/activetitlebar.gif);
- height:18px;
}
.contentContainer ul.blockList li.blockList caption span.tableTab span {
white-space:nowrap;
padding-top:8px;
padding-left:8px;
- display:block;
+ display:inline-block;
float:left;
background-image:url(resources/titlebar.gif);
- height:18px;
}
.contentContainer ul.blockList li.blockList caption span.tableTab, .contentContainer ul.blockList li.blockList caption span.activeTableTab {
padding-top:0px;
padding-left:0px;
background-image:none;
float:none;
- display:inline;
+ display:inline-block;
}
.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd {
width:10px;
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LegacyTaglet.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LegacyTaglet.java Fri Sep 20 19:15:59 2013 -0700
@@ -130,7 +130,13 @@
public Content getTagletOutput(Doc holder, TagletWriter writer)
throws IllegalArgumentException {
Content output = writer.getOutputInstance();
- output.addContent(new RawHtml(legacyTaglet.toString(holder.tags(getName()))));
+ Tag[] tags = holder.tags(getName());
+ if (tags.length > 0) {
+ String tagString = legacyTaglet.toString(tags);
+ if (tagString != null) {
+ output.addContent(new RawHtml(tagString));
+ }
+ }
return output;
}
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java Fri Sep 20 19:15:59 2013 -0700
@@ -34,6 +34,7 @@
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
+import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
@@ -221,8 +222,10 @@
/** If the file is a directory, list its contents. */
public Iterable<DocFile> list() throws IOException {
List<DocFile> files = new ArrayList<DocFile>();
- for (Path f: Files.newDirectoryStream(file)) {
- files.add(new StandardDocFile(f));
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(file)) {
+ for (Path f: ds) {
+ files.add(new StandardDocFile(f));
+ }
}
return files;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/Main.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/Main.java Fri Sep 20 19:15:59 2013 -0700
@@ -30,14 +30,6 @@
/**
* The programmatic interface for the Java Programming Language
* compiler, javac.
- *
- * <p>Except for the two methods
- * {@link #compile(java.lang.String[])}
- * {@link #compile(java.lang.String[],java.io.PrintWriter)},
- * nothing described in this source file is part of any supported
- * API. If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.
*/
@jdk.Supported
public class Main {
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java Fri Sep 20 17:11:32 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,451 +0,0 @@
-/*
- * 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 com.sun.tools.javac.code;
-
-import java.util.Map;
-
-import javax.tools.JavaFileObject;
-
-import com.sun.tools.javac.comp.Annotate;
-import com.sun.tools.javac.comp.AttrContext;
-import com.sun.tools.javac.comp.Env;
-import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.util.Assert;
-import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.Log;
-import com.sun.tools.javac.util.Pair;
-import static com.sun.tools.javac.code.Kinds.PCK;
-
-/**
- * Container for all annotations (attributes in javac) on a Symbol.
- *
- * This class is explicitly mutable. Its contents will change when attributes
- * are annotated onto the Symbol. However this class depends on the facts that
- * List (in javac) is immutable.
- *
- * An instance of this class can be in one of three states:
- *
- * NOT_STARTED indicates that the Symbol this instance belongs to has not been
- * annotated (yet). Specifically if the declaration is not annotated this
- * instance will never move past NOT_STARTED. You can never go back to
- * NOT_STARTED.
- *
- * IN_PROGRESS annotations have been found on the declaration. Will be processed
- * later. You can reset to IN_PROGRESS. While IN_PROGRESS you can set the list
- * of attributes (and this moves out of the IN_PROGRESS state).
- *
- * "unnamed" this Annotations contains some attributes, possibly the final set.
- * While in this state you can only prepend or append to the attributes not set
- * it directly. You can also move back to the IN_PROGRESS state using reset().
- *
- * <p><b>This is NOT part of any supported API. If you write code that depends
- * on this, you do so at your own risk. This code and its internal interfaces
- * are subject to change or deletion without notice.</b>
- */
-public class Annotations {
-
- private static final List<Attribute.Compound> DECL_NOT_STARTED = List.of(null);
- private static final List<Attribute.Compound> DECL_IN_PROGRESS = List.of(null);
-
- /*
- * This field should never be null
- */
- private List<Attribute.Compound> attributes = DECL_NOT_STARTED;
-
- /*
- * Type attributes for this symbol.
- * This field should never be null.
- */
- private List<Attribute.TypeCompound> type_attributes = List.<Attribute.TypeCompound>nil();
-
- /*
- * Type attributes of initializers in this class.
- * Unused if the current symbol is not a ClassSymbol.
- */
- private List<Attribute.TypeCompound> init_type_attributes = List.<Attribute.TypeCompound>nil();
-
- /*
- * Type attributes of class initializers in this class.
- * Unused if the current symbol is not a ClassSymbol.
- */
- private List<Attribute.TypeCompound> clinit_type_attributes = List.<Attribute.TypeCompound>nil();
-
- /*
- * The Symbol this Annotations instance belongs to
- */
- private final Symbol sym;
-
- public Annotations(Symbol sym) {
- this.sym = sym;
- }
-
- public List<Attribute.Compound> getDeclarationAttributes() {
- return filterDeclSentinels(attributes);
- }
-
- public List<Attribute.TypeCompound> getTypeAttributes() {
- return type_attributes;
- }
-
- public List<Attribute.TypeCompound> getInitTypeAttributes() {
- return init_type_attributes;
- }
-
- public List<Attribute.TypeCompound> getClassInitTypeAttributes() {
- return clinit_type_attributes;
- }
-
- public void setDeclarationAttributes(List<Attribute.Compound> a) {
- Assert.check(pendingCompletion() || !isStarted());
- if (a == null) {
- throw new NullPointerException();
- }
- attributes = a;
- }
-
- public void setTypeAttributes(List<Attribute.TypeCompound> a) {
- if (a == null) {
- throw new NullPointerException();
- }
- type_attributes = a;
- }
-
- public void setInitTypeAttributes(List<Attribute.TypeCompound> a) {
- if (a == null) {
- throw new NullPointerException();
- }
- init_type_attributes = a;
- }
-
- public void setClassInitTypeAttributes(List<Attribute.TypeCompound> a) {
- if (a == null) {
- throw new NullPointerException();
- }
- clinit_type_attributes = a;
- }
-
- public void setAttributes(Annotations other) {
- if (other == null) {
- throw new NullPointerException();
- }
- setDeclarationAttributes(other.getDeclarationAttributes());
- setTypeAttributes(other.getTypeAttributes());
- setInitTypeAttributes(other.getInitTypeAttributes());
- setClassInitTypeAttributes(other.getClassInitTypeAttributes());
- }
-
- public void setDeclarationAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.Compound> ctx) {
- Assert.check(pendingCompletion() || (!isStarted() && sym.kind == PCK));
- this.setDeclarationAttributes(getAttributesForCompletion(ctx));
- }
-
- public void appendTypeAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.TypeCompound> ctx) {
- this.appendUniqueTypes(getAttributesForCompletion(ctx));
- }
-
- private <T extends Attribute.Compound> List<T> getAttributesForCompletion(
- final Annotate.AnnotateRepeatedContext<T> ctx) {
-
- Map<Symbol.TypeSymbol, ListBuffer<T>> annotated = ctx.annotated;
- boolean atLeastOneRepeated = false;
- List<T> buf = List.<T>nil();
- for (ListBuffer<T> lb : annotated.values()) {
- if (lb.size() == 1) {
- buf = buf.prepend(lb.first());
- } else { // repeated
- // This will break when other subtypes of Attributs.Compound
- // are introduced, because PlaceHolder is a subtype of TypeCompound.
- T res;
- @SuppressWarnings("unchecked")
- T ph = (T) new Placeholder<T>(ctx, lb.toList(), sym);
- res = ph;
- buf = buf.prepend(res);
- atLeastOneRepeated = true;
- }
- }
-
- if (atLeastOneRepeated) {
- // The Symbol s is now annotated with a combination of
- // finished non-repeating annotations and placeholders for
- // repeating annotations.
- //
- // We need to do this in two passes because when creating
- // a container for a repeating annotation we must
- // guarantee that the @Repeatable on the
- // contained annotation is fully annotated
- //
- // The way we force this order is to do all repeating
- // annotations in a pass after all non-repeating are
- // finished. This will work because @Repeatable
- // is non-repeating and therefore will be annotated in the
- // fist pass.
-
- // Queue a pass that will replace Attribute.Placeholders
- // with Attribute.Compound (made from synthesized containers).
- ctx.annotateRepeated(new Annotate.Annotator() {
- @Override
- public String toString() {
- return "repeated annotation pass of: " + sym + " in: " + sym.owner;
- }
-
- @Override
- public void enterAnnotation() {
- complete(ctx);
- }
- });
- }
- // Add non-repeating attributes
- return buf.reverse();
- }
-
- public Annotations reset() {
- attributes = DECL_IN_PROGRESS;
- return this;
- }
-
- public boolean isEmpty() {
- return !isStarted()
- || pendingCompletion()
- || attributes.isEmpty();
- }
-
- public boolean isTypesEmpty() {
- return type_attributes.isEmpty();
- }
-
- public boolean pendingCompletion() {
- return attributes == DECL_IN_PROGRESS;
- }
-
- public Annotations append(List<Attribute.Compound> l) {
- attributes = filterDeclSentinels(attributes);
-
- if (l.isEmpty()) {
- ; // no-op
- } else if (attributes.isEmpty()) {
- attributes = l;
- } else {
- attributes = attributes.appendList(l);
- }
- return this;
- }
-
- public Annotations appendUniqueTypes(List<Attribute.TypeCompound> l) {
- if (l.isEmpty()) {
- ; // no-op
- } else if (type_attributes.isEmpty()) {
- type_attributes = l;
- } else {
- // TODO: in case we expect a large number of annotations, this
- // might be inefficient.
- for (Attribute.TypeCompound tc : l) {
- if (!type_attributes.contains(tc))
- type_attributes = type_attributes.append(tc);
- }
- }
- return this;
- }
-
- public Annotations appendInitTypeAttributes(List<Attribute.TypeCompound> l) {
- if (l.isEmpty()) {
- ; // no-op
- } else if (init_type_attributes.isEmpty()) {
- init_type_attributes = l;
- } else {
- init_type_attributes = init_type_attributes.appendList(l);
- }
- return this;
- }
-
- public Annotations appendClassInitTypeAttributes(List<Attribute.TypeCompound> l) {
- if (l.isEmpty()) {
- ; // no-op
- } else if (clinit_type_attributes.isEmpty()) {
- clinit_type_attributes = l;
- } else {
- clinit_type_attributes = clinit_type_attributes.appendList(l);
- }
- return this;
- }
-
- public Annotations prepend(List<Attribute.Compound> l) {
- attributes = filterDeclSentinels(attributes);
-
- if (l.isEmpty()) {
- ; // no-op
- } else if (attributes.isEmpty()) {
- attributes = l;
- } else {
- attributes = attributes.prependList(l);
- }
- return this;
- }
-
- private List<Attribute.Compound> filterDeclSentinels(List<Attribute.Compound> a) {
- return (a == DECL_IN_PROGRESS || a == DECL_NOT_STARTED)
- ? List.<Attribute.Compound>nil()
- : a;
- }
-
- private boolean isStarted() {
- return attributes != DECL_NOT_STARTED;
- }
-
- private List<Attribute.Compound> getPlaceholders() {
- List<Attribute.Compound> res = List.<Attribute.Compound>nil();
- for (Attribute.Compound a : filterDeclSentinels(attributes)) {
- if (a instanceof Placeholder) {
- res = res.prepend(a);
- }
- }
- return res.reverse();
- }
-
- private List<Attribute.TypeCompound> getTypePlaceholders() {
- List<Attribute.TypeCompound> res = List.<Attribute.TypeCompound>nil();
- for (Attribute.TypeCompound a : type_attributes) {
- if (a instanceof Placeholder) {
- res = res.prepend(a);
- }
- }
- return res.reverse();
- }
-
- /*
- * Replace Placeholders for repeating annotations with their containers
- */
- private <T extends Attribute.Compound> void complete(Annotate.AnnotateRepeatedContext<T> ctx) {
- Log log = ctx.log;
- Env<AttrContext> env = ctx.env;
- JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
- try {
- // TODO: can we reduce duplication in the following branches?
- if (ctx.isTypeCompound) {
- Assert.check(!isTypesEmpty());
-
- if (isTypesEmpty()) {
- return;
- }
-
- List<Attribute.TypeCompound> result = List.nil();
- for (Attribute.TypeCompound a : getTypeAttributes()) {
- if (a instanceof Placeholder) {
- @SuppressWarnings("unchecked")
- Placeholder<Attribute.TypeCompound> ph = (Placeholder<Attribute.TypeCompound>) a;
- Attribute.TypeCompound replacement = replaceOne(ph, ph.getRepeatedContext());
-
- if (null != replacement) {
- result = result.prepend(replacement);
- }
- } else {
- result = result.prepend(a);
- }
- }
-
- type_attributes = result.reverse();
-
- Assert.check(Annotations.this.getTypePlaceholders().isEmpty());
- } else {
- Assert.check(!pendingCompletion());
-
- if (isEmpty()) {
- return;
- }
-
- List<Attribute.Compound> result = List.nil();
- for (Attribute.Compound a : getDeclarationAttributes()) {
- if (a instanceof Placeholder) {
- @SuppressWarnings("unchecked")
- Attribute.Compound replacement = replaceOne((Placeholder<T>) a, ctx);
-
- if (null != replacement) {
- result = result.prepend(replacement);
- }
- } else {
- result = result.prepend(a);
- }
- }
-
- attributes = result.reverse();
-
- Assert.check(Annotations.this.getPlaceholders().isEmpty());
- }
- } finally {
- log.useSource(oldSource);
- }
- }
-
- private <T extends Attribute.Compound> T replaceOne(Placeholder<T> placeholder, Annotate.AnnotateRepeatedContext<T> ctx) {
- Log log = ctx.log;
-
- // Process repeated annotations
- T validRepeated = ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor(), sym);
-
- if (validRepeated != null) {
- // Check that the container isn't manually
- // present along with repeated instances of
- // its contained annotation.
- ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym);
- if (manualContainer != null) {
- log.error(ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present",
- manualContainer.first().type.tsym);
- }
- }
-
- // A null return will delete the Placeholder
- return validRepeated;
- }
-
- private static class Placeholder<T extends Attribute.Compound> extends Attribute.TypeCompound {
-
- private final Annotate.AnnotateRepeatedContext<T> ctx;
- private final List<T> placeholderFor;
- private final Symbol on;
-
- public Placeholder(Annotate.AnnotateRepeatedContext<T> ctx, List<T> placeholderFor, Symbol on) {
- super(on.type, List.<Pair<Symbol.MethodSymbol, Attribute>>nil(),
- ctx.isTypeCompound ?
- ((Attribute.TypeCompound)placeholderFor.head).position :
- null);
- this.ctx = ctx;
- this.placeholderFor = placeholderFor;
- this.on = on;
- }
-
- @Override
- public String toString() {
- return "<placeholder: " + placeholderFor + " on: " + on + ">";
- }
-
- public List<T> getPlaceholderFor() {
- return placeholderFor;
- }
-
- public Annotate.AnnotateRepeatedContext<T> getRepeatedContext() {
- return ctx;
- }
- }
-}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -28,6 +28,8 @@
import java.util.HashMap;
import java.util.Map;
+import com.sun.tools.javac.tree.EndPosTable;
+import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
@@ -53,10 +55,13 @@
protected DeferredLintHandler(Context context) {
context.put(deferredLintHandlerKey, this);
+ this.currentPos = IMMEDIATE_POSITION;
}
- private DeferredLintHandler() {}
-
+ /**An interface for deferred lint reporting - loggers passed to
+ * {@link #report(LintLogger) } will be called when
+ * {@link #flush(DiagnosticPosition) } is invoked.
+ */
public interface LintLogger {
void report();
}
@@ -64,12 +69,26 @@
private DiagnosticPosition currentPos;
private Map<DiagnosticPosition, ListBuffer<LintLogger>> loggersQueue = new HashMap<DiagnosticPosition, ListBuffer<LintLogger>>();
+ /**Associate the given logger with the current position as set by {@link #setPos(DiagnosticPosition) }.
+ * Will be invoked when {@link #flush(DiagnosticPosition) } will be invoked with the same position.
+ * <br>
+ * Will invoke the logger synchronously if {@link #immediate() } was called
+ * instead of {@link #setPos(DiagnosticPosition) }.
+ */
public void report(LintLogger logger) {
- ListBuffer<LintLogger> loggers = loggersQueue.get(currentPos);
- Assert.checkNonNull(loggers);
- loggers.append(logger);
+ if (currentPos == IMMEDIATE_POSITION) {
+ logger.report();
+ } else {
+ ListBuffer<LintLogger> loggers = loggersQueue.get(currentPos);
+ if (loggers == null) {
+ loggersQueue.put(currentPos, loggers = ListBuffer.<LintLogger>lb());
+ }
+ loggers.append(logger);
+ }
}
+ /**Invoke all {@link LintLogger}s that were associated with the provided {@code pos}.
+ */
public void flush(DiagnosticPosition pos) {
ListBuffer<LintLogger> loggers = loggersQueue.get(pos);
if (loggers != null) {
@@ -80,16 +99,46 @@
}
}
- public DeferredLintHandler setPos(DiagnosticPosition currentPos) {
+ /**Sets the current position to the provided {@code currentPos}. {@link LintLogger}s
+ * passed to subsequent invocations of {@link #report(LintLogger) } will be associated
+ * with the given position.
+ */
+ public DiagnosticPosition setPos(DiagnosticPosition currentPos) {
+ DiagnosticPosition prevPosition = this.currentPos;
this.currentPos = currentPos;
- loggersQueue.put(currentPos, ListBuffer.<LintLogger>lb());
- return this;
+ return prevPosition;
+ }
+
+ /**{@link LintLogger}s passed to subsequent invocations of
+ * {@link #report(LintLogger) } will be invoked immediately.
+ */
+ public DiagnosticPosition immediate() {
+ return setPos(IMMEDIATE_POSITION);
}
- public static final DeferredLintHandler immediateHandler = new DeferredLintHandler() {
+ private static final DiagnosticPosition IMMEDIATE_POSITION = new DiagnosticPosition() {
+ @Override
+ public JCTree getTree() {
+ Assert.error();
+ return null;
+ }
+
@Override
- public void report(LintLogger logger) {
- logger.report();
+ public int getStartPosition() {
+ Assert.error();
+ return -1;
+ }
+
+ @Override
+ public int getPreferredPosition() {
+ Assert.error();
+ return -1;
+ }
+
+ @Override
+ public int getEndPosition(EndPosTable endPosTable) {
+ Assert.error();
+ return -1;
}
};
}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Fri Sep 20 19:15:59 2013 -0700
@@ -97,7 +97,6 @@
public static final int MANDATED = 1<<15;
public static final int StandardFlags = 0x0fff;
- public static final int ModifierFlags = StandardFlags & ~INTERFACE;
// Because the following access flags are overloaded with other
// bit positions, we translate them when reading and writing class
@@ -266,6 +265,11 @@
*/
public static final long THROWS = 1L<<47;
+ /**
+ * Flag that marks potentially ambiguous overloads
+ */
+ public static final long POTENTIALLY_AMBIGUOUS = 1L<<48;
+
/** Modifier masks.
*/
public static final int
@@ -282,7 +286,9 @@
SYNCHRONIZED | FINAL | STRICTFP;
public static final long
ExtendedStandardFlags = (long)StandardFlags | DEFAULT,
+ ModifierFlags = ((long)StandardFlags & ~INTERFACE) | DEFAULT,
InterfaceMethodMask = ABSTRACT | STATIC | PUBLIC | STRICTFP | DEFAULT,
+ AnnotationTypeElementMask = FINAL | ABSTRACT | PUBLIC | STRICTFP,
LocalVarFlags = FINAL | PARAMETER;
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Fri Sep 20 19:15:59 2013 -0700
@@ -33,9 +33,6 @@
import com.sun.tools.javac.util.Options;
import com.sun.tools.javac.util.Pair;
-import static com.sun.tools.javac.code.Flags.*;
-
-
/**
* A class for handling -Xlint suboptions and @SuppresssWarnings.
*
@@ -81,7 +78,6 @@
return l;
}
-
private final AugmentVisitor augmentor;
private final EnumSet<LintCategory> values;
@@ -90,7 +86,6 @@
private static final Map<String, LintCategory> map =
new java.util.concurrent.ConcurrentHashMap<String, LintCategory>(20);
-
protected Lint(Context context) {
// initialize values according to the lint options
Options options = Options.instance(context);
@@ -175,6 +170,11 @@
OPTIONS("options"),
/**
+ * Warn about issues regarding method overloads.
+ */
+ OVERLOADS("overloads"),
+
+ /**
* Warn about issues regarding method overrides.
*/
OVERRIDES("overrides"),
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri Sep 20 19:15:59 2013 -0700
@@ -46,6 +46,7 @@
import static com.sun.tools.javac.code.TypeTag.CLASS;
import static com.sun.tools.javac.code.TypeTag.FORALL;
import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
/** Root class for Java symbols. It contains subclasses
* for specific sorts of symbols, such as variables, methods and operators,
@@ -98,9 +99,9 @@
// <editor-fold defaultstate="collapsed" desc="annotations">
/** The attributes of this symbol are contained in this
- * Annotations. The Annotations instance is NOT immutable.
+ * SymbolMetadata. The SymbolMetadata instance is NOT immutable.
*/
- protected Annotations annotations;
+ protected SymbolMetadata annotations;
/** An accessor method for the attributes of this symbol.
* Attributes of class symbols should be accessed through the accessor
@@ -217,19 +218,19 @@
public void setTypeAttributes(List<Attribute.TypeCompound> a) {
if (annotations != null || a.nonEmpty()) {
if (annotations == null)
- annotations = new Annotations(this);
+ annotations = new SymbolMetadata(this);
annotations.setTypeAttributes(a);
}
}
- private Annotations initedAnnos() {
+ private SymbolMetadata initedAnnos() {
if (annotations == null)
- annotations = new Annotations(this);
+ annotations = new SymbolMetadata(this);
return annotations;
}
/** This method is intended for debugging only. */
- public Annotations getAnnotations() {
+ public SymbolMetadata getAnnotations() {
return annotations;
}
@@ -852,7 +853,7 @@
private void mergeAttributes() {
if (annotations == null &&
package_info.annotations != null) {
- annotations = new Annotations(this);
+ annotations = new SymbolMetadata(this);
annotations.setAttributes(package_info.annotations);
}
}
@@ -1167,11 +1168,11 @@
public void setLazyConstValue(final Env<AttrContext> env,
final Attr attr,
- final JCTree.JCExpression initializer)
+ final JCVariableDecl variable)
{
setData(new Callable<Object>() {
public Object call() {
- return attr.attribLazyConstantValue(env, initializer, type);
+ return attr.attribLazyConstantValue(env, variable, type);
}
});
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/SymbolMetadata.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,451 @@
+/*
+ * 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 com.sun.tools.javac.code;
+
+import java.util.Map;
+
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.comp.Annotate;
+import com.sun.tools.javac.comp.AttrContext;
+import com.sun.tools.javac.comp.Env;
+import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.Assert;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Pair;
+import static com.sun.tools.javac.code.Kinds.PCK;
+
+/**
+ * Container for all annotations (attributes in javac) on a Symbol.
+ *
+ * This class is explicitly mutable. Its contents will change when attributes
+ * are annotated onto the Symbol. However this class depends on the facts that
+ * List (in javac) is immutable.
+ *
+ * An instance of this class can be in one of three states:
+ *
+ * NOT_STARTED indicates that the Symbol this instance belongs to has not been
+ * annotated (yet). Specifically if the declaration is not annotated this
+ * instance will never move past NOT_STARTED. You can never go back to
+ * NOT_STARTED.
+ *
+ * IN_PROGRESS annotations have been found on the declaration. Will be processed
+ * later. You can reset to IN_PROGRESS. While IN_PROGRESS you can set the list
+ * of attributes (and this moves out of the IN_PROGRESS state).
+ *
+ * "unnamed" this SymbolMetadata contains some attributes, possibly the final set.
+ * While in this state you can only prepend or append to the attributes not set
+ * it directly. You can also move back to the IN_PROGRESS state using reset().
+ *
+ * <p><b>This is NOT part of any supported API. If you write code that depends
+ * on this, you do so at your own risk. This code and its internal interfaces
+ * are subject to change or deletion without notice.</b>
+ */
+public class SymbolMetadata {
+
+ private static final List<Attribute.Compound> DECL_NOT_STARTED = List.of(null);
+ private static final List<Attribute.Compound> DECL_IN_PROGRESS = List.of(null);
+
+ /*
+ * This field should never be null
+ */
+ private List<Attribute.Compound> attributes = DECL_NOT_STARTED;
+
+ /*
+ * Type attributes for this symbol.
+ * This field should never be null.
+ */
+ private List<Attribute.TypeCompound> type_attributes = List.<Attribute.TypeCompound>nil();
+
+ /*
+ * Type attributes of initializers in this class.
+ * Unused if the current symbol is not a ClassSymbol.
+ */
+ private List<Attribute.TypeCompound> init_type_attributes = List.<Attribute.TypeCompound>nil();
+
+ /*
+ * Type attributes of class initializers in this class.
+ * Unused if the current symbol is not a ClassSymbol.
+ */
+ private List<Attribute.TypeCompound> clinit_type_attributes = List.<Attribute.TypeCompound>nil();
+
+ /*
+ * The Symbol this SymbolMetadata instance belongs to
+ */
+ private final Symbol sym;
+
+ public SymbolMetadata(Symbol sym) {
+ this.sym = sym;
+ }
+
+ public List<Attribute.Compound> getDeclarationAttributes() {
+ return filterDeclSentinels(attributes);
+ }
+
+ public List<Attribute.TypeCompound> getTypeAttributes() {
+ return type_attributes;
+ }
+
+ public List<Attribute.TypeCompound> getInitTypeAttributes() {
+ return init_type_attributes;
+ }
+
+ public List<Attribute.TypeCompound> getClassInitTypeAttributes() {
+ return clinit_type_attributes;
+ }
+
+ public void setDeclarationAttributes(List<Attribute.Compound> a) {
+ Assert.check(pendingCompletion() || !isStarted());
+ if (a == null) {
+ throw new NullPointerException();
+ }
+ attributes = a;
+ }
+
+ public void setTypeAttributes(List<Attribute.TypeCompound> a) {
+ if (a == null) {
+ throw new NullPointerException();
+ }
+ type_attributes = a;
+ }
+
+ public void setInitTypeAttributes(List<Attribute.TypeCompound> a) {
+ if (a == null) {
+ throw new NullPointerException();
+ }
+ init_type_attributes = a;
+ }
+
+ public void setClassInitTypeAttributes(List<Attribute.TypeCompound> a) {
+ if (a == null) {
+ throw new NullPointerException();
+ }
+ clinit_type_attributes = a;
+ }
+
+ public void setAttributes(SymbolMetadata other) {
+ if (other == null) {
+ throw new NullPointerException();
+ }
+ setDeclarationAttributes(other.getDeclarationAttributes());
+ setTypeAttributes(other.getTypeAttributes());
+ setInitTypeAttributes(other.getInitTypeAttributes());
+ setClassInitTypeAttributes(other.getClassInitTypeAttributes());
+ }
+
+ public void setDeclarationAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.Compound> ctx) {
+ Assert.check(pendingCompletion() || (!isStarted() && sym.kind == PCK));
+ this.setDeclarationAttributes(getAttributesForCompletion(ctx));
+ }
+
+ public void appendTypeAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.TypeCompound> ctx) {
+ this.appendUniqueTypes(getAttributesForCompletion(ctx));
+ }
+
+ private <T extends Attribute.Compound> List<T> getAttributesForCompletion(
+ final Annotate.AnnotateRepeatedContext<T> ctx) {
+
+ Map<Symbol.TypeSymbol, ListBuffer<T>> annotated = ctx.annotated;
+ boolean atLeastOneRepeated = false;
+ List<T> buf = List.<T>nil();
+ for (ListBuffer<T> lb : annotated.values()) {
+ if (lb.size() == 1) {
+ buf = buf.prepend(lb.first());
+ } else { // repeated
+ // This will break when other subtypes of Attributs.Compound
+ // are introduced, because PlaceHolder is a subtype of TypeCompound.
+ T res;
+ @SuppressWarnings("unchecked")
+ T ph = (T) new Placeholder<T>(ctx, lb.toList(), sym);
+ res = ph;
+ buf = buf.prepend(res);
+ atLeastOneRepeated = true;
+ }
+ }
+
+ if (atLeastOneRepeated) {
+ // The Symbol s is now annotated with a combination of
+ // finished non-repeating annotations and placeholders for
+ // repeating annotations.
+ //
+ // We need to do this in two passes because when creating
+ // a container for a repeating annotation we must
+ // guarantee that the @Repeatable on the
+ // contained annotation is fully annotated
+ //
+ // The way we force this order is to do all repeating
+ // annotations in a pass after all non-repeating are
+ // finished. This will work because @Repeatable
+ // is non-repeating and therefore will be annotated in the
+ // fist pass.
+
+ // Queue a pass that will replace Attribute.Placeholders
+ // with Attribute.Compound (made from synthesized containers).
+ ctx.annotateRepeated(new Annotate.Annotator() {
+ @Override
+ public String toString() {
+ return "repeated annotation pass of: " + sym + " in: " + sym.owner;
+ }
+
+ @Override
+ public void enterAnnotation() {
+ complete(ctx);
+ }
+ });
+ }
+ // Add non-repeating attributes
+ return buf.reverse();
+ }
+
+ public SymbolMetadata reset() {
+ attributes = DECL_IN_PROGRESS;
+ return this;
+ }
+
+ public boolean isEmpty() {
+ return !isStarted()
+ || pendingCompletion()
+ || attributes.isEmpty();
+ }
+
+ public boolean isTypesEmpty() {
+ return type_attributes.isEmpty();
+ }
+
+ public boolean pendingCompletion() {
+ return attributes == DECL_IN_PROGRESS;
+ }
+
+ public SymbolMetadata append(List<Attribute.Compound> l) {
+ attributes = filterDeclSentinels(attributes);
+
+ if (l.isEmpty()) {
+ ; // no-op
+ } else if (attributes.isEmpty()) {
+ attributes = l;
+ } else {
+ attributes = attributes.appendList(l);
+ }
+ return this;
+ }
+
+ public SymbolMetadata appendUniqueTypes(List<Attribute.TypeCompound> l) {
+ if (l.isEmpty()) {
+ ; // no-op
+ } else if (type_attributes.isEmpty()) {
+ type_attributes = l;
+ } else {
+ // TODO: in case we expect a large number of annotations, this
+ // might be inefficient.
+ for (Attribute.TypeCompound tc : l) {
+ if (!type_attributes.contains(tc))
+ type_attributes = type_attributes.append(tc);
+ }
+ }
+ return this;
+ }
+
+ public SymbolMetadata appendInitTypeAttributes(List<Attribute.TypeCompound> l) {
+ if (l.isEmpty()) {
+ ; // no-op
+ } else if (init_type_attributes.isEmpty()) {
+ init_type_attributes = l;
+ } else {
+ init_type_attributes = init_type_attributes.appendList(l);
+ }
+ return this;
+ }
+
+ public SymbolMetadata appendClassInitTypeAttributes(List<Attribute.TypeCompound> l) {
+ if (l.isEmpty()) {
+ ; // no-op
+ } else if (clinit_type_attributes.isEmpty()) {
+ clinit_type_attributes = l;
+ } else {
+ clinit_type_attributes = clinit_type_attributes.appendList(l);
+ }
+ return this;
+ }
+
+ public SymbolMetadata prepend(List<Attribute.Compound> l) {
+ attributes = filterDeclSentinels(attributes);
+
+ if (l.isEmpty()) {
+ ; // no-op
+ } else if (attributes.isEmpty()) {
+ attributes = l;
+ } else {
+ attributes = attributes.prependList(l);
+ }
+ return this;
+ }
+
+ private List<Attribute.Compound> filterDeclSentinels(List<Attribute.Compound> a) {
+ return (a == DECL_IN_PROGRESS || a == DECL_NOT_STARTED)
+ ? List.<Attribute.Compound>nil()
+ : a;
+ }
+
+ private boolean isStarted() {
+ return attributes != DECL_NOT_STARTED;
+ }
+
+ private List<Attribute.Compound> getPlaceholders() {
+ List<Attribute.Compound> res = List.<Attribute.Compound>nil();
+ for (Attribute.Compound a : filterDeclSentinels(attributes)) {
+ if (a instanceof Placeholder) {
+ res = res.prepend(a);
+ }
+ }
+ return res.reverse();
+ }
+
+ private List<Attribute.TypeCompound> getTypePlaceholders() {
+ List<Attribute.TypeCompound> res = List.<Attribute.TypeCompound>nil();
+ for (Attribute.TypeCompound a : type_attributes) {
+ if (a instanceof Placeholder) {
+ res = res.prepend(a);
+ }
+ }
+ return res.reverse();
+ }
+
+ /*
+ * Replace Placeholders for repeating annotations with their containers
+ */
+ private <T extends Attribute.Compound> void complete(Annotate.AnnotateRepeatedContext<T> ctx) {
+ Log log = ctx.log;
+ Env<AttrContext> env = ctx.env;
+ JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
+ try {
+ // TODO: can we reduce duplication in the following branches?
+ if (ctx.isTypeCompound) {
+ Assert.check(!isTypesEmpty());
+
+ if (isTypesEmpty()) {
+ return;
+ }
+
+ List<Attribute.TypeCompound> result = List.nil();
+ for (Attribute.TypeCompound a : getTypeAttributes()) {
+ if (a instanceof Placeholder) {
+ @SuppressWarnings("unchecked")
+ Placeholder<Attribute.TypeCompound> ph = (Placeholder<Attribute.TypeCompound>) a;
+ Attribute.TypeCompound replacement = replaceOne(ph, ph.getRepeatedContext());
+
+ if (null != replacement) {
+ result = result.prepend(replacement);
+ }
+ } else {
+ result = result.prepend(a);
+ }
+ }
+
+ type_attributes = result.reverse();
+
+ Assert.check(SymbolMetadata.this.getTypePlaceholders().isEmpty());
+ } else {
+ Assert.check(!pendingCompletion());
+
+ if (isEmpty()) {
+ return;
+ }
+
+ List<Attribute.Compound> result = List.nil();
+ for (Attribute.Compound a : getDeclarationAttributes()) {
+ if (a instanceof Placeholder) {
+ @SuppressWarnings("unchecked")
+ Attribute.Compound replacement = replaceOne((Placeholder<T>) a, ctx);
+
+ if (null != replacement) {
+ result = result.prepend(replacement);
+ }
+ } else {
+ result = result.prepend(a);
+ }
+ }
+
+ attributes = result.reverse();
+
+ Assert.check(SymbolMetadata.this.getPlaceholders().isEmpty());
+ }
+ } finally {
+ log.useSource(oldSource);
+ }
+ }
+
+ private <T extends Attribute.Compound> T replaceOne(Placeholder<T> placeholder, Annotate.AnnotateRepeatedContext<T> ctx) {
+ Log log = ctx.log;
+
+ // Process repeated annotations
+ T validRepeated = ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor(), sym);
+
+ if (validRepeated != null) {
+ // Check that the container isn't manually
+ // present along with repeated instances of
+ // its contained annotation.
+ ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym);
+ if (manualContainer != null) {
+ log.error(ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present",
+ manualContainer.first().type.tsym);
+ }
+ }
+
+ // A null return will delete the Placeholder
+ return validRepeated;
+ }
+
+ private static class Placeholder<T extends Attribute.Compound> extends Attribute.TypeCompound {
+
+ private final Annotate.AnnotateRepeatedContext<T> ctx;
+ private final List<T> placeholderFor;
+ private final Symbol on;
+
+ public Placeholder(Annotate.AnnotateRepeatedContext<T> ctx, List<T> placeholderFor, Symbol on) {
+ super(on.type, List.<Pair<Symbol.MethodSymbol, Attribute>>nil(),
+ ctx.isTypeCompound ?
+ ((Attribute.TypeCompound)placeholderFor.head).position :
+ null);
+ this.ctx = ctx;
+ this.placeholderFor = placeholderFor;
+ this.on = on;
+ }
+
+ @Override
+ public String toString() {
+ return "<placeholder: " + placeholderFor + " on: " + on + ">";
+ }
+
+ public List<T> getPlaceholderFor() {
+ return placeholderFor;
+ }
+
+ public Annotate.AnnotateRepeatedContext<T> getRepeatedContext() {
+ return ctx;
+ }
+ }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Fri Sep 20 19:15:59 2013 -0700
@@ -3055,7 +3055,7 @@
/**
* Does t have the same bounds for quantified variables as s?
*/
- boolean hasSameBounds(ForAll t, ForAll s) {
+ public boolean hasSameBounds(ForAll t, ForAll s) {
List<Type> l1 = t.tvars;
List<Type> l2 = s.tvars;
while (l1.nonEmpty() && l2.nonEmpty() &&
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Sep 20 19:15:59 2013 -0700
@@ -748,19 +748,11 @@
* @see VarSymbol#setLazyConstValue
*/
public Object attribLazyConstantValue(Env<AttrContext> env,
- JCTree.JCExpression initializer,
+ JCVariableDecl variable,
Type type) {
- /* When this env was created, it didn't have the correct lint nor had
- * annotations has been processed.
- * But now at this phase we have already processed annotations and the
- * correct lint must have been set in chk, so we should use that one to
- * attribute the initializer.
- */
- Lint prevLint = env.info.lint;
- env.info.lint = chk.getLint();
-
- JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
+ DiagnosticPosition prevLintPos
+ = deferredLintHandler.setPos(variable.pos());
try {
// Use null as symbol to not attach the type annotation to any symbol.
@@ -768,17 +760,16 @@
// to the symbol.
// This prevents having multiple type annotations, just because of
// lazy constant value evaluation.
- memberEnter.typeAnnotate(initializer, env, null);
+ memberEnter.typeAnnotate(variable.init, env, null, variable.pos());
annotate.flush();
- Type itype = attribExpr(initializer, env, type);
+ Type itype = attribExpr(variable.init, env, type);
if (itype.constValue() != null) {
return coerce(itype, type).constValue();
} else {
return null;
}
} finally {
- env.info.lint = prevLint;
- log.useSource(prevSource);
+ deferredLintHandler.setPos(prevLintPos);
}
}
@@ -1012,7 +1003,7 @@
}
// Attribute all type annotations in the body
- memberEnter.typeAnnotate(tree.body, localEnv, m);
+ memberEnter.typeAnnotate(tree.body, localEnv, m, null);
annotate.flush();
// Attribute method body.
@@ -1042,7 +1033,7 @@
} else {
if (tree.init != null) {
// Field initializer expression need to be entered.
- memberEnter.typeAnnotate(tree.init, env, tree.sym);
+ memberEnter.typeAnnotate(tree.init, env, tree.sym, tree.pos());
annotate.flush();
}
}
@@ -1056,18 +1047,16 @@
((JCLambda)env.tree).paramKind == JCLambda.ParameterKind.IMPLICIT &&
(tree.sym.flags() & PARAMETER) != 0;
chk.validate(tree.vartype, env, !isImplicitLambdaParameter);
- deferredLintHandler.flush(tree.pos());
try {
+ v.getConstValue(); // ensure compile-time constant initializer is evaluated
+ deferredLintHandler.flush(tree.pos());
chk.checkDeprecatedAnnotation(tree.pos(), v);
if (tree.init != null) {
- if ((v.flags_field & FINAL) != 0 &&
- memberEnter.needsLazyConstValue(tree.init)) {
- // In this case, `v' is final. Ensure that it's initializer is
- // evaluated.
- v.getConstValue(); // ensure initializer is evaluated
- } else {
+ if ((v.flags_field & FINAL) == 0 ||
+ !memberEnter.needsLazyConstValue(tree.init)) {
+ // Not a compile-time constant
// Attribute initializer in a new environment
// with the declared variable as owner.
// Check that initializer conforms to variable's declared type.
@@ -1106,7 +1095,7 @@
if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
// Attribute all type annotations in the block
- memberEnter.typeAnnotate(tree, localEnv, localEnv.info.scope.owner);
+ memberEnter.typeAnnotate(tree, localEnv, localEnv.info.scope.owner, null);
annotate.flush();
{
@@ -2319,30 +2308,37 @@
boolean needsRecovery =
resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK;
try {
- Type target = pt();
+ Type currentTarget = pt();
List<Type> explicitParamTypes = null;
if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
//attribute lambda parameters
attribStats(that.params, localEnv);
explicitParamTypes = TreeInfo.types(that.params);
- target = infer.instantiateFunctionalInterface(that, target, explicitParamTypes, resultInfo.checkContext);
}
Type lambdaType;
if (pt() != Type.recoveryType) {
- target = targetChecker.visit(target, that);
- lambdaType = types.findDescriptorType(target);
+ /* We need to adjust the target. If the target is an
+ * intersection type, for example: SAM & I1 & I2 ...
+ * the target will be updated to SAM
+ */
+ currentTarget = targetChecker.visit(currentTarget, that);
+ if (explicitParamTypes != null) {
+ currentTarget = infer.instantiateFunctionalInterface(that,
+ currentTarget, explicitParamTypes, resultInfo.checkContext);
+ }
+ lambdaType = types.findDescriptorType(currentTarget);
} else {
- target = Type.recoveryType;
+ currentTarget = Type.recoveryType;
lambdaType = fallbackDescriptorType(that);
}
- setFunctionalInfo(localEnv, that, pt(), lambdaType, target, resultInfo.checkContext);
+ setFunctionalInfo(localEnv, that, pt(), lambdaType, currentTarget, resultInfo.checkContext);
if (lambdaType.hasTag(FORALL)) {
//lambda expression target desc cannot be a generic method
resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target",
- lambdaType, kindName(target.tsym), target.tsym));
+ lambdaType, kindName(currentTarget.tsym), currentTarget.tsym));
result = that.type = types.createErrorType(pt());
return;
}
@@ -2376,7 +2372,7 @@
if (arityMismatch) {
resultInfo.checkContext.report(that, diags.fragment("incompatible.arg.types.in.lambda"));
- result = that.type = types.createErrorType(target);
+ result = that.type = types.createErrorType(currentTarget);
return;
}
}
@@ -2396,38 +2392,14 @@
new ResultInfo(VAL, lambdaType.getReturnType(), funcContext);
localEnv.info.returnResult = bodyResultInfo;
- Log.DeferredDiagnosticHandler lambdaDeferredHandler = new Log.DeferredDiagnosticHandler(log);
- try {
- if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
- attribTree(that.getBody(), localEnv, bodyResultInfo);
- } else {
- JCBlock body = (JCBlock)that.body;
- attribStats(body.stats, localEnv);
- }
-
- if (resultInfo.checkContext.deferredAttrContext().mode == AttrMode.SPECULATIVE) {
- //check for errors in lambda body
- for (JCDiagnostic deferredDiag : lambdaDeferredHandler.getDiagnostics()) {
- if (deferredDiag.getKind() == JCDiagnostic.Kind.ERROR) {
- resultInfo.checkContext
- .report(that, diags.fragment("bad.arg.types.in.lambda", TreeInfo.types(that.params),
- deferredDiag)); //hidden diag parameter
- //we mark the lambda as erroneous - this is crucial in the recovery step
- //as parameter-dependent type error won't be reported in that stage,
- //meaning that a lambda will be deemed erroeneous only if there is
- //a target-independent error (which will cause method diagnostic
- //to be skipped).
- result = that.type = types.createErrorType(target);
- return;
- }
- }
- }
- } finally {
- lambdaDeferredHandler.reportDeferredDiagnostics();
- log.popDiagnosticHandler(lambdaDeferredHandler);
+ if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
+ attribTree(that.getBody(), localEnv, bodyResultInfo);
+ } else {
+ JCBlock body = (JCBlock)that.body;
+ attribStats(body.stats, localEnv);
}
- result = check(that, target, VAL, resultInfo);
+ result = check(that, currentTarget, VAL, resultInfo);
boolean isSpeculativeRound =
resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
@@ -2435,12 +2407,20 @@
preFlow(that);
flow.analyzeLambda(env, that, make, isSpeculativeRound);
- checkLambdaCompatible(that, lambdaType, resultInfo.checkContext, isSpeculativeRound);
+ checkLambdaCompatible(that, lambdaType, resultInfo.checkContext);
if (!isSpeculativeRound) {
- checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType, target);
+ //add thrown types as bounds to the thrown types free variables if needed:
+ if (resultInfo.checkContext.inferenceContext().free(lambdaType.getThrownTypes())) {
+ List<Type> inferredThrownTypes = flow.analyzeLambdaThrownTypes(env, that, make);
+ List<Type> thrownTypes = resultInfo.checkContext.inferenceContext().asFree(lambdaType.getThrownTypes());
+
+ chk.unhandled(inferredThrownTypes, thrownTypes);
+ }
+
+ checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType, currentTarget);
}
- result = check(that, target, VAL, resultInfo);
+ result = check(that, currentTarget, VAL, resultInfo);
} catch (Types.FunctionDescriptorLookupError ex) {
JCDiagnostic cause = ex.getDiagnostic();
resultInfo.checkContext.report(that, cause);
@@ -2604,10 +2584,9 @@
* Lambda compatibility. Check that given return types, thrown types, parameter types
* are compatible with the expected functional interface descriptor. This means that:
* (i) parameter types must be identical to those of the target descriptor; (ii) return
- * types must be compatible with the return type of the expected descriptor;
- * (iii) finish inference of thrown types if required.
+ * types must be compatible with the return type of the expected descriptor.
*/
- private void checkLambdaCompatible(JCLambda tree, Type descriptor, CheckContext checkContext, boolean speculativeAttr) {
+ private void checkLambdaCompatible(JCLambda tree, Type descriptor, CheckContext checkContext) {
Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType());
//return values have already been checked - but if lambda has no return
@@ -2624,11 +2603,6 @@
if (!types.isSameTypes(argTypes, TreeInfo.types(tree.params))) {
checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda"));
}
-
- if (!speculativeAttr) {
- List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes());
- chk.unhandled(tree.inferredThrownTypes == null ? List.<Type>nil() : tree.inferredThrownTypes, thrownTypes);
- }
}
private Env<AttrContext> lambdaEnv(JCLambda that, Env<AttrContext> env) {
@@ -2664,6 +2638,13 @@
if (that.getMode() == JCMemberReference.ReferenceMode.NEW) {
exprType = chk.checkConstructorRefType(that.expr, exprType);
+ if (!exprType.isErroneous() &&
+ exprType.isRaw() &&
+ that.typeargs != null) {
+ log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()),
+ diags.fragment("mref.infer.and.explicit.params"));
+ exprType = types.createErrorType(exprType);
+ }
}
if (exprType.isErroneous()) {
@@ -3731,7 +3712,7 @@
* Check that method arguments conform to its instantiation.
**/
public Type checkMethod(Type site,
- Symbol sym,
+ final Symbol sym,
ResultInfo resultInfo,
Env<AttrContext> env,
final List<JCExpression> argtrees,
@@ -3820,8 +3801,19 @@
resultInfo.checkContext.report(env.tree.pos(), ex.getDiagnostic());
return types.createErrorType(site);
} catch (Resolve.InapplicableMethodException ex) {
- Assert.error(ex.getDiagnostic().getMessage(Locale.getDefault()));
- return null;
+ final JCDiagnostic diag = ex.getDiagnostic();
+ Resolve.InapplicableSymbolError errSym = rs.new InapplicableSymbolError(null) {
+ @Override
+ protected Pair<Symbol, JCDiagnostic> errCandidate() {
+ return new Pair<Symbol, JCDiagnostic>(sym, diag);
+ }
+ };
+ List<Type> argtypes2 = Type.map(argtypes,
+ rs.new ResolveDeferredRecoveryMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase));
+ JCDiagnostic errDiag = errSym.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
+ env.tree, sym, site, sym.name, argtypes2, typeargtypes);
+ log.report(errDiag);
+ return types.createErrorType(site);
}
}
@@ -4206,6 +4198,7 @@
ResultInfo prevReturnRes = env.info.returnResult;
try {
+ deferredLintHandler.flush(env.tree);
env.info.returnResult = null;
// java.lang.Enum may not be subclassed by a non-enum
if (st.tsym == syms.enumSym &&
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Sep 20 19:15:59 2013 -0700
@@ -148,7 +148,7 @@
sunApiHandler = new MandatoryWarningHandler(log, verboseSunApi,
enforceMandatoryWarnings, "sunapi", null);
- deferredLintHandler = DeferredLintHandler.immediateHandler;
+ deferredLintHandler = DeferredLintHandler.instance(context);
}
/** Switch: generics enabled?
@@ -218,20 +218,6 @@
return prev;
}
- /* This idiom should be used only in cases when it is needed to set the lint
- * of an environment that has been created in a phase previous to annotations
- * processing.
- */
- Lint getLint() {
- return lint;
- }
-
- DeferredLintHandler setDeferredLintHandler(DeferredLintHandler newDeferredLintHandler) {
- DeferredLintHandler prev = deferredLintHandler;
- deferredLintHandler = newDeferredLintHandler;
- return prev;
- }
-
MethodSymbol setMethod(MethodSymbol newMethod) {
MethodSymbol prev = method;
method = newMethod;
@@ -582,14 +568,19 @@
/** Check for redundant casts (i.e. where source type is a subtype of target type)
* The problem should only be reported for non-292 cast
*/
- public void checkRedundantCast(Env<AttrContext> env, JCTypeCast tree) {
- if (!tree.type.isErroneous() &&
- (env.info.lint == null || env.info.lint.isEnabled(Lint.LintCategory.CAST))
+ public void checkRedundantCast(Env<AttrContext> env, final JCTypeCast tree) {
+ if (!tree.type.isErroneous()
&& types.isSameType(tree.expr.type, tree.clazz.type)
&& !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz))
&& !is292targetTypeCast(tree)) {
- log.warning(Lint.LintCategory.CAST,
- tree.pos(), "redundant.cast", tree.expr.type);
+ deferredLintHandler.report(new DeferredLintHandler.LintLogger() {
+ @Override
+ public void report() {
+ if (lint.isEnabled(Lint.LintCategory.CAST))
+ log.warning(Lint.LintCategory.CAST,
+ tree.pos(), "redundant.cast", tree.expr.type);
+ }
+ });
}
}
//where
@@ -1050,6 +1041,7 @@
long checkFlags(DiagnosticPosition pos, long flags, Symbol sym, JCTree tree) {
long mask;
long implicit = 0;
+
switch (sym.kind) {
case VAR:
if (sym.owner.kind != TYP)
@@ -1070,7 +1062,10 @@
} else
mask = ConstructorFlags;
} else if ((sym.owner.flags_field & INTERFACE) != 0) {
- if ((flags & (DEFAULT | STATIC)) != 0) {
+ if ((sym.owner.flags_field & ANNOTATION) != 0) {
+ mask = AnnotationTypeElementMask;
+ implicit = PUBLIC | ABSTRACT;
+ } else if ((flags & (DEFAULT | STATIC)) != 0) {
mask = InterfaceMethodMask;
implicit = PUBLIC;
if ((flags & DEFAULT) != 0) {
@@ -1079,8 +1074,7 @@
} else {
mask = implicit = InterfaceMethodFlags;
}
- }
- else {
+ } else {
mask = MethodFlags;
}
// Imply STRICTFP if owner has STRICTFP set.
@@ -2368,7 +2362,10 @@
//for each method m1 that is overridden (directly or indirectly)
//by method 'sym' in 'site'...
for (Symbol m1 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) {
- if (!sym.overrides(m1, site.tsym, types, false)) continue;
+ if (!sym.overrides(m1, site.tsym, types, false)) {
+ checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)m1);
+ continue;
+ }
//...check each method m2 that is a member of 'site'
for (Symbol m2 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) {
if (m2 == m1) continue;
@@ -2406,14 +2403,17 @@
for (Symbol s : types.membersClosure(site, true).getElementsByName(sym.name, cf)) {
//if (i) the signature of 'sym' is not a subsignature of m1 (seen as
//a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
- if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck) &&
- types.hasSameArgs(s.erasure(types), sym.erasure(types))) {
- log.error(pos,
- "name.clash.same.erasure.no.hide",
- sym, sym.location(),
- s, s.location());
- return;
- }
+ if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck)) {
+ if (types.hasSameArgs(s.erasure(types), sym.erasure(types))) {
+ log.error(pos,
+ "name.clash.same.erasure.no.hide",
+ sym, sym.location(),
+ s, s.location());
+ return;
+ } else {
+ checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)s);
+ }
+ }
}
}
@@ -2496,6 +2496,62 @@
}
}
+ /**
+ * Report warnings for potentially ambiguous method declarations. Two declarations
+ * are potentially ambiguous if they feature two unrelated functional interface
+ * in same argument position (in which case, a call site passing an implicit
+ * lambda would be ambiguous).
+ */
+ void checkPotentiallyAmbiguousOverloads(DiagnosticPosition pos, Type site,
+ MethodSymbol msym1, MethodSymbol msym2) {
+ if (msym1 != msym2 &&
+ allowDefaultMethods &&
+ lint.isEnabled(LintCategory.OVERLOADS) &&
+ (msym1.flags() & POTENTIALLY_AMBIGUOUS) == 0 &&
+ (msym2.flags() & POTENTIALLY_AMBIGUOUS) == 0) {
+ Type mt1 = types.memberType(site, msym1);
+ Type mt2 = types.memberType(site, msym2);
+ //if both generic methods, adjust type variables
+ if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL) &&
+ types.hasSameBounds((ForAll)mt1, (ForAll)mt2)) {
+ mt2 = types.subst(mt2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars);
+ }
+ //expand varargs methods if needed
+ int maxLength = Math.max(mt1.getParameterTypes().length(), mt2.getParameterTypes().length());
+ List<Type> args1 = rs.adjustArgs(mt1.getParameterTypes(), msym1, maxLength, true);
+ List<Type> args2 = rs.adjustArgs(mt2.getParameterTypes(), msym2, maxLength, true);
+ //if arities don't match, exit
+ if (args1.length() != args2.length()) return;
+ boolean potentiallyAmbiguous = false;
+ while (args1.nonEmpty() && args2.nonEmpty()) {
+ Type s = args1.head;
+ Type t = args2.head;
+ if (!types.isSubtype(t, s) && !types.isSubtype(s, t)) {
+ if (types.isFunctionalInterface(s) && types.isFunctionalInterface(t) &&
+ types.findDescriptorType(s).getParameterTypes().length() > 0 &&
+ types.findDescriptorType(s).getParameterTypes().length() ==
+ types.findDescriptorType(t).getParameterTypes().length()) {
+ potentiallyAmbiguous = true;
+ } else {
+ break;
+ }
+ }
+ args1 = args1.tail;
+ args2 = args2.tail;
+ }
+ if (potentiallyAmbiguous) {
+ //we found two incompatible functional interfaces with same arity
+ //this means a call site passing an implicit lambda would be ambigiuous
+ msym1.flags_field |= POTENTIALLY_AMBIGUOUS;
+ msym2.flags_field |= POTENTIALLY_AMBIGUOUS;
+ log.warning(LintCategory.OVERLOADS, pos, "potentially.ambiguous.overload",
+ msym1, msym1.location(),
+ msym2, msym2.location());
+ return;
+ }
+ }
+ }
+
/** Report a conflict between a user symbol and a synthetic symbol.
*/
private void syntheticError(DiagnosticPosition pos, Symbol sym) {
@@ -3275,7 +3331,9 @@
(e.sym.flags() & CLASH) == 0 &&
sym.kind == e.sym.kind &&
sym.name != names.error &&
- (sym.kind != MTH || types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) {
+ (sym.kind != MTH ||
+ types.hasSameArgs(sym.type, e.sym.type) ||
+ types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) {
if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) {
varargsDuplicateError(pos, sym, e.sym);
return true;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Fri Sep 20 19:15:59 2013 -0700
@@ -25,6 +25,7 @@
package com.sun.tools.javac.comp;
+import com.sun.source.tree.MemberReferenceTree;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.util.*;
@@ -39,7 +40,9 @@
import java.util.ArrayList;
+import java.util.Collections;
import java.util.EnumSet;
+import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
@@ -98,7 +101,7 @@
emptyDeferredAttrContext =
new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, infer.emptyContext, null, null) {
@Override
- void addDeferredAttrNode(DeferredType dt, ResultInfo ri, List<Type> stuckVars) {
+ void addDeferredAttrNode(DeferredType dt, ResultInfo ri, DeferredStuckPolicy deferredStuckPolicy) {
Assert.error("Empty deferred context!");
}
@Override
@@ -149,15 +152,15 @@
class Entry {
JCTree speculativeTree;
- Resolve.MethodResolutionPhase phase;
+ ResultInfo resultInfo;
- public Entry(JCTree speculativeTree, MethodResolutionPhase phase) {
+ public Entry(JCTree speculativeTree, ResultInfo resultInfo) {
this.speculativeTree = speculativeTree;
- this.phase = phase;
+ this.resultInfo = resultInfo;
}
- boolean matches(Resolve.MethodResolutionPhase phase) {
- return this.phase == phase;
+ boolean matches(MethodResolutionPhase phase) {
+ return resultInfo.checkContext.deferredAttrContext().phase == phase;
}
}
@@ -178,12 +181,13 @@
* Stores a speculative cache entry corresponding to given symbol
* and resolution phase
*/
- void put(Symbol msym, JCTree speculativeTree, MethodResolutionPhase phase) {
+ void put(JCTree speculativeTree, ResultInfo resultInfo) {
+ Symbol msym = resultInfo.checkContext.deferredAttrContext().msym;
List<Entry> entries = cache.get(msym);
if (entries == null) {
entries = List.nil();
}
- cache.put(msym, entries.prepend(new Entry(speculativeTree, phase)));
+ cache.put(msym, entries.prepend(new Entry(speculativeTree, resultInfo)));
}
}
@@ -203,15 +207,24 @@
* attribution round must follow one or more speculative rounds.
*/
Type check(ResultInfo resultInfo) {
- return check(resultInfo, stuckVars(tree, env, resultInfo), basicCompleter);
+ DeferredStuckPolicy deferredStuckPolicy;
+ if (resultInfo.pt.hasTag(NONE) || resultInfo.pt.isErroneous()) {
+ deferredStuckPolicy = dummyStuckPolicy;
+ } else if (resultInfo.checkContext.deferredAttrContext().mode == AttrMode.SPECULATIVE) {
+ deferredStuckPolicy = new OverloadStuckPolicy(resultInfo, this);
+ } else {
+ deferredStuckPolicy = new CheckStuckPolicy(resultInfo, this);
+ }
+ return check(resultInfo, deferredStuckPolicy, basicCompleter);
}
- Type check(ResultInfo resultInfo, List<Type> stuckVars, DeferredTypeCompleter deferredTypeCompleter) {
+ private Type check(ResultInfo resultInfo, DeferredStuckPolicy deferredStuckPolicy,
+ DeferredTypeCompleter deferredTypeCompleter) {
DeferredAttrContext deferredAttrContext =
resultInfo.checkContext.deferredAttrContext();
Assert.check(deferredAttrContext != emptyDeferredAttrContext);
- if (stuckVars.nonEmpty()) {
- deferredAttrContext.addDeferredAttrNode(this, resultInfo, stuckVars);
+ if (deferredStuckPolicy.isStuck()) {
+ deferredAttrContext.addDeferredAttrNode(this, resultInfo, deferredStuckPolicy);
return Type.noType;
} else {
try {
@@ -236,6 +249,7 @@
Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext);
}
+
/**
* A basic completer for deferred types. This completer type-checks a deferred type
* using attribution; depending on the attribution mode, this could be either standard
@@ -249,7 +263,7 @@
//speculative rounds...
Assert.check(dt.mode == null || dt.mode == AttrMode.SPECULATIVE);
JCTree speculativeTree = attribSpeculative(dt.tree, dt.env, resultInfo);
- dt.speculativeCache.put(deferredAttrContext.msym, speculativeTree, deferredAttrContext.phase);
+ dt.speculativeCache.put(speculativeTree, resultInfo);
return speculativeTree.type;
case CHECK:
Assert.check(dt.mode != null);
@@ -268,6 +282,45 @@
};
/**
+ * Policy for detecting stuck expressions. Different criteria might cause
+ * an expression to be judged as stuck, depending on whether the check
+ * is performed during overload resolution or after most specific.
+ */
+ interface DeferredStuckPolicy {
+ /**
+ * Has the policy detected that a given expression should be considered stuck?
+ */
+ boolean isStuck();
+ /**
+ * Get the set of inference variables a given expression depends upon.
+ */
+ Set<Type> stuckVars();
+ /**
+ * Get the set of inference variables which might get new constraints
+ * if a given expression is being type-checked.
+ */
+ Set<Type> depVars();
+ }
+
+ /**
+ * Basic stuck policy; an expression is never considered to be stuck.
+ */
+ DeferredStuckPolicy dummyStuckPolicy = new DeferredStuckPolicy() {
+ @Override
+ public boolean isStuck() {
+ return false;
+ }
+ @Override
+ public Set<Type> stuckVars() {
+ return Collections.emptySet();
+ }
+ @Override
+ public Set<Type> depVars() {
+ return Collections.emptySet();
+ }
+ };
+
+ /**
* The 'mode' in which the deferred type is to be type-checked
*/
public enum AttrMode {
@@ -388,8 +441,9 @@
* Adds a node to the list of deferred attribution nodes - used by Resolve.rawCheckArgumentsApplicable
* Nodes added this way act as 'roots' for the out-of-order method checking process.
*/
- void addDeferredAttrNode(final DeferredType dt, ResultInfo resultInfo, List<Type> stuckVars) {
- deferredAttrNodes.add(new DeferredAttrNode(dt, resultInfo, stuckVars));
+ void addDeferredAttrNode(final DeferredType dt, ResultInfo resultInfo,
+ DeferredStuckPolicy deferredStuckPolicy) {
+ deferredAttrNodes.add(new DeferredAttrNode(dt, resultInfo, deferredStuckPolicy));
}
/**
@@ -400,23 +454,52 @@
*/
void complete() {
while (!deferredAttrNodes.isEmpty()) {
- Set<Type> stuckVars = new LinkedHashSet<Type>();
+ Map<Type, Set<Type>> depVarsMap = new LinkedHashMap<Type, Set<Type>>();
+ List<Type> stuckVars = List.nil();
boolean progress = false;
//scan a defensive copy of the node list - this is because a deferred
//attribution round can add new nodes to the list
for (DeferredAttrNode deferredAttrNode : List.from(deferredAttrNodes)) {
if (!deferredAttrNode.process(this)) {
- stuckVars.addAll(deferredAttrNode.stuckVars);
+ List<Type> restStuckVars =
+ List.from(deferredAttrNode.deferredStuckPolicy.stuckVars())
+ .intersect(inferenceContext.restvars());
+ stuckVars = stuckVars.prependList(restStuckVars);
+ //update dependency map
+ for (Type t : List.from(deferredAttrNode.deferredStuckPolicy.depVars())
+ .intersect(inferenceContext.restvars())) {
+ Set<Type> prevDeps = depVarsMap.get(t);
+ if (prevDeps == null) {
+ prevDeps = new LinkedHashSet<Type>();
+ depVarsMap.put(t, prevDeps);
+ }
+ prevDeps.addAll(restStuckVars);
+ }
} else {
deferredAttrNodes.remove(deferredAttrNode);
progress = true;
}
}
if (!progress) {
+ DeferredAttrContext dac = this;
+ while (dac != emptyDeferredAttrContext) {
+ if (dac.mode == AttrMode.SPECULATIVE) {
+ //unsticking does not take place during overload
+ break;
+ }
+ dac = dac.parent;
+ }
//remove all variables that have already been instantiated
//from the list of stuck variables
- inferenceContext.solveAny(List.from(stuckVars), warn);
- inferenceContext.notifyChange();
+ try {
+ inferenceContext.solveAny(stuckVars, depVarsMap, warn);
+ inferenceContext.notifyChange();
+ } catch (Infer.GraphStrategy.NodeNotFoundException ex) {
+ //this means that we are in speculative mode and the
+ //set of contraints are too tight for progess to be made.
+ //Just leave the remaining expressions as stuck.
+ break;
+ }
}
}
}
@@ -426,7 +509,7 @@
* Class representing a deferred attribution node. It keeps track of
* a deferred type, along with the expected target type information.
*/
- class DeferredAttrNode implements Infer.FreeTypeListener {
+ class DeferredAttrNode {
/** underlying deferred type */
DeferredType dt;
@@ -434,22 +517,13 @@
/** underlying target type information */
ResultInfo resultInfo;
- /** list of uninferred inference variables causing this node to be stuck */
- List<Type> stuckVars;
+ /** stuck policy associated with this node */
+ DeferredStuckPolicy deferredStuckPolicy;
- DeferredAttrNode(DeferredType dt, ResultInfo resultInfo, List<Type> stuckVars) {
+ DeferredAttrNode(DeferredType dt, ResultInfo resultInfo, DeferredStuckPolicy deferredStuckPolicy) {
this.dt = dt;
this.resultInfo = resultInfo;
- this.stuckVars = stuckVars;
- if (!stuckVars.isEmpty()) {
- resultInfo.checkContext.inferenceContext().addFreeTypeListener(stuckVars, this);
- }
- }
-
- @Override
- public void typesInferred(InferenceContext inferenceContext) {
- stuckVars = List.nil();
- resultInfo = resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
+ this.deferredStuckPolicy = deferredStuckPolicy;
}
/**
@@ -457,24 +531,41 @@
* Invariant: a stuck node cannot be processed.
*/
@SuppressWarnings("fallthrough")
- boolean process(DeferredAttrContext deferredAttrContext) {
+ boolean process(final DeferredAttrContext deferredAttrContext) {
switch (deferredAttrContext.mode) {
case SPECULATIVE:
- dt.check(resultInfo, List.<Type>nil(), new StructuralStuckChecker());
- return true;
+ if (deferredStuckPolicy.isStuck()) {
+ dt.check(resultInfo, dummyStuckPolicy, new StructuralStuckChecker());
+ return true;
+ } else {
+ Assert.error("Cannot get here");
+ }
case CHECK:
- if (stuckVars.nonEmpty()) {
+ if (deferredStuckPolicy.isStuck()) {
//stuck expression - see if we can propagate
if (deferredAttrContext.parent != emptyDeferredAttrContext &&
- Type.containsAny(deferredAttrContext.parent.inferenceContext.inferencevars, List.from(stuckVars))) {
- deferredAttrContext.parent.deferredAttrNodes.add(this);
- dt.check(resultInfo, List.<Type>nil(), dummyCompleter);
+ Type.containsAny(deferredAttrContext.parent.inferenceContext.inferencevars,
+ List.from(deferredStuckPolicy.stuckVars()))) {
+ deferredAttrContext.parent.addDeferredAttrNode(dt,
+ resultInfo.dup(new Check.NestedCheckContext(resultInfo.checkContext) {
+ @Override
+ public InferenceContext inferenceContext() {
+ return deferredAttrContext.parent.inferenceContext;
+ }
+ @Override
+ public DeferredAttrContext deferredAttrContext() {
+ return deferredAttrContext.parent;
+ }
+ }), deferredStuckPolicy);
+ dt.tree.type = Type.stuckType;
return true;
} else {
return false;
}
} else {
- dt.check(resultInfo, stuckVars, basicCompleter);
+ ResultInfo instResultInfo =
+ resultInfo.dup(deferredAttrContext.inferenceContext.asInstType(resultInfo.pt));
+ dt.check(instResultInfo, dummyStuckPolicy, basicCompleter);
return true;
}
default:
@@ -489,12 +580,14 @@
ResultInfo resultInfo;
InferenceContext inferenceContext;
+ Env<AttrContext> env;
public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) {
this.resultInfo = resultInfo;
this.inferenceContext = deferredAttrContext.inferenceContext;
+ this.env = dt.env;
dt.tree.accept(this);
- dt.speculativeCache.put(deferredAttrContext.msym, stuckTree, deferredAttrContext.phase);
+ dt.speculativeCache.put(stuckTree, resultInfo);
return Type.noType;
}
@@ -541,15 +634,25 @@
} catch (Types.FunctionDescriptorLookupError ex) {
checkContext.report(null, ex.getDiagnostic());
}
- switch (tree.sym.kind) {
+ Env<AttrContext> localEnv = env.dup(tree);
+ JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv,
+ attr.memberReferenceQualifierResult(tree));
+ ListBuffer<Type> argtypes = ListBuffer.lb();
+ for (Type t : types.findDescriptorType(pt).getParameterTypes()) {
+ argtypes.append(Type.noType);
+ }
+ JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree);
+ mref2.expr = exprTree;
+ Pair<Symbol, ?> lookupRes =
+ rs.resolveMemberReference(tree, localEnv, mref2, exprTree.type,
+ tree.name, argtypes.toList(), null, true, rs.arityMethodCheck, inferenceContext);
+ switch (lookupRes.fst.kind) {
//note: as argtypes are erroneous types, type-errors must
//have been caused by arity mismatch
case Kinds.ABSENT_MTH:
case Kinds.WRONG_MTH:
case Kinds.WRONG_MTHS:
- case Kinds.STATICERR:
- case Kinds.MISSING_ENCL:
- checkContext.report(null, diags.fragment("incompatible.arg.types.in.mref"));
+ checkContext.report(tree, diags.fragment("incompatible.arg.types.in.mref"));
}
}
}
@@ -575,18 +678,12 @@
infer.emptyContext, emptyDeferredAttrContext, types.noWarnings);
}
- protected boolean validState(DeferredType dt) {
- return dt.mode != null &&
- deferredAttrContext.mode.ordinal() <= dt.mode.ordinal();
- }
-
@Override
public Type apply(Type t) {
if (!t.hasTag(DEFERRED)) {
return t.map(this);
} else {
DeferredType dt = (DeferredType)t;
- Assert.check(validState(dt));
return typeOf(dt);
}
}
@@ -623,11 +720,6 @@
recover(dt) : owntype;
}
- @Override
- protected boolean validState(DeferredType dt) {
- return true;
- }
-
/**
* Synthesize a type for a deferred type that hasn't been previously
* reduced to an ordinary type. Functional deferred types and conditionals
@@ -647,25 +739,6 @@
}
/**
- * Retrieves the list of inference variables that need to be inferred before
- * an AST node can be type-checked
- */
- @SuppressWarnings("fallthrough")
- List<Type> stuckVars(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
- if (resultInfo.pt.hasTag(NONE) || resultInfo.pt.isErroneous()) {
- return List.nil();
- } else {
- return stuckVarsInternal(tree, resultInfo.pt, env, resultInfo.checkContext.inferenceContext());
- }
- }
- //where
- private List<Type> stuckVarsInternal(JCTree tree, Type pt, Env<AttrContext> env, Infer.InferenceContext inferenceContext) {
- StuckChecker sc = new StuckChecker(pt, env, inferenceContext);
- sc.scan(tree);
- return List.from(sc.stuckVars);
- }
-
- /**
* A special tree scanner that would only visit portions of a given tree.
* The set of nodes visited by the scanner can be customized at construction-time.
*/
@@ -737,17 +810,41 @@
* inferring types that make some of the nested expressions incompatible
* with their corresponding instantiated target
*/
- class StuckChecker extends PolyScanner {
+ class CheckStuckPolicy extends PolyScanner implements DeferredStuckPolicy, Infer.FreeTypeListener {
Type pt;
- Env<AttrContext> env;
Infer.InferenceContext inferenceContext;
Set<Type> stuckVars = new LinkedHashSet<Type>();
+ Set<Type> depVars = new LinkedHashSet<Type>();
- StuckChecker(Type pt, Env<AttrContext> env, Infer.InferenceContext inferenceContext) {
- this.pt = pt;
- this.env = env;
- this.inferenceContext = inferenceContext;
+ @Override
+ public boolean isStuck() {
+ return !stuckVars.isEmpty();
+ }
+
+ @Override
+ public Set<Type> stuckVars() {
+ return stuckVars;
+ }
+
+ @Override
+ public Set<Type> depVars() {
+ return depVars;
+ }
+
+ public CheckStuckPolicy(ResultInfo resultInfo, DeferredType dt) {
+ this.pt = resultInfo.pt;
+ this.inferenceContext = resultInfo.checkContext.inferenceContext();
+ scan(dt.tree);
+ if (!stuckVars.isEmpty()) {
+ resultInfo.checkContext.inferenceContext()
+ .addFreeTypeListener(List.from(stuckVars), this);
+ }
+ }
+
+ @Override
+ public void typesInferred(InferenceContext inferenceContext) {
+ stuckVars.clear();
}
@Override
@@ -763,6 +860,7 @@
if (tree.paramKind == JCLambda.ParameterKind.IMPLICIT &&
freeArgVars.nonEmpty()) {
stuckVars.addAll(freeArgVars);
+ depVars.addAll(inferenceContext.freeVarsIn(descType.getReturnType()));
}
scanLambdaBody(tree, descType.getReturnType());
}
@@ -780,41 +878,34 @@
Type descType = types.findDescriptorType(pt);
List<Type> freeArgVars = inferenceContext.freeVarsIn(descType.getParameterTypes());
- Env<AttrContext> localEnv = env.dup(tree, env.info.dup());
- if (freeArgVars.nonEmpty()) {
- //perform arity-based check
- JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv,
- attr.memberReferenceQualifierResult(tree));
- ListBuffer<Type> argtypes = ListBuffer.lb();
- for (Type t : descType.getParameterTypes()) {
- argtypes.append(Type.noType);
- }
- JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree);
- mref2.expr = exprTree;
- Pair<Symbol, ReferenceLookupHelper> lookupRes =
- rs.resolveMemberReference(tree, localEnv, mref2, exprTree.type,
- tree.name, argtypes.toList(), null, true, rs.arityMethodCheck,
- inferenceContext);
- Symbol res = tree.sym = lookupRes.fst;
- if (res.kind >= Kinds.ERRONEOUS ||
- res.type.hasTag(FORALL) ||
- (res.flags() & Flags.VARARGS) != 0 ||
- (TreeInfo.isStaticSelector(exprTree, tree.name.table.names) &&
- exprTree.type.isRaw())) {
- stuckVars.addAll(freeArgVars);
- }
+ if (freeArgVars.nonEmpty() &&
+ tree.overloadKind == JCMemberReference.OverloadKind.OVERLOADED) {
+ stuckVars.addAll(freeArgVars);
+ depVars.addAll(inferenceContext.freeVarsIn(descType.getReturnType()));
}
}
void scanLambdaBody(JCLambda lambda, final Type pt) {
if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) {
- stuckVars.addAll(stuckVarsInternal(lambda.body, pt, env, inferenceContext));
+ Type prevPt = this.pt;
+ try {
+ this.pt = pt;
+ scan(lambda.body);
+ } finally {
+ this.pt = prevPt;
+ }
} else {
LambdaReturnScanner lambdaScanner = new LambdaReturnScanner() {
@Override
public void visitReturn(JCReturn tree) {
if (tree.expr != null) {
- stuckVars.addAll(stuckVarsInternal(tree.expr, pt, env, inferenceContext));
+ Type prevPt = CheckStuckPolicy.this.pt;
+ try {
+ CheckStuckPolicy.this.pt = pt;
+ CheckStuckPolicy.this.scan(tree.expr);
+ } finally {
+ CheckStuckPolicy.this.pt = prevPt;
+ }
}
}
};
@@ -824,6 +915,42 @@
}
/**
+ * This visitor is used to check that structural expressions conform
+ * to their target - this step is required as inference could end up
+ * inferring types that make some of the nested expressions incompatible
+ * with their corresponding instantiated target
+ */
+ class OverloadStuckPolicy extends CheckStuckPolicy implements DeferredStuckPolicy {
+
+ boolean stuck;
+
+ @Override
+ public boolean isStuck() {
+ return super.isStuck() || stuck;
+ }
+
+ public OverloadStuckPolicy(ResultInfo resultInfo, DeferredType dt) {
+ super(resultInfo, dt);
+ }
+
+ @Override
+ public void visitLambda(JCLambda tree) {
+ super.visitLambda(tree);
+ if (tree.paramKind == JCLambda.ParameterKind.IMPLICIT) {
+ stuck = true;
+ }
+ }
+
+ @Override
+ public void visitReference(JCMemberReference tree) {
+ super.visitReference(tree);
+ if (tree.overloadKind == JCMemberReference.OverloadKind.OVERLOADED) {
+ stuck = true;
+ }
+ }
+ }
+
+ /**
* Does the argument expression {@code expr} need speculative type-checking?
*/
boolean isDeferred(Env<AttrContext> env, JCExpression expr) {
@@ -904,6 +1031,26 @@
@Override
public void visitReference(JCMemberReference tree) {
+ //perform arity-based check
+ Env<AttrContext> localEnv = env.dup(tree);
+ JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv,
+ attr.memberReferenceQualifierResult(tree));
+ JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree);
+ mref2.expr = exprTree;
+ Pair<Symbol, ReferenceLookupHelper> lookupRes =
+ rs.resolveMemberReference(tree, localEnv, mref2, exprTree.type,
+ tree.name, List.<Type>nil(), null, true, rs.nilMethodCheck,
+ infer.emptyContext);
+ Symbol res = tree.sym = lookupRes.fst;
+ if (res.kind >= Kinds.ERRONEOUS ||
+ res.type.hasTag(FORALL) ||
+ (res.flags() & Flags.VARARGS) != 0 ||
+ (TreeInfo.isStaticSelector(exprTree, tree.name.table.names) &&
+ exprTree.type.isRaw())) {
+ tree.overloadKind = JCMemberReference.OverloadKind.OVERLOADED;
+ } else {
+ tree.overloadKind = JCMemberReference.OverloadKind.UNOVERLOADED;
+ }
//a method reference is always a poly expression
result = ArgumentExpressionKind.POLY;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Fri Sep 20 19:15:59 2013 -0700
@@ -207,7 +207,7 @@
public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
new AliveAnalyzer().analyzeTree(env, make);
- new AssignAnalyzer().analyzeTree(env, make);
+ new AssignAnalyzer(log, syms, lint, names).analyzeTree(env);
new FlowAnalyzer().analyzeTree(env, make);
new CaptureAnalyzer().analyzeTree(env, make);
}
@@ -224,7 +224,6 @@
}
try {
new AliveAnalyzer().analyzeTree(env, that, make);
- new LambdaFlowAnalyzer().analyzeTree(env, that, make);
} finally {
if (!speculative) {
log.popDiagnosticHandler(diagHandler);
@@ -232,6 +231,23 @@
}
}
+ public List<Type> analyzeLambdaThrownTypes(Env<AttrContext> env, JCLambda that, TreeMaker make) {
+ //we need to disable diagnostics temporarily; the problem is that if
+ //a lambda expression contains e.g. an unreachable statement, an error
+ //message will be reported and will cause compilation to skip the flow analyis
+ //step - if we suppress diagnostics, we won't stop at Attr for flow-analysis
+ //related errors, which will allow for more errors to be detected
+ Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
+ try {
+ new AssignAnalyzer(log, syms, lint, names).analyzeTree(env);
+ LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer();
+ flowAnalyzer.analyzeTree(env, that, make);
+ return flowAnalyzer.inferredThrownTypes;
+ } finally {
+ log.popDiagnosticHandler(diagHandler);
+ }
+ }
+
/**
* Definite assignment scan mode
*/
@@ -276,15 +292,6 @@
}
/**
- * Utility method to reset several Bits instances.
- */
- private void resetBits(Bits... bits) {
- for (Bits b : bits) {
- b.reset();
- }
- }
-
- /**
* Base visitor class for all visitors implementing dataflow analysis logic.
* This class define the shared logic for handling jumps (break/continue statements).
*/
@@ -331,17 +338,17 @@
this.tree = tree;
}
- void resolveJump() {
+ void resolveJump(JCTree tree) {
//do nothing
}
}
- abstract void markDead();
+ abstract void markDead(JCTree tree);
/** Record an outward transfer of control. */
void recordExit(JCTree tree, P pe) {
pendingExits.append(pe);
- markDead();
+ markDead(tree);
}
/** Resolve all jumps of this statement. */
@@ -355,7 +362,7 @@
P exit = exits.head;
if (exit.tree.hasTag(jk.treeTag) &&
jk.getTarget(exit.tree) == tree) {
- exit.resolveJump();
+ exit.resolveJump(tree);
resolved = true;
} else {
pendingExits.append(exit);
@@ -364,12 +371,12 @@
return resolved;
}
- /** Resolve all breaks of this statement. */
+ /** Resolve all continues of this statement. */
boolean resolveContinues(JCTree tree) {
return resolveJump(tree, new ListBuffer<P>(), JumpKind.CONTINUE);
}
- /** Resolve all continues of this statement. */
+ /** Resolve all breaks of this statement. */
boolean resolveBreaks(JCTree tree, ListBuffer<P> oldPendingExits) {
return resolveJump(tree, oldPendingExits, JumpKind.BREAK);
}
@@ -398,7 +405,7 @@
private boolean alive;
@Override
- void markDead() {
+ void markDead(JCTree tree) {
alive = false;
}
@@ -680,7 +687,7 @@
public void visitThrow(JCThrow tree) {
scan(tree.expr);
- markDead();
+ markDead(tree);
}
public void visitApply(JCMethodInvocation tree) {
@@ -781,7 +788,7 @@
}
@Override
- void markDead() {
+ void markDead(JCTree tree) {
//do nothing
}
@@ -1206,7 +1213,7 @@
else {
markThrown(tree, tree.expr.type);
}
- markDead();
+ markDead(tree);
}
public void visitApply(JCMethodInvocation tree) {
@@ -1318,27 +1325,35 @@
* Specialized pass that performs inference of thrown types for lambdas.
*/
class LambdaFlowAnalyzer extends FlowAnalyzer {
+ List<Type> inferredThrownTypes;
+ boolean inLambda;
@Override
public void visitLambda(JCLambda tree) {
- if (tree.type != null &&
- tree.type.isErroneous()) {
+ if ((tree.type != null &&
+ tree.type.isErroneous()) || inLambda) {
return;
}
List<Type> prevCaught = caught;
List<Type> prevThrown = thrown;
ListBuffer<FlowPendingExit> prevPending = pendingExits;
+ inLambda = true;
try {
pendingExits = ListBuffer.lb();
caught = List.of(syms.throwableType);
thrown = List.nil();
scan(tree.body);
- tree.inferredThrownTypes = thrown;
+ inferredThrownTypes = thrown;
} finally {
pendingExits = prevPending;
caught = prevCaught;
thrown = prevThrown;
+ inLambda = false;
}
}
+ @Override
+ public void visitClassDef(JCClassDecl tree) {
+ //skip
+ }
}
/**
@@ -1348,11 +1363,13 @@
* depends on the results of the liveliness analyzer. This pass is also used to mark
* effectively-final local variables/parameters.
*/
- class AssignAnalyzer extends BaseAnalyzer<AssignAnalyzer.AssignPendingExit> {
+
+ public abstract static class AbstractAssignAnalyzer<P extends AbstractAssignAnalyzer.AbstractAssignPendingExit>
+ extends BaseAnalyzer<P> {
/** The set of definitely assigned variables.
*/
- final Bits inits;
+ protected final Bits inits;
/** The set of definitely unassigned variables.
*/
@@ -1378,7 +1395,7 @@
/** A mapping from addresses to variable symbols.
*/
- JCVariableDecl[] vardecls;
+ protected JCVariableDecl[] vardecls;
/** The current class being defined.
*/
@@ -1390,11 +1407,11 @@
/** The next available variable sequence number.
*/
- int nextadr;
+ protected int nextadr;
/** The first variable sequence number in a block that can return.
*/
- int returnadr;
+ protected int returnadr;
/** The list of unreferenced automatic resources.
*/
@@ -1406,35 +1423,46 @@
/** The starting position of the analysed tree */
int startPos;
- AssignAnalyzer() {
- inits = new Bits();
+ final Symtab syms;
+
+ protected Names names;
+
+ public static class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit {
+
+ final Bits inits;
+ final Bits uninits;
+ final Bits exit_inits = new Bits(true);
+ final Bits exit_uninits = new Bits(true);
+
+ public AbstractAssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
+ super(tree);
+ this.inits = inits;
+ this.uninits = uninits;
+ this.exit_inits.assign(inits);
+ this.exit_uninits.assign(uninits);
+ }
+
+ @Override
+ public void resolveJump(JCTree tree) {
+ inits.andSet(exit_inits);
+ uninits.andSet(exit_uninits);
+ }
+ }
+
+ public AbstractAssignAnalyzer(Bits inits, Symtab syms, Names names) {
+ this.inits = inits;
uninits = new Bits();
uninitsTry = new Bits();
initsWhenTrue = new Bits(true);
initsWhenFalse = new Bits(true);
uninitsWhenTrue = new Bits(true);
uninitsWhenFalse = new Bits(true);
- }
-
- class AssignPendingExit extends BaseAnalyzer.PendingExit {
-
- final Bits exit_inits = new Bits(true);
- final Bits exit_uninits = new Bits(true);
-
- AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
- super(tree);
- this.exit_inits.assign(inits);
- this.exit_uninits.assign(uninits);
- }
-
- void resolveJump() {
- inits.andSet(exit_inits);
- uninits.andSet(exit_uninits);
- }
+ this.syms = syms;
+ this.names = names;
}
@Override
- void markDead() {
+ protected void markDead(JCTree tree) {
inits.inclRange(returnadr, nextadr);
uninits.inclRange(returnadr, nextadr);
}
@@ -1444,7 +1472,7 @@
/** Do we need to track init/uninit state of this symbol?
* I.e. is symbol either a local or a blank final variable?
*/
- boolean trackable(VarSymbol sym) {
+ protected boolean trackable(VarSymbol sym) {
return
sym.pos >= startPos &&
((sym.owner.kind == MTH ||
@@ -1464,44 +1492,35 @@
}
sym.adr = nextadr;
vardecls[nextadr] = varDecl;
- inits.excl(nextadr);
+ exclVarFromInits(varDecl, nextadr);
uninits.incl(nextadr);
nextadr++;
}
+ protected void exclVarFromInits(JCTree tree, int adr) {
+ inits.excl(adr);
+ }
+
+ protected void assignToInits(JCTree tree, Bits bits) {
+ inits.assign(bits);
+ }
+
+ protected void andSetInits(JCTree tree, Bits bits) {
+ inits.andSet(bits);
+ }
+
+ protected void orSetInits(JCTree tree, Bits bits) {
+ inits.orSet(bits);
+ }
+
/** Record an initialization of a trackable variable.
*/
void letInit(DiagnosticPosition pos, VarSymbol sym) {
if (sym.adr >= firstadr && trackable(sym)) {
- if ((sym.flags() & EFFECTIVELY_FINAL) != 0) {
- if (!uninits.isMember(sym.adr)) {
- //assignment targeting an effectively final variable
- //makes the variable lose its status of effectively final
- //if the variable is _not_ definitively unassigned
- sym.flags_field &= ~EFFECTIVELY_FINAL;
- } else {
- uninit(sym);
- }
- }
- else if ((sym.flags() & FINAL) != 0) {
- if ((sym.flags() & PARAMETER) != 0) {
- if ((sym.flags() & UNION) != 0) { //multi-catch parameter
- log.error(pos, "multicatch.parameter.may.not.be.assigned",
- sym);
- }
- else {
- log.error(pos, "final.parameter.may.not.be.assigned",
- sym);
- }
- } else if (!uninits.isMember(sym.adr)) {
- log.error(pos, flowKind.errKey, sym);
- } else {
- uninit(sym);
- }
+ if (uninits.isMember(sym.adr)) {
+ uninit(sym);
}
inits.incl(sym.adr);
- } else if ((sym.flags() & FINAL) != 0) {
- log.error(pos, "var.might.already.be.assigned", sym);
}
}
//where
@@ -1535,12 +1554,14 @@
void checkInit(DiagnosticPosition pos, VarSymbol sym) {
checkInit(pos, sym, "var.might.not.have.been.initialized");
}
- void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) {
- if ((sym.adr >= firstadr || sym.owner.kind != TYP) &&
- trackable(sym) &&
- !inits.isMember(sym.adr)) {
- log.error(pos, errkey, sym);
- inits.incl(sym.adr);
+
+ void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) {}
+
+ /** Utility method to reset several Bits instances.
+ */
+ private void resetBits(Bits... bits) {
+ for (Bits b : bits) {
+ b.reset();
}
}
@@ -1558,7 +1579,7 @@
/** Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets.
*/
- void merge() {
+ protected void merge(JCTree tree) {
inits.assign(initsWhenFalse.andSet(initsWhenTrue));
uninits.assign(uninitsWhenFalse.andSet(uninitsWhenTrue));
}
@@ -1573,7 +1594,9 @@
void scanExpr(JCTree tree) {
if (tree != null) {
scan(tree);
- if (inits.isReset()) merge();
+ if (inits.isReset()) {
+ merge(tree);
+ }
}
}
@@ -1590,7 +1613,7 @@
*/
void scanCond(JCTree tree) {
if (tree.type.isFalse()) {
- if (inits.isReset()) merge();
+ if (inits.isReset()) merge(tree);
initsWhenTrue.assign(inits);
initsWhenTrue.inclRange(firstadr, nextadr);
uninitsWhenTrue.assign(uninits);
@@ -1598,7 +1621,7 @@
initsWhenFalse.assign(inits);
uninitsWhenFalse.assign(uninits);
} else if (tree.type.isTrue()) {
- if (inits.isReset()) merge();
+ if (inits.isReset()) merge(tree);
initsWhenFalse.assign(inits);
initsWhenFalse.inclRange(firstadr, nextadr);
uninitsWhenFalse.assign(uninits);
@@ -1617,22 +1640,22 @@
/* ------------ Visitor methods for various sorts of trees -------------*/
+ @Override
public void visitClassDef(JCClassDecl tree) {
- if (tree.sym == null) return;
+ if (tree.sym == null) {
+ return;
+ }
JCClassDecl classDefPrev = classDef;
int firstadrPrev = firstadr;
int nextadrPrev = nextadr;
- ListBuffer<AssignPendingExit> pendingExitsPrev = pendingExits;
- Lint lintPrev = lint;
+ ListBuffer<P> pendingExitsPrev = pendingExits;
- pendingExits = new ListBuffer<AssignPendingExit>();
+ pendingExits = new ListBuffer<P>();
if (tree.name != names.empty) {
firstadr = nextadr;
}
classDef = tree;
- lint = lint.augment(tree.sym);
-
try {
// define all the static fields
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
@@ -1640,8 +1663,9 @@
JCVariableDecl def = (JCVariableDecl)l.head;
if ((def.mods.flags & STATIC) != 0) {
VarSymbol sym = def.sym;
- if (trackable(sym))
+ if (trackable(sym)) {
newVar(def);
+ }
}
}
}
@@ -1660,8 +1684,9 @@
JCVariableDecl def = (JCVariableDecl)l.head;
if ((def.mods.flags & STATIC) == 0) {
VarSymbol sym = def.sym;
- if (trackable(sym))
+ if (trackable(sym)) {
newVar(def);
+ }
}
}
}
@@ -1685,21 +1710,25 @@
nextadr = nextadrPrev;
firstadr = firstadrPrev;
classDef = classDefPrev;
- lint = lintPrev;
}
}
+ @Override
public void visitMethodDef(JCMethodDecl tree) {
- if (tree.body == null) return;
+ if (tree.body == null) {
+ return;
+ }
+ /* MemberEnter can generate synthetic methods, ignore them
+ */
+ if ((tree.sym.flags() & SYNTHETIC) != 0) {
+ return;
+ }
final Bits initsPrev = new Bits(inits);
final Bits uninitsPrev = new Bits(uninits);
int nextadrPrev = nextadr;
int firstadrPrev = firstadr;
int returnadrPrev = returnadr;
- Lint lintPrev = lint;
-
- lint = lint.augment(tree.sym);
Assert.check(pendingExits.isEmpty());
@@ -1707,13 +1736,17 @@
boolean isInitialConstructor =
TreeInfo.isInitialConstructor(tree);
- if (!isInitialConstructor)
+ if (!isInitialConstructor) {
firstadr = nextadr;
+ }
for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
JCVariableDecl def = l.head;
scan(def);
- inits.incl(def.sym.adr);
- uninits.excl(def.sym.adr);
+ Assert.check((def.sym.flags() & PARAMETER) != 0, "Method parameter without PARAMETER flag");
+ /* If we are executing the code from Gen, then there can be
+ * synthetic or mandated variables, ignore them.
+ */
+ initParam(def);
}
// else we are in an instance initializer block;
// leave caught unchanged.
@@ -1737,39 +1770,42 @@
}
}
}
- List<AssignPendingExit> exits = pendingExits.toList();
- pendingExits = new ListBuffer<AssignPendingExit>();
+ List<P> exits = pendingExits.toList();
+ pendingExits = new ListBuffer<>();
while (exits.nonEmpty()) {
- AssignPendingExit exit = exits.head;
+ P exit = exits.head;
exits = exits.tail;
Assert.check(exit.tree.hasTag(RETURN), exit.tree);
if (isInitialConstructor) {
- inits.assign(exit.exit_inits);
- for (int i = firstadr; i < nextadr; i++)
+ assignToInits(exit.tree, exit.exit_inits);
+ for (int i = firstadr; i < nextadr; i++) {
checkInit(exit.tree.pos(), vardecls[i].sym);
+ }
}
}
} finally {
- inits.assign(initsPrev);
+ assignToInits(tree, initsPrev);
uninits.assign(uninitsPrev);
nextadr = nextadrPrev;
firstadr = firstadrPrev;
returnadr = returnadrPrev;
- lint = lintPrev;
}
}
+ protected void initParam(JCVariableDecl def) {
+ inits.incl(def.sym.adr);
+ uninits.excl(def.sym.adr);
+ }
+
public void visitVarDef(JCVariableDecl tree) {
boolean track = trackable(tree.sym);
- if (track && tree.sym.owner.kind == MTH) newVar(tree);
+ if (track && tree.sym.owner.kind == MTH) {
+ newVar(tree);
+ }
if (tree.init != null) {
- Lint lintPrev = lint;
- lint = lint.augment(tree.sym);
- try{
- scanExpr(tree.init);
- if (track) letInit(tree.pos(), tree.sym);
- } finally {
- lint = lintPrev;
+ scanExpr(tree.init);
+ if (track) {
+ letInit(tree.pos(), tree.sym);
}
}
}
@@ -1780,14 +1816,18 @@
nextadr = nextadrPrev;
}
+ int getLogNumberOfErrors() {
+ return 0;
+ }
+
public void visitDoLoop(JCDoWhileLoop tree) {
- ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
+ ListBuffer<P> prevPendingExits = pendingExits;
FlowKind prevFlowKind = flowKind;
flowKind = FlowKind.NORMAL;
final Bits initsSkip = new Bits(true);
final Bits uninitsSkip = new Bits(true);
- pendingExits = new ListBuffer<AssignPendingExit>();
- int prevErrors = log.nerrors;
+ pendingExits = new ListBuffer<P>();
+ int prevErrors = getLogNumberOfErrors();
do {
final Bits uninitsEntry = new Bits(uninits);
uninitsEntry.excludeFrom(nextadr);
@@ -1798,28 +1838,28 @@
initsSkip.assign(initsWhenFalse);
uninitsSkip.assign(uninitsWhenFalse);
}
- if (log.nerrors != prevErrors ||
+ if (getLogNumberOfErrors() != prevErrors ||
flowKind.isFinal() ||
new Bits(uninitsEntry).diffSet(uninitsWhenTrue).nextBit(firstadr)==-1)
break;
- inits.assign(initsWhenTrue);
+ assignToInits(tree.cond, initsWhenTrue);
uninits.assign(uninitsEntry.andSet(uninitsWhenTrue));
flowKind = FlowKind.SPECULATIVE_LOOP;
} while (true);
flowKind = prevFlowKind;
- inits.assign(initsSkip);
+ assignToInits(tree, initsSkip);
uninits.assign(uninitsSkip);
resolveBreaks(tree, prevPendingExits);
}
public void visitWhileLoop(JCWhileLoop tree) {
- ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
+ ListBuffer<P> prevPendingExits = pendingExits;
FlowKind prevFlowKind = flowKind;
flowKind = FlowKind.NORMAL;
final Bits initsSkip = new Bits(true);
final Bits uninitsSkip = new Bits(true);
- pendingExits = new ListBuffer<AssignPendingExit>();
- int prevErrors = log.nerrors;
+ pendingExits = new ListBuffer<>();
+ int prevErrors = getLogNumberOfErrors();
final Bits uninitsEntry = new Bits(uninits);
uninitsEntry.excludeFrom(nextadr);
do {
@@ -1828,35 +1868,36 @@
initsSkip.assign(initsWhenFalse) ;
uninitsSkip.assign(uninitsWhenFalse);
}
- inits.assign(initsWhenTrue);
+ assignToInits(tree, initsWhenTrue);
uninits.assign(uninitsWhenTrue);
scan(tree.body);
resolveContinues(tree);
- if (log.nerrors != prevErrors ||
+ if (getLogNumberOfErrors() != prevErrors ||
flowKind.isFinal() ||
- new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
+ new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) {
break;
+ }
uninits.assign(uninitsEntry.andSet(uninits));
flowKind = FlowKind.SPECULATIVE_LOOP;
} while (true);
flowKind = prevFlowKind;
//a variable is DA/DU after the while statement, if it's DA/DU assuming the
//branch is not taken AND if it's DA/DU before any break statement
- inits.assign(initsSkip);
+ assignToInits(tree.body, initsSkip);
uninits.assign(uninitsSkip);
resolveBreaks(tree, prevPendingExits);
}
public void visitForLoop(JCForLoop tree) {
- ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
+ ListBuffer<P> prevPendingExits = pendingExits;
FlowKind prevFlowKind = flowKind;
flowKind = FlowKind.NORMAL;
int nextadrPrev = nextadr;
scan(tree.init);
final Bits initsSkip = new Bits(true);
final Bits uninitsSkip = new Bits(true);
- pendingExits = new ListBuffer<AssignPendingExit>();
- int prevErrors = log.nerrors;
+ pendingExits = new ListBuffer<P>();
+ int prevErrors = getLogNumberOfErrors();
do {
final Bits uninitsEntry = new Bits(uninits);
uninitsEntry.excludeFrom(nextadr);
@@ -1866,7 +1907,7 @@
initsSkip.assign(initsWhenFalse);
uninitsSkip.assign(uninitsWhenFalse);
}
- inits.assign(initsWhenTrue);
+ assignToInits(tree.body, initsWhenTrue);
uninits.assign(uninitsWhenTrue);
} else if (!flowKind.isFinal()) {
initsSkip.assign(inits);
@@ -1877,7 +1918,7 @@
scan(tree.body);
resolveContinues(tree);
scan(tree.step);
- if (log.nerrors != prevErrors ||
+ if (getLogNumberOfErrors() != prevErrors ||
flowKind.isFinal() ||
new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
break;
@@ -1887,7 +1928,7 @@
flowKind = prevFlowKind;
//a variable is DA/DU after a for loop, if it's DA/DU assuming the
//branch is not taken AND if it's DA/DU before any break statement
- inits.assign(initsSkip);
+ assignToInits(tree.body, initsSkip);
uninits.assign(uninitsSkip);
resolveBreaks(tree, prevPendingExits);
nextadr = nextadrPrev;
@@ -1896,7 +1937,7 @@
public void visitForeachLoop(JCEnhancedForLoop tree) {
visitVarDef(tree.var);
- ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
+ ListBuffer<P> prevPendingExits = pendingExits;
FlowKind prevFlowKind = flowKind;
flowKind = FlowKind.NORMAL;
int nextadrPrev = nextadr;
@@ -1905,14 +1946,14 @@
final Bits uninitsStart = new Bits(uninits);
letInit(tree.pos(), tree.var.sym);
- pendingExits = new ListBuffer<AssignPendingExit>();
- int prevErrors = log.nerrors;
+ pendingExits = new ListBuffer<P>();
+ int prevErrors = getLogNumberOfErrors();
do {
final Bits uninitsEntry = new Bits(uninits);
uninitsEntry.excludeFrom(nextadr);
scan(tree.body);
resolveContinues(tree);
- if (log.nerrors != prevErrors ||
+ if (getLogNumberOfErrors() != prevErrors ||
flowKind.isFinal() ||
new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
break;
@@ -1920,41 +1961,50 @@
flowKind = FlowKind.SPECULATIVE_LOOP;
} while (true);
flowKind = prevFlowKind;
- inits.assign(initsStart);
+ assignToInits(tree.body, initsStart);
uninits.assign(uninitsStart.andSet(uninits));
resolveBreaks(tree, prevPendingExits);
nextadr = nextadrPrev;
}
public void visitLabelled(JCLabeledStatement tree) {
- ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
- pendingExits = new ListBuffer<AssignPendingExit>();
+ ListBuffer<P> prevPendingExits = pendingExits;
+ pendingExits = new ListBuffer<P>();
scan(tree.body);
resolveBreaks(tree, prevPendingExits);
}
public void visitSwitch(JCSwitch tree) {
- ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
- pendingExits = new ListBuffer<AssignPendingExit>();
+ ListBuffer<P> prevPendingExits = pendingExits;
+ pendingExits = new ListBuffer<>();
int nextadrPrev = nextadr;
scanExpr(tree.selector);
final Bits initsSwitch = new Bits(inits);
final Bits uninitsSwitch = new Bits(uninits);
boolean hasDefault = false;
for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
- inits.assign(initsSwitch);
+ assignToInits(l.head, initsSwitch);
uninits.assign(uninits.andSet(uninitsSwitch));
JCCase c = l.head;
- if (c.pat == null)
+ if (c.pat == null) {
hasDefault = true;
- else
+ } else {
scanExpr(c.pat);
+ }
+ if (hasDefault) {
+ assignToInits(null, initsSwitch);
+ uninits.assign(uninits.andSet(uninitsSwitch));
+ }
scan(c.stats);
addVars(c.stats, initsSwitch, uninitsSwitch);
+ if (!hasDefault) {
+ assignToInits(l.head.stats.last(), initsSwitch);
+ uninits.assign(uninits.andSet(uninitsSwitch));
+ }
// Warn about fall-through if lint switch fallthrough enabled.
}
if (!hasDefault) {
- inits.andSet(initsSwitch);
+ andSetInits(null, initsSwitch);
}
resolveBreaks(tree, prevPendingExits);
nextadr = nextadrPrev;
@@ -1973,11 +2023,17 @@
}
}
+ boolean isEnabled(Lint.LintCategory lc) {
+ return false;
+ }
+
+ void reportWarning(Lint.LintCategory lc, DiagnosticPosition pos, String key, Object ... args) {}
+
public void visitTry(JCTry tree) {
ListBuffer<JCVariableDecl> resourceVarDecls = ListBuffer.lb();
final Bits uninitsTryPrev = new Bits(uninitsTry);
- ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
- pendingExits = new ListBuffer<AssignPendingExit>();
+ ListBuffer<P> prevPendingExits = pendingExits;
+ pendingExits = new ListBuffer<>();
final Bits initsTry = new Bits(inits);
uninitsTry.assign(uninits);
for (JCTree resource : tree.resources) {
@@ -1999,10 +2055,10 @@
int nextadrCatch = nextadr;
if (!resourceVarDecls.isEmpty() &&
- lint.isEnabled(Lint.LintCategory.TRY)) {
+ isEnabled(Lint.LintCategory.TRY)) {
for (JCVariableDecl resVar : resourceVarDecls) {
if (unrefdResources.includes(resVar.sym)) {
- log.warning(Lint.LintCategory.TRY, resVar.pos(),
+ reportWarning(Lint.LintCategory.TRY, resVar.pos(),
"try.resource.not.referenced", resVar.sym);
unrefdResources.remove(resVar.sym);
}
@@ -2018,20 +2074,22 @@
for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
JCVariableDecl param = l.head.param;
- inits.assign(initsCatchPrev);
+ assignToInits(tree.body, initsCatchPrev);
uninits.assign(uninitsCatchPrev);
scan(param);
- inits.incl(param.sym.adr);
- uninits.excl(param.sym.adr);
+ /* If this is a TWR and we are executing the code from Gen,
+ * then there can be synthetic variables, ignore them.
+ */
+ initParam(param);
scan(l.head.body);
initsEnd.andSet(inits);
uninitsEnd.andSet(uninits);
nextadr = nextadrCatch;
}
if (tree.finalizer != null) {
- inits.assign(initsTry);
+ assignToInits(tree.finalizer, initsTry);
uninits.assign(uninitsTry);
- ListBuffer<AssignPendingExit> exits = pendingExits;
+ ListBuffer<P> exits = pendingExits;
pendingExits = prevPendingExits;
scan(tree.finalizer);
if (!tree.finallyCanCompleteNormally) {
@@ -2041,19 +2099,19 @@
// FIX: this doesn't preserve source order of exits in catch
// versus finally!
while (exits.nonEmpty()) {
- AssignPendingExit exit = exits.next();
+ P exit = exits.next();
if (exit.exit_inits != null) {
exit.exit_inits.orSet(inits);
exit.exit_uninits.andSet(uninits);
}
pendingExits.append(exit);
}
- inits.orSet(initsEnd);
+ orSetInits(tree, initsEnd);
}
} else {
- inits.assign(initsEnd);
+ assignToInits(tree, initsEnd);
uninits.assign(uninitsEnd);
- ListBuffer<AssignPendingExit> exits = pendingExits;
+ ListBuffer<P> exits = pendingExits;
pendingExits = prevPendingExits;
while (exits.nonEmpty()) pendingExits.append(exits.next());
}
@@ -2064,7 +2122,7 @@
scanCond(tree.cond);
final Bits initsBeforeElse = new Bits(initsWhenFalse);
final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse);
- inits.assign(initsWhenTrue);
+ assignToInits(tree.cond, initsWhenTrue);
uninits.assign(uninitsWhenTrue);
if (tree.truepart.type.hasTag(BOOLEAN) &&
tree.falsepart.type.hasTag(BOOLEAN)) {
@@ -2077,7 +2135,7 @@
final Bits initsAfterThenWhenFalse = new Bits(initsWhenFalse);
final Bits uninitsAfterThenWhenTrue = new Bits(uninitsWhenTrue);
final Bits uninitsAfterThenWhenFalse = new Bits(uninitsWhenFalse);
- inits.assign(initsBeforeElse);
+ assignToInits(tree.truepart, initsBeforeElse);
uninits.assign(uninitsBeforeElse);
scanCond(tree.falsepart);
initsWhenTrue.andSet(initsAfterThenWhenTrue);
@@ -2088,10 +2146,10 @@
scanExpr(tree.truepart);
final Bits initsAfterThen = new Bits(inits);
final Bits uninitsAfterThen = new Bits(uninits);
- inits.assign(initsBeforeElse);
+ assignToInits(tree.truepart, initsBeforeElse);
uninits.assign(uninitsBeforeElse);
scanExpr(tree.falsepart);
- inits.andSet(initsAfterThen);
+ andSetInits(tree.falsepart, initsAfterThen);
uninits.andSet(uninitsAfterThen);
}
}
@@ -2100,39 +2158,46 @@
scanCond(tree.cond);
final Bits initsBeforeElse = new Bits(initsWhenFalse);
final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse);
- inits.assign(initsWhenTrue);
+ assignToInits(tree.cond, initsWhenTrue);
uninits.assign(uninitsWhenTrue);
scan(tree.thenpart);
if (tree.elsepart != null) {
final Bits initsAfterThen = new Bits(inits);
final Bits uninitsAfterThen = new Bits(uninits);
- inits.assign(initsBeforeElse);
+ assignToInits(tree.thenpart, initsBeforeElse);
uninits.assign(uninitsBeforeElse);
scan(tree.elsepart);
- inits.andSet(initsAfterThen);
+ andSetInits(tree.elsepart, initsAfterThen);
uninits.andSet(uninitsAfterThen);
} else {
- inits.andSet(initsBeforeElse);
+ andSetInits(tree.thenpart, initsBeforeElse);
uninits.andSet(uninitsBeforeElse);
}
}
+ protected P createNewPendingExit(JCTree tree, Bits inits, Bits uninits) {
+ return null;
+ }
+
+ @Override
public void visitBreak(JCBreak tree) {
- recordExit(tree, new AssignPendingExit(tree, inits, uninits));
+ recordExit(tree, createNewPendingExit(tree, inits, uninits));
}
+ @Override
public void visitContinue(JCContinue tree) {
- recordExit(tree, new AssignPendingExit(tree, inits, uninits));
+ recordExit(tree, createNewPendingExit(tree, inits, uninits));
}
+ @Override
public void visitReturn(JCReturn tree) {
scanExpr(tree.expr);
- recordExit(tree, new AssignPendingExit(tree, inits, uninits));
+ recordExit(tree, createNewPendingExit(tree, inits, uninits));
}
public void visitThrow(JCThrow tree) {
scanExpr(tree.expr);
- markDead();
+ markDead(tree.expr);
}
public void visitApply(JCMethodInvocation tree) {
@@ -2151,10 +2216,10 @@
final Bits prevUninits = new Bits(uninits);
final Bits prevInits = new Bits(inits);
int returnadrPrev = returnadr;
- ListBuffer<AssignPendingExit> prevPending = pendingExits;
+ ListBuffer<P> prevPending = pendingExits;
try {
returnadr = nextadr;
- pendingExits = new ListBuffer<AssignPendingExit>();
+ pendingExits = new ListBuffer<P>();
for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
JCVariableDecl def = l.head;
scan(def);
@@ -2170,7 +2235,7 @@
finally {
returnadr = returnadrPrev;
uninits.assign(prevUninits);
- inits.assign(prevInits);
+ assignToInits(tree, prevInits);
pendingExits = prevPending;
}
}
@@ -2186,11 +2251,11 @@
scanCond(tree.cond);
uninitsExit.andSet(uninitsWhenTrue);
if (tree.detail != null) {
- inits.assign(initsWhenFalse);
+ assignToInits(tree, initsWhenFalse);
uninits.assign(uninitsWhenFalse);
scanExpr(tree.detail);
}
- inits.assign(initsExit);
+ assignToInits(tree, initsExit);
uninits.assign(uninitsExit);
}
@@ -2236,7 +2301,7 @@
scanCond(tree.lhs);
final Bits initsWhenFalseLeft = new Bits(initsWhenFalse);
final Bits uninitsWhenFalseLeft = new Bits(uninitsWhenFalse);
- inits.assign(initsWhenTrue);
+ assignToInits(tree.lhs, initsWhenTrue);
uninits.assign(uninitsWhenTrue);
scanCond(tree.rhs);
initsWhenFalse.andSet(initsWhenFalseLeft);
@@ -2246,7 +2311,7 @@
scanCond(tree.lhs);
final Bits initsWhenTrueLeft = new Bits(initsWhenTrue);
final Bits uninitsWhenTrueLeft = new Bits(uninitsWhenTrue);
- inits.assign(initsWhenFalse);
+ assignToInits(tree.lhs, initsWhenFalse);
uninits.assign(uninitsWhenFalse);
scanCond(tree.rhs);
initsWhenTrue.andSet(initsWhenTrueLeft);
@@ -2284,14 +2349,12 @@
/** Perform definite assignment/unassignment analysis on a tree.
*/
- public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
- analyzeTree(env, env.tree, make);
- }
+ public void analyzeTree(Env<?> env) {
+ analyzeTree(env, env.tree);
+ }
- public void analyzeTree(Env<AttrContext> env, JCTree tree, TreeMaker make) {
+ public void analyzeTree(Env<?> env, JCTree tree) {
try {
- attrEnv = env;
- Flow.this.make = make;
startPos = tree.pos().getStartPosition();
if (vardecls == null)
@@ -2301,7 +2364,7 @@
vardecls[i] = null;
firstadr = 0;
nextadr = 0;
- pendingExits = new ListBuffer<AssignPendingExit>();
+ pendingExits = new ListBuffer<>();
this.classDef = null;
unrefdResources = new Scope(env.enclClass.sym);
scan(tree);
@@ -2310,18 +2373,160 @@
startPos = -1;
resetBits(inits, uninits, uninitsTry, initsWhenTrue,
initsWhenFalse, uninitsWhenTrue, uninitsWhenFalse);
- if (vardecls != null) for (int i=0; i<vardecls.length; i++)
- vardecls[i] = null;
+ if (vardecls != null) {
+ for (int i=0; i<vardecls.length; i++)
+ vardecls[i] = null;
+ }
firstadr = 0;
nextadr = 0;
pendingExits = null;
- Flow.this.make = null;
this.classDef = null;
unrefdResources = null;
}
}
}
+ public static class AssignAnalyzer
+ extends AbstractAssignAnalyzer<AssignAnalyzer.AssignPendingExit> {
+
+ Log log;
+ Lint lint;
+
+ public static class AssignPendingExit
+ extends AbstractAssignAnalyzer.AbstractAssignPendingExit {
+
+ public AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
+ super(tree, inits, uninits);
+ }
+ }
+
+ public AssignAnalyzer(Log log, Symtab syms, Lint lint, Names names) {
+ super(new Bits(), syms, names);
+ this.log = log;
+ this.lint = lint;
+ }
+
+ @Override
+ protected AssignPendingExit createNewPendingExit(JCTree tree,
+ Bits inits, Bits uninits) {
+ return new AssignPendingExit(tree, inits, uninits);
+ }
+
+ /** Record an initialization of a trackable variable.
+ */
+ @Override
+ void letInit(DiagnosticPosition pos, VarSymbol sym) {
+ if (sym.adr >= firstadr && trackable(sym)) {
+ if ((sym.flags() & EFFECTIVELY_FINAL) != 0) {
+ if (!uninits.isMember(sym.adr)) {
+ //assignment targeting an effectively final variable
+ //makes the variable lose its status of effectively final
+ //if the variable is _not_ definitively unassigned
+ sym.flags_field &= ~EFFECTIVELY_FINAL;
+ } else {
+ uninit(sym);
+ }
+ }
+ else if ((sym.flags() & FINAL) != 0) {
+ if ((sym.flags() & PARAMETER) != 0) {
+ if ((sym.flags() & UNION) != 0) { //multi-catch parameter
+ log.error(pos, "multicatch.parameter.may.not.be.assigned", sym);
+ }
+ else {
+ log.error(pos, "final.parameter.may.not.be.assigned",
+ sym);
+ }
+ } else if (!uninits.isMember(sym.adr)) {
+ log.error(pos, flowKind.errKey, sym);
+ } else {
+ uninit(sym);
+ }
+ }
+ inits.incl(sym.adr);
+ } else if ((sym.flags() & FINAL) != 0) {
+ log.error(pos, "var.might.already.be.assigned", sym);
+ }
+ }
+
+ @Override
+ void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) {
+ if ((sym.adr >= firstadr || sym.owner.kind != TYP) &&
+ trackable(sym) &&
+ !inits.isMember(sym.adr)) {
+ log.error(pos, errkey, sym);
+ inits.incl(sym.adr);
+ }
+ }
+
+ @Override
+ void reportWarning(Lint.LintCategory lc, DiagnosticPosition pos,
+ String key, Object ... args) {
+ log.warning(lc, pos, key, args);
+ }
+
+ @Override
+ int getLogNumberOfErrors() {
+ return log.nerrors;
+ }
+
+ @Override
+ boolean isEnabled(Lint.LintCategory lc) {
+ return lint.isEnabled(lc);
+ }
+
+ @Override
+ public void visitClassDef(JCClassDecl tree) {
+ if (tree.sym == null) {
+ return;
+ }
+
+ Lint lintPrev = lint;
+ lint = lint.augment(tree.sym);
+ try {
+ super.visitClassDef(tree);
+ } finally {
+ lint = lintPrev;
+ }
+ }
+
+ @Override
+ public void visitMethodDef(JCMethodDecl tree) {
+ if (tree.body == null) {
+ return;
+ }
+
+ /* MemberEnter can generate synthetic methods ignore them
+ */
+ if ((tree.sym.flags() & SYNTHETIC) != 0) {
+ return;
+ }
+
+ Lint lintPrev = lint;
+ lint = lint.augment(tree.sym);
+ try {
+ super.visitMethodDef(tree);
+ } finally {
+ lint = lintPrev;
+ }
+ }
+
+ @Override
+ public void visitVarDef(JCVariableDecl tree) {
+ if (tree.init == null) {
+ super.visitVarDef(tree);
+ } else {
+ Lint lintPrev = lint;
+ lint = lint.augment(tree.sym);
+ try{
+ super.visitVarDef(tree);
+ } finally {
+ lint = lintPrev;
+ }
+ }
+ }
+
+ }
+
/**
* This pass implements the last step of the dataflow analysis, namely
* the effectively-final analysis check. This checks that every local variable
@@ -2334,7 +2539,7 @@
JCTree currentTree; //local class or lambda
@Override
- void markDead() {
+ void markDead(JCTree tree) {
//do nothing
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Fri Sep 20 19:15:59 2013 -0700
@@ -40,17 +40,17 @@
import com.sun.tools.javac.comp.Infer.GraphSolver.InferenceGraph.Node;
import com.sun.tools.javac.comp.Resolve.InapplicableMethodException;
import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
-
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
+import com.sun.tools.javac.util.GraphUtils.TarjanNode;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.EnumMap;
import java.util.EnumSet;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
import static com.sun.tools.javac.code.TypeTag.*;
@@ -114,6 +114,12 @@
}
@Override
+ InapplicableMethodException setMessage() {
+ //no message to set
+ return this;
+ }
+
+ @Override
InapplicableMethodException setMessage(JCDiagnostic diag) {
messages = messages.append(diag);
return this;
@@ -1006,10 +1012,24 @@
* and (ii) tell th engine when we are done fixing inference variables
*/
interface GraphStrategy {
+
+ /**
+ * A NodeNotFoundException is thrown whenever an inference strategy fails
+ * to pick the next node to solve in the inference graph.
+ */
+ public static class NodeNotFoundException extends RuntimeException {
+ private static final long serialVersionUID = 0;
+
+ InferenceGraph graph;
+
+ public NodeNotFoundException(InferenceGraph graph) {
+ this.graph = graph;
+ }
+ }
/**
* Pick the next node (leaf) to solve in the graph
*/
- Node pickNode(InferenceGraph g);
+ Node pickNode(InferenceGraph g) throws NodeNotFoundException;
/**
* Is this the last step?
*/
@@ -1022,7 +1042,10 @@
*/
abstract class LeafSolver implements GraphStrategy {
public Node pickNode(InferenceGraph g) {
- Assert.check(!g.nodes.isEmpty(), "No nodes to solve!");
+ if (g.nodes.isEmpty()) {
+ //should not happen
+ throw new NodeNotFoundException(g);
+ };
return g.nodes.get(0);
}
@@ -1069,6 +1092,7 @@
*/
abstract class BestLeafSolver extends LeafSolver {
+ /** list of ivars of which at least one must be solved */
List<Type> varsToSolve;
BestLeafSolver(List<Type> varsToSolve) {
@@ -1076,54 +1100,66 @@
}
/**
- * Computes the minimum path that goes from a given node to any of the nodes
- * containing a variable in {@code varsToSolve}. For any given path, the cost
- * is computed as the total number of type-variables that should be eagerly
- * instantiated across that path.
+ * Computes a path that goes from a given node to the leafs in the graph.
+ * Typically this will start from a node containing a variable in
+ * {@code varsToSolve}. For any given path, the cost is computed as the total
+ * number of type-variables that should be eagerly instantiated across that path.
*/
- int computeMinPath(InferenceGraph g, Node n) {
- return computeMinPath(g, n, List.<Node>nil(), 0);
+ Pair<List<Node>, Integer> computeTreeToLeafs(Node n) {
+ Pair<List<Node>, Integer> cachedPath = treeCache.get(n);
+ if (cachedPath == null) {
+ //cache miss
+ if (n.isLeaf()) {
+ //if leaf, stop
+ cachedPath = new Pair<List<Node>, Integer>(List.of(n), n.data.length());
+ } else {
+ //if non-leaf, proceed recursively
+ Pair<List<Node>, Integer> path = new Pair<List<Node>, Integer>(List.of(n), n.data.length());
+ for (Node n2 : n.getAllDependencies()) {
+ if (n2 == n) continue;
+ Pair<List<Node>, Integer> subpath = computeTreeToLeafs(n2);
+ path = new Pair<List<Node>, Integer>(
+ path.fst.prependList(subpath.fst),
+ path.snd + subpath.snd);
+ }
+ cachedPath = path;
+ }
+ //save results in cache
+ treeCache.put(n, cachedPath);
+ }
+ return cachedPath;
}
- int computeMinPath(InferenceGraph g, Node n, List<Node> path, int cost) {
- if (path.contains(n)) return Integer.MAX_VALUE;
- List<Node> path2 = path.prepend(n);
- int cost2 = cost + n.data.size();
- if (!Collections.disjoint(n.data, varsToSolve)) {
- return cost2;
- } else {
- int bestPath = Integer.MAX_VALUE;
- for (Node n2 : g.nodes) {
- if (n2.deps.contains(n)) {
- int res = computeMinPath(g, n2, path2, cost2);
- if (res < bestPath) {
- bestPath = res;
- }
- }
- }
- return bestPath;
- }
- }
+ /** cache used to avoid redundant computation of tree costs */
+ final Map<Node, Pair<List<Node>, Integer>> treeCache =
+ new HashMap<Node, Pair<List<Node>, Integer>>();
+
+ /** constant value used to mark non-existent paths */
+ final Pair<List<Node>, Integer> noPath =
+ new Pair<List<Node>, Integer>(null, Integer.MAX_VALUE);
/**
* Pick the leaf that minimize cost
*/
@Override
public Node pickNode(final InferenceGraph g) {
- final Map<Node, Integer> leavesMap = new HashMap<Node, Integer>();
+ treeCache.clear(); //graph changes at every step - cache must be cleared
+ Pair<List<Node>, Integer> bestPath = noPath;
for (Node n : g.nodes) {
- if (n.isLeaf(n)) {
- leavesMap.put(n, computeMinPath(g, n));
+ if (!Collections.disjoint(n.data, varsToSolve)) {
+ Pair<List<Node>, Integer> path = computeTreeToLeafs(n);
+ //discard all paths containing at least a node in the
+ //closure computed above
+ if (path.snd < bestPath.snd) {
+ bestPath = path;
+ }
}
}
- Assert.check(!leavesMap.isEmpty(), "No nodes to solve!");
- TreeSet<Node> orderedLeaves = new TreeSet<Node>(new Comparator<Node>() {
- public int compare(Node n1, Node n2) {
- return leavesMap.get(n1) - leavesMap.get(n2);
- }
- });
- orderedLeaves.addAll(leavesMap.keySet());
- return orderedLeaves.first();
+ if (bestPath == noPath) {
+ //no path leads there
+ throw new NodeNotFoundException(g);
+ }
+ return bestPath.fst.head;
}
}
@@ -1321,6 +1357,33 @@
}
/**
+ * There are two kinds of dependencies between inference variables. The basic
+ * kind of dependency (or bound dependency) arises when a variable mention
+ * another variable in one of its bounds. There's also a more subtle kind
+ * of dependency that arises when a variable 'might' lead to better constraints
+ * on another variable (this is typically the case with variables holding up
+ * stuck expressions).
+ */
+ enum DependencyKind implements GraphUtils.DependencyKind {
+
+ /** bound dependency */
+ BOUND("dotted"),
+ /** stuck dependency */
+ STUCK("dashed");
+
+ final String dotSyle;
+
+ private DependencyKind(String dotSyle) {
+ this.dotSyle = dotSyle;
+ }
+
+ @Override
+ public String getDotStyle() {
+ return dotSyle;
+ }
+ }
+
+ /**
* This is the graph inference solver - the solver organizes all inference variables in
* a given inference context by bound dependencies - in the general case, such dependencies
* would lead to a cyclic directed graph (hence the name); the dependency info is used to build
@@ -1331,10 +1394,12 @@
class GraphSolver {
InferenceContext inferenceContext;
+ Map<Type, Set<Type>> stuckDeps;
Warner warn;
- GraphSolver(InferenceContext inferenceContext, Warner warn) {
+ GraphSolver(InferenceContext inferenceContext, Map<Type, Set<Type>> stuckDeps, Warner warn) {
this.inferenceContext = inferenceContext;
+ this.stuckDeps = stuckDeps;
this.warn = warn;
}
@@ -1345,7 +1410,7 @@
*/
void solve(GraphStrategy sstrategy) {
checkWithinBounds(inferenceContext, warn); //initial propagation of bounds
- InferenceGraph inferenceGraph = new InferenceGraph();
+ InferenceGraph inferenceGraph = new InferenceGraph(stuckDeps);
while (!sstrategy.done()) {
InferenceGraph.Node nodeToSolve = sstrategy.pickNode(inferenceGraph);
List<Type> varsToSolve = List.from(nodeToSolve.data);
@@ -1390,64 +1455,172 @@
*/
class Node extends GraphUtils.TarjanNode<ListBuffer<Type>> {
- Set<Node> deps;
+ /** map listing all dependencies (grouped by kind) */
+ EnumMap<DependencyKind, Set<Node>> deps;
Node(Type ivar) {
super(ListBuffer.of(ivar));
- this.deps = new HashSet<Node>();
+ this.deps = new EnumMap<DependencyKind, Set<Node>>(DependencyKind.class);
+ }
+
+ @Override
+ public GraphUtils.DependencyKind[] getSupportedDependencyKinds() {
+ return DependencyKind.values();
}
@Override
- public Iterable<? extends Node> getDependencies() {
- return deps;
+ public String getDependencyName(GraphUtils.Node<ListBuffer<Type>> to, GraphUtils.DependencyKind dk) {
+ if (dk == DependencyKind.STUCK) return "";
+ else {
+ StringBuilder buf = new StringBuilder();
+ String sep = "";
+ for (Type from : data) {
+ UndetVar uv = (UndetVar)inferenceContext.asFree(from);
+ for (Type bound : uv.getBounds(InferenceBound.values())) {
+ if (bound.containsAny(List.from(to.data))) {
+ buf.append(sep);
+ buf.append(bound);
+ sep = ",";
+ }
+ }
+ }
+ return buf.toString();
+ }
+ }
+
+ @Override
+ public Iterable<? extends Node> getAllDependencies() {
+ return getDependencies(DependencyKind.values());
}
@Override
- public String printDependency(GraphUtils.Node<ListBuffer<Type>> to) {
- StringBuilder buf = new StringBuilder();
- String sep = "";
- for (Type from : data) {
- UndetVar uv = (UndetVar)inferenceContext.asFree(from);
- for (Type bound : uv.getBounds(InferenceBound.values())) {
- if (bound.containsAny(List.from(to.data))) {
- buf.append(sep);
- buf.append(bound);
- sep = ",";
- }
+ public Iterable<? extends TarjanNode<ListBuffer<Type>>> getDependenciesByKind(GraphUtils.DependencyKind dk) {
+ return getDependencies((DependencyKind)dk);
+ }
+
+ /**
+ * Retrieves all dependencies with given kind(s).
+ */
+ protected Set<Node> getDependencies(DependencyKind... depKinds) {
+ Set<Node> buf = new LinkedHashSet<Node>();
+ for (DependencyKind dk : depKinds) {
+ Set<Node> depsByKind = deps.get(dk);
+ if (depsByKind != null) {
+ buf.addAll(depsByKind);
}
}
- return buf.toString();
+ return buf;
+ }
+
+ /**
+ * Adds dependency with given kind.
+ */
+ protected void addDependency(DependencyKind dk, Node depToAdd) {
+ Set<Node> depsByKind = deps.get(dk);
+ if (depsByKind == null) {
+ depsByKind = new LinkedHashSet<Node>();
+ deps.put(dk, depsByKind);
+ }
+ depsByKind.add(depToAdd);
+ }
+
+ /**
+ * Add multiple dependencies of same given kind.
+ */
+ protected void addDependencies(DependencyKind dk, Set<Node> depsToAdd) {
+ for (Node n : depsToAdd) {
+ addDependency(dk, n);
+ }
+ }
+
+ /**
+ * Remove a dependency, regardless of its kind.
+ */
+ protected Set<DependencyKind> removeDependency(Node n) {
+ Set<DependencyKind> removedKinds = new HashSet<>();
+ for (DependencyKind dk : DependencyKind.values()) {
+ Set<Node> depsByKind = deps.get(dk);
+ if (depsByKind == null) continue;
+ if (depsByKind.remove(n)) {
+ removedKinds.add(dk);
+ }
+ }
+ return removedKinds;
}
- boolean isLeaf(Node n) {
- //no deps, or only one self dep
- return (n.deps.isEmpty() ||
- n.deps.size() == 1 && n.deps.contains(n));
+ /**
+ * Compute closure of a give node, by recursively walking
+ * through all its dependencies (of given kinds)
+ */
+ protected Set<Node> closure(DependencyKind... depKinds) {
+ boolean progress = true;
+ Set<Node> closure = new HashSet<Node>();
+ closure.add(this);
+ while (progress) {
+ progress = false;
+ for (Node n1 : new HashSet<Node>(closure)) {
+ progress = closure.addAll(n1.getDependencies(depKinds));
+ }
+ }
+ return closure;
}
- void mergeWith(List<? extends Node> nodes) {
+ /**
+ * Is this node a leaf? This means either the node has no dependencies,
+ * or it just has self-dependencies.
+ */
+ protected boolean isLeaf() {
+ //no deps, or only one self dep
+ Set<Node> allDeps = getDependencies(DependencyKind.BOUND, DependencyKind.STUCK);
+ if (allDeps.isEmpty()) return true;
+ for (Node n : allDeps) {
+ if (n != this) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Merge this node with another node, acquiring its dependencies.
+ * This routine is used to merge all cyclic node together and
+ * form an acyclic graph.
+ */
+ protected void mergeWith(List<? extends Node> nodes) {
for (Node n : nodes) {
Assert.check(n.data.length() == 1, "Attempt to merge a compound node!");
data.appendList(n.data);
- deps.addAll(n.deps);
+ for (DependencyKind dk : DependencyKind.values()) {
+ addDependencies(dk, n.getDependencies(dk));
+ }
}
//update deps
- Set<Node> deps2 = new HashSet<Node>();
- for (Node d : deps) {
- if (data.contains(d.data.first())) {
- deps2.add(this);
- } else {
- deps2.add(d);
+ EnumMap<DependencyKind, Set<Node>> deps2 = new EnumMap<DependencyKind, Set<Node>>(DependencyKind.class);
+ for (DependencyKind dk : DependencyKind.values()) {
+ for (Node d : getDependencies(dk)) {
+ Set<Node> depsByKind = deps2.get(dk);
+ if (depsByKind == null) {
+ depsByKind = new LinkedHashSet<Node>();
+ deps2.put(dk, depsByKind);
+ }
+ if (data.contains(d.data.first())) {
+ depsByKind.add(this);
+ } else {
+ depsByKind.add(d);
+ }
}
}
deps = deps2;
}
- void graphChanged(Node from, Node to) {
- if (deps.contains(from)) {
- deps.remove(from);
+ /**
+ * Notify all nodes that something has changed in the graph
+ * topology.
+ */
+ private void graphChanged(Node from, Node to) {
+ for (DependencyKind dk : removeDependency(from)) {
if (to != null) {
- deps.add(to);
+ addDependency(dk, to);
}
}
}
@@ -1456,8 +1629,21 @@
/** the nodes in the inference graph */
ArrayList<Node> nodes;
- InferenceGraph() {
- initNodes();
+ InferenceGraph(Map<Type, Set<Type>> optDeps) {
+ initNodes(optDeps);
+ }
+
+ /**
+ * Basic lookup helper for retrieving a graph node given an inference
+ * variable type.
+ */
+ public Node findNode(Type t) {
+ for (Node n : nodes) {
+ if (n.data.contains(t)) {
+ return n;
+ }
+ }
+ return null;
}
/**
@@ -1484,24 +1670,32 @@
* Create the graph nodes. First a simple node is created for every inference
* variables to be solved. Then Tarjan is used to found all connected components
* in the graph. For each component containing more than one node, a super node is
- * created, effectively replacing the original cyclic nodes.
+ * created, effectively replacing the original cyclic nodes.
*/
- void initNodes() {
+ void initNodes(Map<Type, Set<Type>> stuckDeps) {
+ //add nodes
nodes = new ArrayList<Node>();
for (Type t : inferenceContext.restvars()) {
nodes.add(new Node(t));
}
+ //add dependencies
for (Node n_i : nodes) {
Type i = n_i.data.first();
+ Set<Type> optDepsByNode = stuckDeps.get(i);
for (Node n_j : nodes) {
Type j = n_j.data.first();
UndetVar uv_i = (UndetVar)inferenceContext.asFree(i);
if (Type.containsAny(uv_i.getBounds(InferenceBound.values()), List.of(j))) {
- //update i's deps
- n_i.deps.add(n_j);
+ //update i's bound dependencies
+ n_i.addDependency(DependencyKind.BOUND, n_j);
+ }
+ if (optDepsByNode != null && optDepsByNode.contains(j)) {
+ //update i's stuck dependencies
+ n_i.addDependency(DependencyKind.STUCK, n_j);
}
}
}
+ //merge cyclic nodes
ArrayList<Node> acyclicNodes = new ArrayList<Node>();
for (List<? extends Node> conSubGraph : GraphUtils.tarjan(nodes)) {
if (conSubGraph.length() > 1) {
@@ -1631,8 +1825,8 @@
return filterVars(new Filter<UndetVar>() {
public boolean accepts(UndetVar uv) {
return uv.getBounds(InferenceBound.UPPER)
- .diff(uv.getDeclaredBounds())
- .appendList(uv.getBounds(InferenceBound.EQ, InferenceBound.LOWER)).nonEmpty();
+ .diff(uv.getDeclaredBounds())
+ .appendList(uv.getBounds(InferenceBound.EQ, InferenceBound.LOWER)).nonEmpty();
}
});
}
@@ -1822,11 +2016,15 @@
}
}
+ private void solve(GraphStrategy ss, Warner warn) {
+ solve(ss, new HashMap<Type, Set<Type>>(), warn);
+ }
+
/**
* Solve with given graph strategy.
*/
- private void solve(GraphStrategy ss, Warner warn) {
- GraphSolver s = new GraphSolver(this, warn);
+ private void solve(GraphStrategy ss, Map<Type, Set<Type>> stuckDeps, Warner warn) {
+ GraphSolver s = new GraphSolver(this, stuckDeps, warn);
s.solve(ss);
}
@@ -1855,18 +2053,12 @@
/**
* Solve at least one variable in given list.
*/
- public void solveAny(List<Type> varsToSolve, Warner warn) {
- checkWithinBounds(this, warn); //propagate bounds
- List<Type> boundedVars = boundedVars().intersect(restvars()).intersect(varsToSolve);
- if (boundedVars.isEmpty()) {
- throw inferenceException.setMessage("cyclic.inference",
- freeVarsIn(varsToSolve));
- }
- solve(new BestLeafSolver(boundedVars) {
+ public void solveAny(List<Type> varsToSolve, Map<Type, Set<Type>> optDeps, Warner warn) {
+ solve(new BestLeafSolver(varsToSolve.intersect(restvars())) {
public boolean done() {
return instvars().intersect(varsToSolve).nonEmpty();
}
- }, warn);
+ }, optDeps, warn);
}
/**
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Fri Sep 20 19:15:59 2013 -0700
@@ -1745,6 +1745,11 @@
// Just erase the type var
ret = new VarSymbol(sym.flags(), name,
types.erasure(sym.type), sym.owner);
+
+ /* this information should also be kept for LVT generation at Gen
+ * a Symbol with pos < startPos won't be tracked.
+ */
+ ((VarSymbol)ret).pos = ((VarSymbol)sym).pos;
break;
case CAPTURED_VAR:
ret = new VarSymbol(SYNTHETIC | FINAL, name, types.erasure(sym.type), translatedSym) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Fri Sep 20 19:15:59 2013 -0700
@@ -49,7 +49,6 @@
import static com.sun.tools.javac.code.TypeTag.*;
import static com.sun.tools.javac.jvm.ByteCodes.*;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
-import javax.lang.model.type.TypeKind;
/** This pass translates away some syntactic sugar: inner classes,
* class literals, assertions, foreach loops, etc.
@@ -1480,7 +1479,12 @@
* @param owner The class in which the definitions go.
*/
List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner) {
- long flags = FINAL | SYNTHETIC;
+ return freevarDefs(pos, freevars, owner, 0);
+ }
+
+ List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner,
+ long additionalFlags) {
+ long flags = FINAL | SYNTHETIC | additionalFlags;
if (owner.kind == TYP &&
target.usePrivateSyntheticFields())
flags |= PRIVATE;
@@ -1543,7 +1547,7 @@
(owner.isConstructor() && c.isInner() &&
!c.isPrivate() && !c.isStatic());
long flags =
- FINAL | (isMandated ? MANDATED : SYNTHETIC);
+ FINAL | (isMandated ? MANDATED : SYNTHETIC) | PARAMETER;
VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
owner.extraParams = owner.extraParams.prepend(outerThis);
return makeOuterThisVarDecl(pos, outerThis);
@@ -1627,7 +1631,8 @@
JCTree makeTwrTry(JCTry tree) {
make_at(tree.pos());
twrVars = twrVars.dup();
- JCBlock twrBlock = makeTwrBlock(tree.resources, tree.body, 0);
+ JCBlock twrBlock = makeTwrBlock(tree.resources, tree.body,
+ tree.finallyCanCompleteNormally, 0);
if (tree.catchers.isEmpty() && tree.finalizer == null)
result = translate(twrBlock);
else
@@ -1636,7 +1641,8 @@
return result;
}
- private JCBlock makeTwrBlock(List<JCTree> resources, JCBlock block, int depth) {
+ private JCBlock makeTwrBlock(List<JCTree> resources, JCBlock block,
+ boolean finallyCanCompleteNormally, int depth) {
if (resources.isEmpty())
return block;
@@ -1692,17 +1698,20 @@
make.at(TreeInfo.endPos(block));
JCBlock finallyClause = makeTwrFinallyClause(primaryException, expr);
make.at(oldPos);
- JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block, depth + 1),
+ JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block,
+ finallyCanCompleteNormally, depth + 1),
List.<JCCatch>of(catchClause),
finallyClause);
+ outerTry.finallyCanCompleteNormally = finallyCanCompleteNormally;
stats.add(outerTry);
- return make.Block(0L, stats.toList());
+ JCBlock newBlock = make.Block(0L, stats.toList());
+ return newBlock;
}
private JCBlock makeTwrFinallyClause(Symbol primaryException, JCExpression resource) {
// primaryException.addSuppressed(catchException);
VarSymbol catchException =
- new VarSymbol(0, make.paramName(2),
+ new VarSymbol(SYNTHETIC, make.paramName(2),
syms.throwableType,
currentMethodSym);
JCStatement addSuppressionStatement =
@@ -1717,6 +1726,7 @@
JCBlock catchBlock = make.Block(0L, List.<JCStatement>of(addSuppressionStatement));
List<JCCatch> catchClauses = List.<JCCatch>of(make.Catch(catchExceptionDecl, catchBlock));
JCTry tryTree = make.Try(tryBlock, catchClauses, null);
+ tryTree.finallyCanCompleteNormally = true;
// if (primaryException != null) {try...} else resourceClose;
JCIf closeIfStatement = make.If(makeNonNullCheck(make.Ident(primaryException)),
@@ -2017,7 +2027,7 @@
// catchParam := ClassNotFoundException e1
VarSymbol catchParam =
- new VarSymbol(0, make.paramName(1),
+ new VarSymbol(SYNTHETIC, make.paramName(1),
syms.classNotFoundExceptionType,
classDollarSym);
@@ -2705,7 +2715,7 @@
JCVariableDecl otdef = null;
if (currentClass.hasOuterInstance())
otdef = outerThisDef(tree.pos, m);
- List<JCVariableDecl> fvdefs = freevarDefs(tree.pos, fvs, m);
+ List<JCVariableDecl> fvdefs = freevarDefs(tree.pos, fvs, m, PARAMETER);
// Recursively translate result type, parameters and thrown list.
tree.restype = translate(tree.restype);
@@ -3364,18 +3374,18 @@
*/
private void visitArrayForeachLoop(JCEnhancedForLoop tree) {
make_at(tree.expr.pos());
- VarSymbol arraycache = new VarSymbol(0,
+ VarSymbol arraycache = new VarSymbol(SYNTHETIC,
names.fromString("arr" + target.syntheticNameChar()),
tree.expr.type,
currentMethodSym);
JCStatement arraycachedef = make.VarDef(arraycache, tree.expr);
- VarSymbol lencache = new VarSymbol(0,
+ VarSymbol lencache = new VarSymbol(SYNTHETIC,
names.fromString("len" + target.syntheticNameChar()),
syms.intType,
currentMethodSym);
JCStatement lencachedef = make.
VarDef(lencache, make.Select(make.Ident(arraycache), syms.lengthVar));
- VarSymbol index = new VarSymbol(0,
+ VarSymbol index = new VarSymbol(SYNTHETIC,
names.fromString("i" + target.syntheticNameChar()),
syms.intType,
currentMethodSym);
@@ -3457,7 +3467,7 @@
names.iterator,
eType,
List.<Type>nil());
- VarSymbol itvar = new VarSymbol(0, names.fromString("i" + target.syntheticNameChar()),
+ VarSymbol itvar = new VarSymbol(SYNTHETIC, names.fromString("i" + target.syntheticNameChar()),
types.erasure(types.asSuper(iterator.type.getReturnType(), syms.iteratorType.tsym)),
currentMethodSym);
@@ -3830,19 +3840,32 @@
@Override
public void visitTry(JCTry tree) {
- /* special case of try without catchers and with finally emtpy.
- * Don't give it a try, translate only the body.
- */
- if (tree.resources.isEmpty()) {
- if (tree.catchers.isEmpty() &&
- tree.finalizer.getStatements().isEmpty()) {
+ if (tree.resources.nonEmpty()) {
+ result = makeTwrTry(tree);
+ return;
+ }
+
+ boolean hasBody = tree.body.getStatements().nonEmpty();
+ boolean hasCatchers = tree.catchers.nonEmpty();
+ boolean hasFinally = tree.finalizer != null &&
+ tree.finalizer.getStatements().nonEmpty();
+
+ if (!hasCatchers && !hasFinally) {
+ result = translate(tree.body);
+ return;
+ }
+
+ if (!hasBody) {
+ if (hasFinally) {
+ result = translate(tree.finalizer);
+ } else {
result = translate(tree.body);
- } else {
- super.visitTry(tree);
}
- } else {
- result = makeTwrTry(tree);
+ return;
}
+
+ // no optimizations possible
+ super.visitTry(tree);
}
/**************************************************************************
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Fri Sep 20 19:15:59 2013 -0700
@@ -84,6 +84,7 @@
private final Source source;
private final Target target;
private final DeferredLintHandler deferredLintHandler;
+ private final Lint lint;
public static MemberEnter instance(Context context) {
MemberEnter instance = context.get(memberEnterKey);
@@ -109,6 +110,7 @@
source = Source.instance(context);
target = Target.instance(context);
deferredLintHandler = DeferredLintHandler.instance(context);
+ lint = Lint.instance(context);
allowTypeAnnos = source.allowTypeAnnotations();
}
@@ -506,9 +508,10 @@
}
// process package annotations
- annotateLater(tree.packageAnnotations, env, tree.packge);
+ annotateLater(tree.packageAnnotations, env, tree.packge, null);
- DeferredLintHandler prevLintHandler = chk.setDeferredLintHandler(DeferredLintHandler.immediateHandler);
+ DiagnosticPosition prevLintPos = deferredLintHandler.immediate();
+ Lint prevLint = chk.setLint(lint);
try {
// Import-on-demand java.lang.
@@ -517,7 +520,8 @@
// Process all import clauses.
memberEnter(tree.defs, env);
} finally {
- chk.setDeferredLintHandler(prevLintHandler);
+ chk.setLint(prevLint);
+ deferredLintHandler.setPos(prevLintPos);
}
}
@@ -564,8 +568,7 @@
Env<AttrContext> localEnv = methodEnv(tree, env);
- DeferredLintHandler prevLintHandler =
- chk.setDeferredLintHandler(deferredLintHandler.setPos(tree.pos()));
+ DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
try {
// Compute the method type
m.type = signature(m, tree.typarams, tree.params,
@@ -573,7 +576,7 @@
tree.thrown,
localEnv);
} finally {
- chk.setDeferredLintHandler(prevLintHandler);
+ deferredLintHandler.setPos(prevLintPos);
}
if (types.isSignaturePolymorphic(m)) {
@@ -597,10 +600,10 @@
if (chk.checkUnique(tree.pos(), m, enclScope)) {
enclScope.enter(m);
}
- annotateLater(tree.mods.annotations, localEnv, m);
+ annotateLater(tree.mods.annotations, localEnv, m, tree.pos());
// Visit the signature of the method. Note that
// TypeAnnotate doesn't descend into the body.
- typeAnnotate(tree, localEnv, m);
+ typeAnnotate(tree, localEnv, m, tree.pos());
if (tree.defaultValue != null)
annotateDefaultValueLater(tree.defaultValue, localEnv, m);
@@ -630,15 +633,14 @@
localEnv = env.dup(tree, env.info.dup());
localEnv.info.staticLevel++;
}
- DeferredLintHandler prevLintHandler =
- chk.setDeferredLintHandler(deferredLintHandler.setPos(tree.pos()));
+ DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
try {
if (TreeInfo.isEnumInit(tree)) {
attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype);
} else {
// Make sure type annotations are processed.
// But we don't have a symbol to attach them to yet - use null.
- typeAnnotate(tree.vartype, env, null);
+ typeAnnotate(tree.vartype, env, null, tree.pos());
attr.attribType(tree.vartype, localEnv);
if (tree.nameexpr != null) {
attr.attribExpr(tree.nameexpr, localEnv);
@@ -658,7 +660,7 @@
}
}
} finally {
- chk.setDeferredLintHandler(prevLintHandler);
+ deferredLintHandler.setPos(prevLintPos);
}
if ((tree.mods.flags & VARARGS) != 0) {
@@ -680,15 +682,15 @@
needsLazyConstValue(tree.init)) {
Env<AttrContext> initEnv = getInitEnv(tree, env);
initEnv.info.enclVar = v;
- v.setLazyConstValue(initEnv(tree, initEnv), attr, tree.init);
+ v.setLazyConstValue(initEnv(tree, initEnv), attr, tree);
}
}
if (chk.checkUnique(tree.pos(), v, enclScope)) {
chk.checkTransparentVar(tree.pos(), v, enclScope);
enclScope.enter(v);
}
- annotateLater(tree.mods.annotations, localEnv, v);
- typeAnnotate(tree.vartype, env, v);
+ annotateLater(tree.mods.annotations, localEnv, v, tree.pos());
+ typeAnnotate(tree.vartype, env, v, tree.pos());
annotate.flush();
v.pos = tree.pos;
}
@@ -720,6 +722,11 @@
}
@Override
+ public void visitNewArray(JCNewArray that) {
+ result = false;
+ }
+
+ @Override
public void visitLambda(JCLambda that) {
result = false;
}
@@ -730,6 +737,11 @@
}
@Override
+ public void visitApply(JCMethodInvocation that) {
+ result = false;
+ }
+
+ @Override
public void visitSelect(JCFieldAccess tree) {
tree.selected.accept(this);
}
@@ -820,7 +832,8 @@
/** Queue annotations for later processing. */
void annotateLater(final List<JCAnnotation> annotations,
final Env<AttrContext> localEnv,
- final Symbol s) {
+ final Symbol s,
+ final DiagnosticPosition deferPos) {
if (annotations.isEmpty()) {
return;
}
@@ -837,6 +850,11 @@
public void enterAnnotation() {
Assert.check(s.kind == PCK || s.annotationsPendingCompletion());
JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
+ DiagnosticPosition prevLintPos =
+ deferPos != null
+ ? deferredLintHandler.setPos(deferPos)
+ : deferredLintHandler.immediate();
+ Lint prevLint = deferPos != null ? null : chk.setLint(lint);
try {
if (s.hasAnnotations() &&
annotations.nonEmpty())
@@ -845,6 +863,9 @@
kindName(s), s);
actualEnterAnnotations(annotations, localEnv, s);
} finally {
+ if (prevLint != null)
+ chk.setLint(prevLint);
+ deferredLintHandler.setPos(prevLintPos);
log.useSource(prev);
}
}
@@ -964,6 +985,7 @@
isFirst = false;
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
+ DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
try {
// Save class environment for later member enter (2) processing.
halfcompleted.append(env);
@@ -985,9 +1007,9 @@
Env<AttrContext> baseEnv = baseEnv(tree, env);
if (tree.extending != null)
- typeAnnotate(tree.extending, baseEnv, sym);
+ typeAnnotate(tree.extending, baseEnv, sym, tree.pos());
for (JCExpression impl : tree.implementing)
- typeAnnotate(impl, baseEnv, sym);
+ typeAnnotate(impl, baseEnv, sym, tree.pos());
annotate.flush();
// Determine supertype.
@@ -1048,7 +1070,7 @@
attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
if (hasDeprecatedAnnotation(tree.mods.annotations))
c.flags_field |= DEPRECATED;
- annotateLater(tree.mods.annotations, baseEnv, c);
+ annotateLater(tree.mods.annotations, baseEnv, c, tree.pos());
// class type parameters use baseEnv but everything uses env
chk.checkNonCyclicDecl(tree);
@@ -1056,7 +1078,7 @@
attr.attribTypeVariables(tree.typarams, baseEnv);
// Do this here, where we have the symbol.
for (JCTypeParameter tp : tree.typarams)
- typeAnnotate(tp, baseEnv, sym);
+ typeAnnotate(tp, baseEnv, sym, tree.pos());
annotate.flush();
// Add default constructor if needed.
@@ -1126,6 +1148,7 @@
} catch (CompletionFailure ex) {
chk.completionError(tree.pos(), ex);
} finally {
+ deferredLintHandler.setPos(prevLintPos);
log.useSource(prev);
}
@@ -1186,9 +1209,9 @@
}
}
- public void typeAnnotate(final JCTree tree, final Env<AttrContext> env, final Symbol sym) {
+ public void typeAnnotate(final JCTree tree, final Env<AttrContext> env, final Symbol sym, DiagnosticPosition deferPos) {
if (allowTypeAnnos) {
- tree.accept(new TypeAnnotate(env, sym));
+ tree.accept(new TypeAnnotate(env, sym, deferPos));
}
}
@@ -1199,10 +1222,12 @@
private class TypeAnnotate extends TreeScanner {
private Env<AttrContext> env;
private Symbol sym;
+ private DiagnosticPosition deferPos;
- public TypeAnnotate(final Env<AttrContext> env, final Symbol sym) {
+ public TypeAnnotate(final Env<AttrContext> env, final Symbol sym, DiagnosticPosition deferPos) {
this.env = env;
this.sym = sym;
+ this.deferPos = deferPos;
}
void annotateTypeLater(final List<JCAnnotation> annotations) {
@@ -1210,6 +1235,8 @@
return;
}
+ final DiagnosticPosition deferPos = this.deferPos;
+
annotate.normal(new Annotate.Annotator() {
@Override
public String toString() {
@@ -1218,9 +1245,16 @@
@Override
public void enterAnnotation() {
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
+ DiagnosticPosition prevLintPos = null;
+
+ if (deferPos != null) {
+ prevLintPos = deferredLintHandler.setPos(deferPos);
+ }
try {
actualEnterTypeAnnotations(annotations, env, sym);
} finally {
+ if (prevLintPos != null)
+ deferredLintHandler.setPos(prevLintPos);
log.useSource(prev);
}
}
@@ -1262,13 +1296,19 @@
@Override
public void visitVarDef(final JCVariableDecl tree) {
- if (sym != null && sym.kind == Kinds.VAR) {
- // Don't visit a parameter once when the sym is the method
- // and once when the sym is the parameter.
- scan(tree.mods);
- scan(tree.vartype);
+ DiagnosticPosition prevPos = deferPos;
+ deferPos = tree.pos();
+ try {
+ if (sym != null && sym.kind == Kinds.VAR) {
+ // Don't visit a parameter once when the sym is the method
+ // and once when the sym is the parameter.
+ scan(tree.mods);
+ scan(tree.vartype);
+ }
+ scan(tree.init);
+ } finally {
+ deferPos = prevPos;
}
- scan(tree.init);
}
@Override
@@ -1532,7 +1572,7 @@
* parameters from baseInit.
*/
initParams = List.nil();
- VarSymbol param = new VarSymbol(0, make.paramName(0), argtypes.head, init);
+ VarSymbol param = new VarSymbol(PARAMETER, make.paramName(0), argtypes.head, init);
initParams = initParams.append(param);
argTypesList = argTypesList.tail;
}
@@ -1541,7 +1581,7 @@
initParams = (initParams == null) ? List.<VarSymbol>nil() : initParams;
List<VarSymbol> baseInitParams = baseInit.params;
while (baseInitParams.nonEmpty() && argTypesList.nonEmpty()) {
- VarSymbol param = new VarSymbol(baseInitParams.head.flags(),
+ VarSymbol param = new VarSymbol(baseInitParams.head.flags() | PARAMETER,
baseInitParams.head.name, argTypesList.head, init);
initParams = initParams.append(param);
baseInitParams = baseInitParams.tail;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Sep 20 19:15:59 2013 -0700
@@ -568,8 +568,10 @@
currentResolutionContext,
warn);
- currentResolutionContext.methodCheck.argumentsAcceptable(env, currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn),
+ DeferredAttr.DeferredAttrContext dc = currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn);
+ currentResolutionContext.methodCheck.argumentsAcceptable(env, dc,
argtypes, mt.getParameterTypes(), warn);
+ dc.complete();
return mt;
}
@@ -1053,7 +1055,8 @@
DeferredType dt = (DeferredType) actual;
DeferredType.SpeculativeCache.Entry e = dt.speculativeCache.get(deferredAttrContext.msym, deferredAttrContext.phase);
return (e == null || e.speculativeTree == deferredAttr.stuckTree)
- ? false : mostSpecific(found, req, e.speculativeTree, warn);
+ ? super.compatible(found, req, warn) :
+ mostSpecific(found, req, e.speculativeTree, warn);
default:
return standaloneMostSpecific(found, req, actual, warn);
}
@@ -1125,13 +1128,15 @@
@Override
public void visitReference(JCMemberReference tree) {
if (types.isFunctionalInterface(t.tsym) &&
- types.isFunctionalInterface(s.tsym) &&
- types.asSuper(t, s.tsym) == null &&
- types.asSuper(s, t.tsym) == null) {
+ types.isFunctionalInterface(s.tsym)) {
Type desc_t = types.findDescriptorType(t);
Type desc_s = types.findDescriptorType(s);
- if (types.isSameTypes(desc_t.getParameterTypes(), desc_s.getParameterTypes())) {
- if (!desc_s.getReturnType().hasTag(VOID)) {
+ if (types.isSameTypes(desc_t.getParameterTypes(),
+ inferenceContext().asFree(desc_s.getParameterTypes()))) {
+ if (types.asSuper(t, s.tsym) != null ||
+ types.asSuper(s, t.tsym) != null) {
+ result &= MostSpecificCheckContext.super.compatible(t, s, warn);
+ } else if (!desc_s.getReturnType().hasTag(VOID)) {
//perform structural comparison
Type ret_t = desc_t.getReturnType();
Type ret_s = desc_s.getReturnType();
@@ -1141,25 +1146,24 @@
} else {
return;
}
- } else {
- result &= false;
}
} else {
- result &= MostSpecificCheckContext.super.compatible(t, s, warn);
+ result &= false;
}
}
@Override
public void visitLambda(JCLambda tree) {
if (types.isFunctionalInterface(t.tsym) &&
- types.isFunctionalInterface(s.tsym) &&
- types.asSuper(t, s.tsym) == null &&
- types.asSuper(s, t.tsym) == null) {
+ types.isFunctionalInterface(s.tsym)) {
Type desc_t = types.findDescriptorType(t);
Type desc_s = types.findDescriptorType(s);
- if (tree.paramKind == JCLambda.ParameterKind.EXPLICIT
- || types.isSameTypes(desc_t.getParameterTypes(), desc_s.getParameterTypes())) {
- if (!desc_s.getReturnType().hasTag(VOID)) {
+ if (types.isSameTypes(desc_t.getParameterTypes(),
+ inferenceContext().asFree(desc_s.getParameterTypes()))) {
+ if (types.asSuper(t, s.tsym) != null ||
+ types.asSuper(s, t.tsym) != null) {
+ result &= MostSpecificCheckContext.super.compatible(t, s, warn);
+ } else if (!desc_s.getReturnType().hasTag(VOID)) {
//perform structural comparison
Type ret_t = desc_t.getReturnType();
Type ret_s = desc_s.getReturnType();
@@ -1167,11 +1171,9 @@
} else {
return;
}
- } else {
- result &= false;
}
} else {
- result &= MostSpecificCheckContext.super.compatible(t, s, warn);
+ result &= false;
}
}
//where
@@ -1521,7 +1523,8 @@
currentResolutionContext = prevResolutionContext;
}
}
- private List<Type> adjustArgs(List<Type> args, Symbol msym, int length, boolean allowVarargs) {
+
+ List<Type> adjustArgs(List<Type> args, Symbol msym, int length, boolean allowVarargs) {
if ((msym.flags() & VARARGS) != 0 && allowVarargs) {
Type varargsElem = types.elemtype(args.last());
if (varargsElem == null) {
@@ -2241,33 +2244,33 @@
public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
return (syms.operatorNames.contains(name)) ?
argtypes :
- Type.map(argtypes, new ResolveDeferredRecoveryMap(accessedSym));
- }
-
- class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap {
-
- public ResolveDeferredRecoveryMap(Symbol msym) {
- deferredAttr.super(AttrMode.SPECULATIVE, msym, currentResolutionContext.step);
- }
-
- @Override
- protected Type typeOf(DeferredType dt) {
- Type res = super.typeOf(dt);
- if (!res.isErroneous()) {
- switch (TreeInfo.skipParens(dt.tree).getTag()) {
- case LAMBDA:
- case REFERENCE:
- return dt;
- case CONDEXPR:
- return res == Type.recoveryType ?
- dt : res;
- }
- }
- return res;
- }
+ Type.map(argtypes, new ResolveDeferredRecoveryMap(AttrMode.SPECULATIVE, accessedSym, currentResolutionContext.step));
}
};
+ class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap {
+
+ public ResolveDeferredRecoveryMap(AttrMode mode, Symbol msym, MethodResolutionPhase step) {
+ deferredAttr.super(mode, msym, step);
+ }
+
+ @Override
+ protected Type typeOf(DeferredType dt) {
+ Type res = super.typeOf(dt);
+ if (!res.isErroneous()) {
+ switch (TreeInfo.skipParens(dt.tree).getTag()) {
+ case LAMBDA:
+ case REFERENCE:
+ return dt;
+ case CONDEXPR:
+ return res == Type.recoveryType ?
+ dt : res;
+ }
+ }
+ return res;
+ }
+ }
+
/** Check that sym is not an abstract method.
*/
void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
@@ -2543,22 +2546,26 @@
@Override
Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
if (sym.kind >= AMBIGUOUS) {
- final JCDiagnostic details = sym.kind == WRONG_MTH ?
- ((InapplicableSymbolError)sym).errCandidate().snd :
- null;
- sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) {
- @Override
- JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
- Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
- String key = details == null ?
- "cant.apply.diamond" :
- "cant.apply.diamond.1";
- return diags.create(dkind, log.currentSource(), pos, key,
- diags.fragment("diamond", site.tsym), details);
- }
- };
- sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
- env.info.pendingResolutionPhase = currentResolutionContext.step;
+ if (sym.kind != WRONG_MTH && sym.kind != WRONG_MTHS) {
+ sym = super.access(env, pos, location, sym);
+ } else {
+ final JCDiagnostic details = sym.kind == WRONG_MTH ?
+ ((InapplicableSymbolError)sym).errCandidate().snd :
+ null;
+ sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) {
+ @Override
+ JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
+ Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
+ String key = details == null ?
+ "cant.apply.diamond" :
+ "cant.apply.diamond.1";
+ return diags.create(dkind, log.currentSource(), pos, key,
+ diags.fragment("diamond", site.tsym), details);
+ }
+ };
+ sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
+ env.info.pendingResolutionPhase = currentResolutionContext.step;
+ }
}
return sym;
}});
@@ -3969,16 +3976,6 @@
static {
String argMismatchRegex = MethodCheckDiag.ARG_MISMATCH.regex();
- rewriters.put(new Template(argMismatchRegex, new Template("(.*)(bad.arg.types.in.lambda)", skip, skip)),
- new DiagnosticRewriter() {
- @Override
- public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
- DiagnosticPosition preferedPos, DiagnosticSource preferredSource,
- DiagnosticType preferredKind, JCDiagnostic d) {
- return (JCDiagnostic)((JCDiagnostic)d.getArgs()[0]).getArgs()[1];
- }
- });
-
rewriters.put(new Template(argMismatchRegex, skip),
new DiagnosticRewriter() {
@Override
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Fri Sep 20 19:15:59 2013 -0700
@@ -310,7 +310,7 @@
Type.MethodType mType = (Type.MethodType)bridgeType;
List<Type> argTypes = mType.argtypes;
while (implParams.nonEmpty() && argTypes.nonEmpty()) {
- VarSymbol param = new VarSymbol(implParams.head.flags() | SYNTHETIC,
+ VarSymbol param = new VarSymbol(implParams.head.flags() | SYNTHETIC | PARAMETER,
implParams.head.name, argTypes.head, bridge);
param.setAttributes(implParams.head);
bridgeParams = bridgeParams.append(param);
@@ -833,7 +833,7 @@
}
public void visitReference(JCMemberReference tree) {
- tree.expr = translate(tree.expr, null);
+ tree.expr = translate(tree.expr, erasure(tree.expr.type));
tree.type = erasure(tree.type);
result = tree;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Sep 20 19:15:59 2013 -0700
@@ -72,7 +72,7 @@
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
-public class ClassReader implements Completer {
+public class ClassReader {
/** The context key for the class reader. */
protected static final Context.Key<ClassReader> classReaderKey =
new Context.Key<ClassReader>();
@@ -234,6 +234,17 @@
*/
Set<Name> warnedAttrs = new HashSet<Name>();
+ /**
+ * Completer that delegates to the complete-method of this class.
+ */
+ private final Completer thisCompleter = new Completer() {
+ @Override
+ public void complete(Symbol sym) throws CompletionFailure {
+ ClassReader.this.complete(sym);
+ }
+ };
+
+
/** Get the ClassReader instance for this invocation. */
public static ClassReader instance(Context context) {
ClassReader instance = context.get(classReaderKey);
@@ -264,8 +275,8 @@
}
packages.put(names.empty, syms.rootPackage);
- syms.rootPackage.completer = this;
- syms.unnamedPackage.completer = this;
+ syms.rootPackage.completer = thisCompleter;
+ syms.unnamedPackage.completer = thisCompleter;
}
/** Construct a new class reader, optionally treated as the
@@ -727,12 +738,14 @@
ClassSymbol t = enterClass(names.fromUtf(signatureBuffer,
startSbp,
sbp - startSbp));
- if (outer == Type.noType)
- outer = t.erasure(types);
- else
- outer = new ClassType(outer, List.<Type>nil(), t);
- sbp = startSbp;
- return outer;
+
+ try {
+ return (outer == Type.noType) ?
+ t.erasure(types) :
+ new ClassType(outer, List.<Type>nil(), t);
+ } finally {
+ sbp = startSbp;
+ }
}
case '<': // generic arguments
@@ -797,6 +810,13 @@
continue;
case '.':
+ //we have seen an enclosing non-generic class
+ if (outer != Type.noType) {
+ t = enterClass(names.fromUtf(signatureBuffer,
+ startSbp,
+ sbp - startSbp));
+ outer = new ClassType(outer, List.<Type>nil(), t);
+ }
signatureBuffer[sbp++] = (byte)'$';
continue;
case '/':
@@ -2310,7 +2330,7 @@
ClassSymbol c = new ClassSymbol(0, name, owner);
if (owner.kind == PCK)
Assert.checkNull(classes.get(c.flatname), c);
- c.completer = this;
+ c.completer = thisCompleter;
return c;
}
@@ -2380,7 +2400,7 @@
/** Completion for classes to be loaded. Before a class is loaded
* we make sure its enclosing class (if any) is loaded.
*/
- public void complete(Symbol sym) throws CompletionFailure {
+ private void complete(Symbol sym) throws CompletionFailure {
if (sym.kind == TYP) {
ClassSymbol c = (ClassSymbol)sym;
c.members_field = new Scope.ErrorScope(c); // make sure it's always defined
@@ -2601,7 +2621,7 @@
p = new PackageSymbol(
Convert.shortName(fullname),
enterPackage(Convert.packagePart(fullname)));
- p.completer = this;
+ p.completer = thisCompleter;
packages.put(fullname, p);
}
return p;
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Fri Sep 20 19:15:59 2013 -0700
@@ -37,7 +37,6 @@
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Attribute.RetentionPolicy;
-import com.sun.tools.javac.code.Attribute.TypeCompound;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.code.Types.UniqueType;
@@ -55,7 +54,6 @@
import static com.sun.tools.javac.main.Option.*;
import static javax.tools.StandardLocation.CLASS_OUTPUT;
-
/** This class provides operations to map an internal symbol table graph
* rooted in a ClassSymbol into a classfile.
*
@@ -1180,25 +1178,26 @@
if (code.varBufferSize > 0) {
int alenIdx = writeAttr(names.LocalVariableTable);
- databuf.appendChar(code.varBufferSize);
-
+ databuf.appendChar(code.getLVTSize());
for (int i=0; i<code.varBufferSize; i++) {
Code.LocalVar var = code.varBuffer[i];
- // write variable info
- Assert.check(var.start_pc >= 0
- && var.start_pc <= code.cp);
- databuf.appendChar(var.start_pc);
- Assert.check(var.length >= 0
- && (var.start_pc + var.length) <= code.cp);
- databuf.appendChar(var.length);
- VarSymbol sym = var.sym;
- databuf.appendChar(pool.put(sym.name));
- Type vartype = sym.erasure(types);
- if (needsLocalVariableTypeEntry(sym.type))
- nGenericVars++;
- databuf.appendChar(pool.put(typeSig(vartype)));
- databuf.appendChar(var.reg);
+ for (Code.LocalVar.Range r: var.aliveRanges) {
+ // write variable info
+ Assert.check(r.start_pc >= 0
+ && r.start_pc <= code.cp);
+ databuf.appendChar(r.start_pc);
+ Assert.check(r.length >= 0
+ && (r.start_pc + r.length) <= code.cp);
+ databuf.appendChar(r.length);
+ VarSymbol sym = var.sym;
+ databuf.appendChar(pool.put(sym.name));
+ Type vartype = sym.erasure(types);
+ databuf.appendChar(pool.put(typeSig(vartype)));
+ databuf.appendChar(var.reg);
+ if (needsLocalVariableTypeEntry(var.sym.type))
+ nGenericVars++;
+ }
}
endAttr(alenIdx);
acount++;
@@ -1214,13 +1213,15 @@
VarSymbol sym = var.sym;
if (!needsLocalVariableTypeEntry(sym.type))
continue;
- count++;
- // write variable info
- databuf.appendChar(var.start_pc);
- databuf.appendChar(var.length);
- databuf.appendChar(pool.put(sym.name));
- databuf.appendChar(pool.put(typeSig(sym.type)));
- databuf.appendChar(var.reg);
+ for (Code.LocalVar.Range r : var.aliveRanges) {
+ // write variable info
+ databuf.appendChar(r.start_pc);
+ databuf.appendChar(r.length);
+ databuf.appendChar(pool.put(sym.name));
+ databuf.appendChar(pool.put(typeSig(sym.type)));
+ databuf.appendChar(var.reg);
+ count++;
+ }
}
Assert.check(count == nGenericVars);
endAttr(alenIdx);
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Fri Sep 20 19:15:59 2013 -0700
@@ -28,6 +28,7 @@
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Types.UniqueType;
+import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
@@ -181,6 +182,8 @@
final MethodSymbol meth;
+ final LVTRanges lvtRanges;
+
/** Construct a code object, given the settings of the fatcode,
* debugging info switches and the CharacterRangeTable.
*/
@@ -193,7 +196,8 @@
CRTable crt,
Symtab syms,
Types types,
- Pool pool) {
+ Pool pool,
+ LVTRanges lvtRanges) {
this.meth = meth;
this.fatcode = fatcode;
this.lineMap = lineMap;
@@ -215,6 +219,7 @@
state = new State();
lvar = new LocalVar[20];
this.pool = pool;
+ this.lvtRanges = lvtRanges;
}
@@ -305,9 +310,19 @@
/** The current output code pointer.
*/
- public int curPc() {
- if (pendingJumps != null) resolvePending();
- if (pendingStatPos != Position.NOPOS) markStatBegin();
+ public int curCP() {
+ /*
+ * This method has side-effects because calling it can indirectly provoke
+ * extra code generation, like goto instructions, depending on the context
+ * where it's called.
+ * Use with care or even better avoid using it.
+ */
+ if (pendingJumps != null) {
+ resolvePending();
+ }
+ if (pendingStatPos != Position.NOPOS) {
+ markStatBegin();
+ }
fixedPc = true;
return cp;
}
@@ -1175,7 +1190,7 @@
/** Declare an entry point; return current code pointer
*/
public int entryPoint() {
- int pc = curPc();
+ int pc = curCP();
alive = true;
pendingStackMap = needStackMap;
return pc;
@@ -1185,7 +1200,7 @@
* return current code pointer
*/
public int entryPoint(State state) {
- int pc = curPc();
+ int pc = curCP();
alive = true;
this.state = state.dup();
Assert.check(state.stacksize <= max_stack);
@@ -1198,7 +1213,7 @@
* return current code pointer
*/
public int entryPoint(State state, Type pushed) {
- int pc = curPc();
+ int pc = curCP();
alive = true;
this.state = state.dup();
Assert.check(state.stacksize <= max_stack);
@@ -1238,7 +1253,7 @@
/** Emit a stack map entry. */
public void emitStackMap() {
- int pc = curPc();
+ int pc = curCP();
if (!needStackMap) return;
@@ -1482,6 +1497,9 @@
chain.pc + 3 == target && target == cp && !fixedPc) {
// If goto the next instruction, the jump is not needed:
// compact the code.
+ if (varDebugInfo) {
+ adjustAliveRanges(cp, -3);
+ }
cp = cp - 3;
target = target - 3;
if (chain.next == null) {
@@ -1781,8 +1799,7 @@
sym = sym.clone(sym.owner);
sym.type = newtype;
LocalVar newlv = lvar[i] = new LocalVar(sym);
- // should the following be initialized to cp?
- newlv.start_pc = lv.start_pc;
+ newlv.aliveRanges = lv.aliveRanges;
}
}
}
@@ -1870,8 +1887,36 @@
static class LocalVar {
final VarSymbol sym;
final char reg;
- char start_pc = Character.MAX_VALUE;
- char length = Character.MAX_VALUE;
+
+ class Range {
+ char start_pc = Character.MAX_VALUE;
+ char length = Character.MAX_VALUE;
+
+ Range() {}
+
+ Range(char start) {
+ this.start_pc = start;
+ }
+
+ Range(char start, char length) {
+ this.start_pc = start;
+ this.length = length;
+ }
+
+ boolean closed() {
+ return start_pc != Character.MAX_VALUE && length != Character.MAX_VALUE;
+ }
+
+ @Override
+ public String toString() {
+ int currentStartPC = start_pc;
+ int currentLength = length;
+ return "startpc = " + currentStartPC + " length " + currentLength;
+ }
+ }
+
+ java.util.List<Range> aliveRanges = new java.util.ArrayList<>();
+
LocalVar(VarSymbol v) {
this.sym = v;
this.reg = (char)v.adr;
@@ -1879,9 +1924,78 @@
public LocalVar dup() {
return new LocalVar(sym);
}
+
+ Range firstRange() {
+ return aliveRanges.isEmpty() ? null : aliveRanges.get(0);
+ }
+
+ Range lastRange() {
+ return aliveRanges.isEmpty() ? null : aliveRanges.get(aliveRanges.size() - 1);
+ }
+
+ @Override
public String toString() {
- return "" + sym + " in register " + ((int)reg) + " starts at pc=" + ((int)start_pc) + " length=" + ((int)length);
+ if (aliveRanges == null) {
+ return "empty local var";
+ }
+ StringBuilder sb = new StringBuilder().append(sym)
+ .append(" in register ").append((int)reg).append(" \n");
+ for (Range r : aliveRanges) {
+ sb.append(" starts at pc=").append(Integer.toString(((int)r.start_pc)))
+ .append(" length=").append(Integer.toString(((int)r.length)))
+ .append("\n");
+ }
+ return sb.toString();
+ }
+
+ public void openRange(char start) {
+ if (!hasOpenRange()) {
+ aliveRanges.add(new Range(start));
+ }
}
+
+ public void closeRange(char end) {
+ if (isLastRangeInitialized()) {
+ Range range = lastRange();
+ if (range != null) {
+ if (range.length == Character.MAX_VALUE) {
+ range.length = end;
+ }
+ }
+ } else {
+ if (!aliveRanges.isEmpty()) {
+ aliveRanges.remove(aliveRanges.size() - 1);
+ }
+ }
+ }
+
+ public boolean hasOpenRange() {
+ if (aliveRanges.isEmpty()) {
+ return false;
+ }
+ Range range = lastRange();
+ return range.length == Character.MAX_VALUE;
+ }
+
+ public boolean isLastRangeInitialized() {
+ if (aliveRanges.isEmpty()) {
+ return false;
+ }
+ Range range = lastRange();
+ return range.start_pc != Character.MAX_VALUE;
+ }
+
+ public Range getWidestRange() {
+ if (aliveRanges.isEmpty()) {
+ return new Range();
+ } else {
+ Range firstRange = firstRange();
+ Range lastRange = lastRange();
+ char length = (char)(lastRange.length + (lastRange.start_pc - firstRange.start_pc));
+ return new Range(firstRange.start_pc, length);
+ }
+ }
+
};
/** Local variables, indexed by register. */
@@ -1892,11 +2006,60 @@
int adr = v.adr;
lvar = ArrayUtils.ensureCapacity(lvar, adr+1);
Assert.checkNull(lvar[adr]);
- if (pendingJumps != null) resolvePending();
+ if (pendingJumps != null) {
+ resolvePending();
+ }
lvar[adr] = new LocalVar(v);
state.defined.excl(adr);
}
+
+ public void closeAliveRanges(JCTree tree) {
+ closeAliveRanges(tree, cp);
+ }
+
+ public void closeAliveRanges(JCTree tree, int closingCP) {
+ List<VarSymbol> locals = lvtRanges.getVars(meth, tree);
+ for (LocalVar localVar: lvar) {
+ for (VarSymbol aliveLocal : locals) {
+ if (localVar == null) {
+ return;
+ }
+ if (localVar.sym == aliveLocal && localVar.lastRange() != null) {
+ char length = (char)(closingCP - localVar.lastRange().start_pc);
+ if (length > 0 && length < Character.MAX_VALUE) {
+ localVar.closeRange(length);
+ }
+ }
+ }
+ }
+ }
+
+ void adjustAliveRanges(int oldCP, int delta) {
+ for (LocalVar localVar: lvar) {
+ if (localVar == null) {
+ return;
+ }
+ for (LocalVar.Range range: localVar.aliveRanges) {
+ if (range.closed() && range.start_pc + range.length >= oldCP) {
+ range.length += delta;
+ }
+ }
+ }
+ }
+
+ /**
+ * Calculates the size of the LocalVariableTable.
+ */
+ public int getLVTSize() {
+ int result = varBufferSize;
+ for (int i = 0; i < varBufferSize; i++) {
+ LocalVar var = varBuffer[i];
+ result += var.aliveRanges.size() - 1;
+ }
+ return result;
+ }
+
/** Set the current variable defined state. */
public void setDefined(Bits newDefined) {
if (alive && newDefined != state.defined) {
@@ -1922,8 +2085,7 @@
} else {
state.defined.incl(adr);
if (cp < Character.MAX_VALUE) {
- if (v.start_pc == Character.MAX_VALUE)
- v.start_pc = (char)cp;
+ v.openRange((char)cp);
}
}
}
@@ -1933,15 +2095,15 @@
state.defined.excl(adr);
if (adr < lvar.length &&
lvar[adr] != null &&
- lvar[adr].start_pc != Character.MAX_VALUE) {
+ lvar[adr].isLastRangeInitialized()) {
LocalVar v = lvar[adr];
- char length = (char)(curPc() - v.start_pc);
+ char length = (char)(curCP() - v.lastRange().start_pc);
if (length > 0 && length < Character.MAX_VALUE) {
lvar[adr] = v.dup();
- v.length = length;
+ v.closeRange(length);
putVar(v);
} else {
- v.start_pc = Character.MAX_VALUE;
+ v.lastRange().start_pc = Character.MAX_VALUE;
}
}
}
@@ -1951,10 +2113,10 @@
LocalVar v = lvar[adr];
if (v != null) {
lvar[adr] = null;
- if (v.start_pc != Character.MAX_VALUE) {
- char length = (char)(curPc() - v.start_pc);
+ if (v.isLastRangeInitialized()) {
+ char length = (char)(curCP() - v.lastRange().start_pc);
if (length < Character.MAX_VALUE) {
- v.length = length;
+ v.closeRange(length);
putVar(v);
fillLocalVarPosition(v);
}
@@ -1968,8 +2130,9 @@
return;
for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
TypeAnnotationPosition p = ta.position;
- p.lvarOffset = new int[] { (int)lv.start_pc };
- p.lvarLength = new int[] { (int)lv.length };
+ LocalVar.Range widestRange = lv.getWidestRange();
+ p.lvarOffset = new int[] { (int)widestRange.start_pc };
+ p.lvarLength = new int[] { (int)widestRange.length };
p.lvarIndex = new int[] { (int)lv.reg };
p.isValidOffset = true;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Fri Sep 20 19:15:59 2013 -0700
@@ -24,6 +24,7 @@
*/
package com.sun.tools.javac.jvm;
+
import java.util.*;
import com.sun.tools.javac.util.*;
@@ -95,10 +96,14 @@
return instance;
}
- /* Constant pool, reset by genClass.
+ /** Constant pool, reset by genClass.
*/
private Pool pool;
+ /** LVTRanges info.
+ */
+ private LVTRanges lvtRanges;
+
protected Gen(Context context) {
context.put(genKey, this);
@@ -128,6 +133,9 @@
options.isUnset(G_CUSTOM)
? options.isSet(G)
: options.isSet(G_CUSTOM, "vars");
+ if (varDebugInfo) {
+ lvtRanges = LVTRanges.instance(context);
+ }
genCrt = options.isSet(XJCOV);
debugCode = options.isSet("debugcode");
allowInvokedynamic = target.hasInvokedynamic() || options.isSet("invokedynamic");
@@ -423,7 +431,7 @@
*/
void endFinalizerGap(Env<GenContext> env) {
if (env.info.gaps != null && env.info.gaps.length() % 2 == 1)
- env.info.gaps.append(code.curPc());
+ env.info.gaps.append(code.curCP());
}
/** Mark end of all gaps in catch-all ranges for finalizers of environments
@@ -743,10 +751,10 @@
genStat(tree, env);
return;
}
- int startpc = code.curPc();
+ int startpc = code.curCP();
genStat(tree, env);
if (tree.hasTag(Tag.BLOCK)) crtFlags |= CRT_BLOCK;
- code.crt.put(tree, crtFlags, startpc, code.curPc());
+ code.crt.put(tree, crtFlags, startpc, code.curCP());
}
/** Derived visitor method: generate code for a statement.
@@ -781,9 +789,9 @@
if (trees.length() == 1) { // mark one statement with the flags
genStat(trees.head, env, crtFlags | CRT_STATEMENT);
} else {
- int startpc = code.curPc();
+ int startpc = code.curCP();
genStats(trees, env);
- code.crt.put(trees, crtFlags, startpc, code.curPc());
+ code.crt.put(trees, crtFlags, startpc, code.curCP());
}
}
@@ -806,9 +814,9 @@
*/
public CondItem genCond(JCTree tree, int crtFlags) {
if (!genCrt) return genCond(tree, false);
- int startpc = code.curPc();
+ int startpc = code.curCP();
CondItem item = genCond(tree, (crtFlags & CRT_FLOW_CONTROLLER) != 0);
- code.crt.put(tree, crtFlags, startpc, code.curPc());
+ code.crt.put(tree, crtFlags, startpc, code.curCP());
return item;
}
@@ -971,7 +979,6 @@
// definition.
Env<GenContext> localEnv = env.dup(tree);
localEnv.enclMethod = tree;
-
// The expected type of every return statement in this method
// is the method's return type.
this.pt = tree.sym.erasure(types).getReturnType();
@@ -1045,7 +1052,7 @@
code.crt.put(tree.body,
CRT_BLOCK,
startpcCrt,
- code.curPc());
+ code.curCP());
code.endScopes(0);
@@ -1087,10 +1094,12 @@
: null,
syms,
types,
- pool);
+ pool,
+ varDebugInfo ? lvtRanges : null);
items = new Items(pool, code, syms, types);
- if (code.debugCode)
+ if (code.debugCode) {
System.err.println(meth + " for body " + tree);
+ }
// If method is not static, create a new local variable address
// for `this'.
@@ -1111,7 +1120,7 @@
}
// Get ready to generate code for method body.
- int startpcCrt = genCrt ? code.curPc() : 0;
+ int startpcCrt = genCrt ? code.curCP() : 0;
code.entryPoint();
// Suppress initial stackmap
@@ -1189,14 +1198,30 @@
Chain loopDone = c.jumpFalse();
code.resolve(c.trueJumps);
genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET);
+ if (varDebugInfo) {
+ checkLoopLocalVarRangeEnding(loop, body,
+ LoopLocalVarRangeEndingPoint.BEFORE_STEPS);
+ }
code.resolve(loopEnv.info.cont);
genStats(step, loopEnv);
+ if (varDebugInfo) {
+ checkLoopLocalVarRangeEnding(loop, body,
+ LoopLocalVarRangeEndingPoint.AFTER_STEPS);
+ }
code.resolve(code.branch(goto_), startpc);
code.resolve(loopDone);
} else {
genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET);
+ if (varDebugInfo) {
+ checkLoopLocalVarRangeEnding(loop, body,
+ LoopLocalVarRangeEndingPoint.BEFORE_STEPS);
+ }
code.resolve(loopEnv.info.cont);
genStats(step, loopEnv);
+ if (varDebugInfo) {
+ checkLoopLocalVarRangeEnding(loop, body,
+ LoopLocalVarRangeEndingPoint.AFTER_STEPS);
+ }
CondItem c;
if (cond != null) {
code.statBegin(cond.pos);
@@ -1210,6 +1235,44 @@
code.resolve(loopEnv.info.exit);
}
+ private enum LoopLocalVarRangeEndingPoint {
+ BEFORE_STEPS,
+ AFTER_STEPS,
+ }
+
+ /**
+ * Checks whether we have reached an alive range ending point for local
+ * variables after a loop.
+ *
+ * Local variables alive range ending point for loops varies depending
+ * on the loop type. The range can be closed before or after the code
+ * for the steps sentences has been generated.
+ *
+ * - While loops has no steps so in that case the range is closed just
+ * after the body of the loop.
+ *
+ * - For-like loops may have steps so as long as the steps sentences
+ * can possibly contain non-synthetic local variables, the alive range
+ * for local variables must be closed after the steps in this case.
+ */
+ private void checkLoopLocalVarRangeEnding(JCTree loop, JCTree body,
+ LoopLocalVarRangeEndingPoint endingPoint) {
+ if (varDebugInfo && lvtRanges.containsKey(code.meth, body)) {
+ switch (endingPoint) {
+ case BEFORE_STEPS:
+ if (!loop.hasTag(FORLOOP)) {
+ code.closeAliveRanges(body);
+ }
+ break;
+ case AFTER_STEPS:
+ if (loop.hasTag(FORLOOP)) {
+ code.closeAliveRanges(body);
+ }
+ break;
+ }
+ }
+ }
+
public void visitForeachLoop(JCEnhancedForLoop tree) {
throw new AssertionError(); // should have been removed by Lower.
}
@@ -1223,7 +1286,7 @@
public void visitSwitch(JCSwitch tree) {
int limit = code.nextreg;
Assert.check(!tree.selector.type.hasTag(CLASS));
- int startpcCrt = genCrt ? code.curPc() : 0;
+ int startpcCrt = genCrt ? code.curCP() : 0;
Item sel = genExpr(tree.selector, syms.intType);
List<JCCase> cases = tree.cases;
if (cases.isEmpty()) {
@@ -1231,13 +1294,13 @@
sel.load().drop();
if (genCrt)
code.crt.put(TreeInfo.skipParens(tree.selector),
- CRT_FLOW_CONTROLLER, startpcCrt, code.curPc());
+ CRT_FLOW_CONTROLLER, startpcCrt, code.curCP());
} else {
// We are seeing a nonempty switch.
sel.load();
if (genCrt)
code.crt.put(TreeInfo.skipParens(tree.selector),
- CRT_FLOW_CONTROLLER, startpcCrt, code.curPc());
+ CRT_FLOW_CONTROLLER, startpcCrt, code.curCP());
Env<GenContext> switchEnv = env.dup(tree, new GenContext());
switchEnv.info.isSwitch = true;
@@ -1278,10 +1341,10 @@
?
tableswitch : lookupswitch;
- int startpc = code.curPc(); // the position of the selector operation
+ int startpc = code.curCP(); // the position of the selector operation
code.emitop0(opcode);
code.align(4);
- int tableBase = code.curPc(); // the start of the jump table
+ int tableBase = code.curCP(); // the start of the jump table
int[] offsets = null; // a table of offsets for a lookupswitch
code.emit4(-1); // leave space for default offset
if (opcode == tableswitch) {
@@ -1323,6 +1386,9 @@
// Generate code for the statements in this case.
genStats(c.stats, switchEnv, CRT_FLOW_TARGET);
+ if (varDebugInfo && lvtRanges.containsKey(code.meth, c.stats.last())) {
+ code.closeAliveRanges(c.stats.last());
+ }
}
// Resolve all breaks.
@@ -1402,7 +1468,7 @@
void gen() {
genLast();
Assert.check(syncEnv.info.gaps.length() % 2 == 0);
- syncEnv.info.gaps.append(code.curPc());
+ syncEnv.info.gaps.append(code.curCP());
}
void genLast() {
if (code.isAlive()) {
@@ -1441,10 +1507,10 @@
jsrState);
}
Assert.check(tryEnv.info.gaps.length() % 2 == 0);
- tryEnv.info.gaps.append(code.curPc());
+ tryEnv.info.gaps.append(code.curCP());
} else {
Assert.check(tryEnv.info.gaps.length() % 2 == 0);
- tryEnv.info.gaps.append(code.curPc());
+ tryEnv.info.gaps.append(code.curCP());
genLast();
}
}
@@ -1467,10 +1533,10 @@
*/
void genTry(JCTree body, List<JCCatch> catchers, Env<GenContext> env) {
int limit = code.nextreg;
- int startpc = code.curPc();
+ int startpc = code.curCP();
Code.State stateTry = code.state.dup();
genStat(body, env, CRT_BLOCK);
- int endpc = code.curPc();
+ int endpc = code.curCP();
boolean hasFinalizer =
env.info.finalize != null &&
env.info.finalize.hasFinalizer();
@@ -1478,82 +1544,77 @@
code.statBegin(TreeInfo.endPos(body));
genFinalizer(env);
code.statBegin(TreeInfo.endPos(env.tree));
- Chain exitChain;
- if (startpc != endpc) {
- exitChain = code.branch(goto_);
- } else {
- exitChain = code.branch(dontgoto);
+ Chain exitChain = code.branch(goto_);
+ if (varDebugInfo && lvtRanges.containsKey(code.meth, body)) {
+ code.closeAliveRanges(body);
}
endFinalizerGap(env);
- if (startpc != endpc) {
- for (List<JCCatch> l = catchers; l.nonEmpty(); l = l.tail) {
- // start off with exception on stack
- code.entryPoint(stateTry, l.head.param.sym.type);
- genCatch(l.head, env, startpc, endpc, gaps);
- genFinalizer(env);
- if (hasFinalizer || l.tail.nonEmpty()) {
- code.statBegin(TreeInfo.endPos(env.tree));
- exitChain = Code.mergeChains(exitChain,
- code.branch(goto_));
- }
- endFinalizerGap(env);
+ if (startpc != endpc) for (List<JCCatch> l = catchers; l.nonEmpty(); l = l.tail) {
+ // start off with exception on stack
+ code.entryPoint(stateTry, l.head.param.sym.type);
+ genCatch(l.head, env, startpc, endpc, gaps);
+ genFinalizer(env);
+ if (hasFinalizer || l.tail.nonEmpty()) {
+ code.statBegin(TreeInfo.endPos(env.tree));
+ exitChain = Code.mergeChains(exitChain,
+ code.branch(goto_));
}
+ endFinalizerGap(env);
+ }
+ if (hasFinalizer) {
+ // Create a new register segement to avoid allocating
+ // the same variables in finalizers and other statements.
+ code.newRegSegment();
+
+ // Add a catch-all clause.
+
+ // start off with exception on stack
+ int catchallpc = code.entryPoint(stateTry, syms.throwableType);
- if (hasFinalizer) {
- // Create a new register segement to avoid allocating
- // the same variables in finalizers and other statements.
- code.newRegSegment();
-
- // Add a catch-all clause.
-
- // start off with exception on stack
- int catchallpc = code.entryPoint(stateTry, syms.throwableType);
+ // Register all exception ranges for catch all clause.
+ // The range of the catch all clause is from the beginning
+ // of the try or synchronized block until the present
+ // code pointer excluding all gaps in the current
+ // environment's GenContext.
+ int startseg = startpc;
+ while (env.info.gaps.nonEmpty()) {
+ int endseg = env.info.gaps.next().intValue();
+ registerCatch(body.pos(), startseg, endseg,
+ catchallpc, 0);
+ startseg = env.info.gaps.next().intValue();
+ }
+ code.statBegin(TreeInfo.finalizerPos(env.tree));
+ code.markStatBegin();
- // Register all exception ranges for catch all clause.
- // The range of the catch all clause is from the beginning
- // of the try or synchronized block until the present
- // code pointer excluding all gaps in the current
- // environment's GenContext.
- int startseg = startpc;
- while (env.info.gaps.nonEmpty()) {
- int endseg = env.info.gaps.next().intValue();
- registerCatch(body.pos(), startseg, endseg,
- catchallpc, 0);
- startseg = env.info.gaps.next().intValue();
- }
+ Item excVar = makeTemp(syms.throwableType);
+ excVar.store();
+ genFinalizer(env);
+ excVar.load();
+ registerCatch(body.pos(), startseg,
+ env.info.gaps.next().intValue(),
+ catchallpc, 0);
+ code.emitop0(athrow);
+ code.markDead();
+
+ // If there are jsr's to this finalizer, ...
+ if (env.info.cont != null) {
+ // Resolve all jsr's.
+ code.resolve(env.info.cont);
+
+ // Mark statement line number
code.statBegin(TreeInfo.finalizerPos(env.tree));
code.markStatBegin();
- Item excVar = makeTemp(syms.throwableType);
- excVar.store();
- genFinalizer(env);
- excVar.load();
- registerCatch(body.pos(), startseg,
- env.info.gaps.next().intValue(),
- catchallpc, 0);
- code.emitop0(athrow);
- code.markDead();
-
- // If there are jsr's to this finalizer, ...
- if (env.info.cont != null) {
- // Resolve all jsr's.
- code.resolve(env.info.cont);
+ // Save return address.
+ LocalItem retVar = makeTemp(syms.throwableType);
+ retVar.store();
- // Mark statement line number
- code.statBegin(TreeInfo.finalizerPos(env.tree));
- code.markStatBegin();
-
- // Save return address.
- LocalItem retVar = makeTemp(syms.throwableType);
- retVar.store();
+ // Generate finalizer code.
+ env.info.finalize.genLast();
- // Generate finalizer code.
- env.info.finalize.genLast();
-
- // Return.
- code.emitop1w(ret, retVar.reg);
- code.markDead();
- }
+ // Return.
+ code.emitop1w(ret, retVar.reg);
+ code.markDead();
}
}
// Resolve all breaks.
@@ -1581,7 +1642,7 @@
int catchType = makeRef(tree.pos(), subCatch.type);
int end = gaps.head.intValue();
registerCatch(tree.pos(),
- startpc, end, code.curPc(),
+ startpc, end, code.curCP(),
catchType);
if (subCatch.type.isAnnotated()) {
// All compounds share the same position, simply update the
@@ -1597,7 +1658,7 @@
for (JCExpression subCatch : subClauses) {
int catchType = makeRef(tree.pos(), subCatch.type);
registerCatch(tree.pos(),
- startpc, endpc, code.curPc(),
+ startpc, endpc, code.curCP(),
catchType);
if (subCatch.type.isAnnotated()) {
// All compounds share the same position, simply update the
@@ -1740,11 +1801,19 @@
code.resolve(c.trueJumps);
genStat(tree.thenpart, env, CRT_STATEMENT | CRT_FLOW_TARGET);
thenExit = code.branch(goto_);
+ if (varDebugInfo && lvtRanges.containsKey(code.meth, tree.thenpart)) {
+ code.closeAliveRanges(tree.thenpart,
+ thenExit != null && tree.elsepart == null ? thenExit.pc : code.cp);
+ }
}
if (elseChain != null) {
code.resolve(elseChain);
- if (tree.elsepart != null)
+ if (tree.elsepart != null) {
genStat(tree.elsepart, env,CRT_STATEMENT | CRT_FLOW_TARGET);
+ if (varDebugInfo && lvtRanges.containsKey(code.meth, tree.elsepart)) {
+ code.closeAliveRanges(tree.elsepart);
+ }
+ }
}
code.resolve(thenExit);
code.endScopes(limit);
@@ -1838,20 +1907,20 @@
Chain elseChain = c.jumpFalse();
if (!c.isFalse()) {
code.resolve(c.trueJumps);
- int startpc = genCrt ? code.curPc() : 0;
+ int startpc = genCrt ? code.curCP() : 0;
genExpr(tree.truepart, pt).load();
code.state.forceStackTop(tree.type);
if (genCrt) code.crt.put(tree.truepart, CRT_FLOW_TARGET,
- startpc, code.curPc());
+ startpc, code.curCP());
thenExit = code.branch(goto_);
}
if (elseChain != null) {
code.resolve(elseChain);
- int startpc = genCrt ? code.curPc() : 0;
+ int startpc = genCrt ? code.curCP() : 0;
genExpr(tree.falsepart, pt).load();
code.state.forceStackTop(tree.type);
if (genCrt) code.crt.put(tree.falsepart, CRT_FLOW_TARGET,
- startpc, code.curPc());
+ startpc, code.curCP());
}
code.resolve(thenExit);
result = items.makeStackItem(pt);
@@ -2431,6 +2500,19 @@
new Env<GenContext>(cdef, new GenContext());
localEnv.toplevel = env.toplevel;
localEnv.enclClass = cdef;
+
+ /* We must not analyze synthetic methods
+ */
+ if (varDebugInfo && (cdef.sym.flags() & SYNTHETIC) == 0) {
+ try {
+ LVTAssignAnalyzer lvtAssignAnalyzer = LVTAssignAnalyzer.make(
+ lvtRanges, syms, names);
+ lvtAssignAnalyzer.analyzeTree(localEnv);
+ } catch (Throwable e) {
+ throw e;
+ }
+ }
+
for (List<JCTree> l = cdef.defs; l.nonEmpty(); l = l.tail) {
genDef(l.head, localEnv);
}
@@ -2515,4 +2597,311 @@
cont = Code.mergeChains(c, cont);
}
}
+
+ static class LVTAssignAnalyzer
+ extends Flow.AbstractAssignAnalyzer<LVTAssignAnalyzer.LVTAssignPendingExit> {
+
+ final LVTBits lvtInits;
+ final LVTRanges lvtRanges;
+
+ /* This class is anchored to a context dependent tree. The tree can
+ * vary inside the same instruction for example in the switch instruction
+ * the same FlowBits instance can be anchored to the whole tree, or
+ * to a given case. The aim is to always anchor the bits to the tree
+ * capable of closing a DA range.
+ */
+ static class LVTBits extends Bits {
+
+ enum BitsOpKind {
+ INIT,
+ CLEAR,
+ INCL_BIT,
+ EXCL_BIT,
+ ASSIGN,
+ AND_SET,
+ OR_SET,
+ DIFF_SET,
+ XOR_SET,
+ INCL_RANGE,
+ EXCL_RANGE,
+ }
+
+ JCTree currentTree;
+ LVTAssignAnalyzer analyzer;
+ private int[] oldBits = null;
+ BitsState stateBeforeOp;
+
+ LVTBits() {
+ super(false);
+ }
+
+ LVTBits(int[] bits, BitsState initState) {
+ super(bits, initState);
+ }
+
+ @Override
+ public void clear() {
+ generalOp(null, -1, BitsOpKind.CLEAR);
+ }
+
+ @Override
+ protected void internalReset() {
+ super.internalReset();
+ oldBits = null;
+ }
+
+ @Override
+ public Bits assign(Bits someBits) {
+ // bits can be null
+ oldBits = bits;
+ stateBeforeOp = currentState;
+ super.assign(someBits);
+ changed();
+ return this;
+ }
+
+ @Override
+ public void excludeFrom(int start) {
+ generalOp(null, start, BitsOpKind.EXCL_RANGE);
+ }
+
+ @Override
+ public void excl(int x) {
+ Assert.check(x >= 0);
+ generalOp(null, x, BitsOpKind.EXCL_BIT);
+ }
+
+ @Override
+ public Bits andSet(Bits xs) {
+ return generalOp(xs, -1, BitsOpKind.AND_SET);
+ }
+
+ @Override
+ public Bits orSet(Bits xs) {
+ return generalOp(xs, -1, BitsOpKind.OR_SET);
+ }
+
+ @Override
+ public Bits diffSet(Bits xs) {
+ return generalOp(xs, -1, BitsOpKind.DIFF_SET);
+ }
+
+ @Override
+ public Bits xorSet(Bits xs) {
+ return generalOp(xs, -1, BitsOpKind.XOR_SET);
+ }
+
+ private Bits generalOp(Bits xs, int i, BitsOpKind opKind) {
+ Assert.check(currentState != BitsState.UNKNOWN);
+ oldBits = dupBits();
+ stateBeforeOp = currentState;
+ switch (opKind) {
+ case AND_SET:
+ super.andSet(xs);
+ break;
+ case OR_SET:
+ super.orSet(xs);
+ break;
+ case XOR_SET:
+ super.xorSet(xs);
+ break;
+ case DIFF_SET:
+ super.diffSet(xs);
+ break;
+ case CLEAR:
+ super.clear();
+ break;
+ case EXCL_BIT:
+ super.excl(i);
+ break;
+ case EXCL_RANGE:
+ super.excludeFrom(i);
+ break;
+ }
+ changed();
+ return this;
+ }
+
+ /* The tree we need to anchor the bits instance to.
+ */
+ LVTBits at(JCTree tree) {
+ this.currentTree = tree;
+ return this;
+ }
+
+ /* If the instance should be changed but the tree is not a closing
+ * tree then a reset is needed or the former tree can mistakingly be
+ * used.
+ */
+ LVTBits resetTree() {
+ this.currentTree = null;
+ return this;
+ }
+
+ /** This method will be called after any operation that causes a change to
+ * the bits. Subclasses can thus override it in order to extract information
+ * from the changes produced to the bits by the given operation.
+ */
+ public void changed() {
+ if (currentTree != null &&
+ stateBeforeOp != BitsState.UNKNOWN &&
+ trackTree(currentTree)) {
+ List<VarSymbol> locals =
+ analyzer.lvtRanges
+ .getVars(analyzer.currentMethod, currentTree);
+ locals = locals != null ?
+ locals : List.<VarSymbol>nil();
+ for (JCVariableDecl vardecl : analyzer.vardecls) {
+ //once the first is null, the rest will be so.
+ if (vardecl == null) {
+ break;
+ }
+ if (trackVar(vardecl.sym) && bitChanged(vardecl.sym.adr)) {
+ locals = locals.prepend(vardecl.sym);
+ }
+ }
+ if (!locals.isEmpty()) {
+ analyzer.lvtRanges.setEntry(analyzer.currentMethod,
+ currentTree, locals);
+ }
+ }
+ }
+
+ boolean bitChanged(int x) {
+ boolean isMemberOfBits = isMember(x);
+ int[] tmp = bits;
+ bits = oldBits;
+ boolean isMemberOfOldBits = isMember(x);
+ bits = tmp;
+ return (!isMemberOfBits && isMemberOfOldBits);
+ }
+
+ boolean trackVar(VarSymbol var) {
+ return (var.owner.kind == MTH &&
+ (var.flags() & (PARAMETER | HASINIT)) == 0 &&
+ analyzer.trackable(var));
+ }
+
+ boolean trackTree(JCTree tree) {
+ switch (tree.getTag()) {
+ // of course a method closes the alive range of a local variable.
+ case METHODDEF:
+ // for while loops we want only the body
+ case WHILELOOP:
+ return false;
+ }
+ return true;
+ }
+
+ }
+
+ public class LVTAssignPendingExit extends Flow.AssignAnalyzer.AssignPendingExit {
+
+ LVTAssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
+ super(tree, inits, uninits);
+ }
+
+ @Override
+ public void resolveJump(JCTree tree) {
+ lvtInits.at(tree);
+ super.resolveJump(tree);
+ }
+ }
+
+ private LVTAssignAnalyzer(LVTRanges lvtRanges, Symtab syms, Names names) {
+ super(new LVTBits(), syms, names);
+ lvtInits = (LVTBits)inits;
+ this.lvtRanges = lvtRanges;
+ }
+
+ public static LVTAssignAnalyzer make(LVTRanges lvtRanges, Symtab syms, Names names) {
+ LVTAssignAnalyzer result = new LVTAssignAnalyzer(lvtRanges, syms, names);
+ result.lvtInits.analyzer = result;
+ return result;
+ }
+
+ @Override
+ protected void markDead(JCTree tree) {
+ lvtInits.at(tree).inclRange(returnadr, nextadr);
+ super.markDead(tree);
+ }
+
+ @Override
+ protected void merge(JCTree tree) {
+ lvtInits.at(tree);
+ super.merge(tree);
+ }
+
+ boolean isSyntheticOrMandated(Symbol sym) {
+ return (sym.flags() & (SYNTHETIC | MANDATED)) != 0;
+ }
+
+ @Override
+ protected boolean trackable(VarSymbol sym) {
+ if (isSyntheticOrMandated(sym)) {
+ //fast check to avoid tracking synthetic or mandated variables
+ return false;
+ }
+ return super.trackable(sym);
+ }
+
+ @Override
+ protected void initParam(JCVariableDecl def) {
+ if (!isSyntheticOrMandated(def.sym)) {
+ super.initParam(def);
+ }
+ }
+
+ @Override
+ protected void assignToInits(JCTree tree, Bits bits) {
+ lvtInits.at(tree);
+ lvtInits.assign(bits);
+ }
+
+ @Override
+ protected void andSetInits(JCTree tree, Bits bits) {
+ lvtInits.at(tree);
+ lvtInits.andSet(bits);
+ }
+
+ @Override
+ protected void orSetInits(JCTree tree, Bits bits) {
+ lvtInits.at(tree);
+ lvtInits.orSet(bits);
+ }
+
+ @Override
+ protected void exclVarFromInits(JCTree tree, int adr) {
+ lvtInits.at(tree);
+ lvtInits.excl(adr);
+ }
+
+ @Override
+ protected LVTAssignPendingExit createNewPendingExit(JCTree tree, Bits inits, Bits uninits) {
+ return new LVTAssignPendingExit(tree, inits, uninits);
+ }
+
+ MethodSymbol currentMethod;
+
+ @Override
+ public void visitMethodDef(JCMethodDecl tree) {
+ if ((tree.sym.flags() & (SYNTHETIC | GENERATEDCONSTR)) != 0) {
+ return;
+ }
+ if (tree.name.equals(names.clinit)) {
+ return;
+ }
+ boolean enumClass = (tree.sym.owner.flags() & ENUM) != 0;
+ if (enumClass &&
+ (tree.name.equals(names.valueOf) ||
+ tree.name.equals(names.values) ||
+ tree.name.equals(names.init))) {
+ return;
+ }
+ currentMethod = tree.sym;
+ super.visitMethodDef(tree);
+ }
+
+ }
+
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java Fri Sep 20 19:15:59 2013 -0700
@@ -789,18 +789,18 @@
Chain jumpTrue() {
if (tree == null) return Code.mergeChains(trueJumps, code.branch(opcode));
// we should proceed further in -Xjcov mode only
- int startpc = code.curPc();
+ int startpc = code.curCP();
Chain c = Code.mergeChains(trueJumps, code.branch(opcode));
- code.crt.put(tree, CRTable.CRT_BRANCH_TRUE, startpc, code.curPc());
+ code.crt.put(tree, CRTable.CRT_BRANCH_TRUE, startpc, code.curCP());
return c;
}
Chain jumpFalse() {
if (tree == null) return Code.mergeChains(falseJumps, code.branch(Code.negate(opcode)));
// we should proceed further in -Xjcov mode only
- int startpc = code.curPc();
+ int startpc = code.curCP();
Chain c = Code.mergeChains(falseJumps, code.branch(Code.negate(opcode)));
- code.crt.put(tree, CRTable.CRT_BRANCH_FALSE, startpc, code.curPc());
+ code.crt.put(tree, CRTable.CRT_BRANCH_FALSE, startpc, code.curCP());
return c;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/LVTRanges.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,129 @@
+/*
+ * 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 com.sun.tools.javac.jvm;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.WeakHashMap;
+
+import com.sun.tools.javac.code.Symbol.MethodSymbol;
+import com.sun.tools.javac.code.Symbol.VarSymbol;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.List;
+
+/** This class contains a one to many relation between a tree and a set of variables.
+ * The relation implies that the given tree closes the DA (definite assignment)
+ * range for the set of variables.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class LVTRanges {
+ /** The context key for the LVT ranges. */
+ protected static final Context.Key<LVTRanges> lvtRangesKey = new Context.Key<>();
+
+ /** Get the LVTRanges instance for this context. */
+ public static LVTRanges instance(Context context) {
+ LVTRanges instance = context.get(lvtRangesKey);
+ if (instance == null) {
+ instance = new LVTRanges(context);
+ }
+ return instance;
+ }
+
+ private static final long serialVersionUID = 1812267524140424433L;
+
+ protected Context context;
+
+ protected Map<MethodSymbol, Map<JCTree, List<VarSymbol>>>
+ aliveRangeClosingTrees = new WeakHashMap<>();
+
+ public LVTRanges(Context context) {
+ this.context = context;
+ context.put(lvtRangesKey, this);
+ }
+
+ public List<VarSymbol> getVars(MethodSymbol method, JCTree tree) {
+ Map<JCTree, List<VarSymbol>> varMap = aliveRangeClosingTrees.get(method);
+ return (varMap != null) ? varMap.get(tree) : null;
+ }
+
+ public boolean containsKey(MethodSymbol method, JCTree tree) {
+ Map<JCTree, List<VarSymbol>> varMap = aliveRangeClosingTrees.get(method);
+ if (varMap == null) {
+ return false;
+ }
+ return varMap.containsKey(tree);
+ }
+
+ public void setEntry(MethodSymbol method, JCTree tree, List<VarSymbol> vars) {
+ Map<JCTree, List<VarSymbol>> varMap = aliveRangeClosingTrees.get(method);
+ if (varMap != null) {
+ varMap.put(tree, vars);
+ } else {
+ varMap = new WeakHashMap<>();
+ varMap.put(tree, vars);
+ aliveRangeClosingTrees.put(method, varMap);
+ }
+ }
+
+ public List<VarSymbol> removeEntry(MethodSymbol method, JCTree tree) {
+ Map<JCTree, List<VarSymbol>> varMap = aliveRangeClosingTrees.get(method);
+ if (varMap != null) {
+ List<VarSymbol> result = varMap.remove(tree);
+ if (varMap.isEmpty()) {
+ aliveRangeClosingTrees.remove(method);
+ }
+ return result;
+ }
+ return null;
+ }
+
+ /* This method should be used for debugging LVT related issues.
+ */
+ @Override
+ public String toString() {
+ String result = "";
+ for (Entry<MethodSymbol, Map<JCTree, List<VarSymbol>>> mainEntry: aliveRangeClosingTrees.entrySet()) {
+ result += "Method: \n" + mainEntry.getKey().flatName() + "\n";
+ int i = 1;
+ for (Entry<JCTree, List<VarSymbol>> treeEntry: mainEntry.getValue().entrySet()) {
+ result += " Tree " + i + ": \n" + treeEntry.getKey().toString() + "\n";
+ result += " Variables closed:\n";
+ for (VarSymbol var: treeEntry.getValue()) {
+ result += " " + var.toString();
+ }
+ result += "\n";
+ i++;
+ }
+ }
+ return result;
+ }
+
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Fri Sep 20 19:15:59 2013 -0700
@@ -80,7 +80,7 @@
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
-public class JavaCompiler implements ClassReader.SourceCompleter {
+public class JavaCompiler {
/** The context key for the compiler. */
protected static final Context.Key<JavaCompiler> compilerKey =
new Context.Key<JavaCompiler>();
@@ -311,6 +311,17 @@
protected JavaCompiler delegateCompiler;
/**
+ * SourceCompleter that delegates to the complete-method of this class.
+ */
+ protected final ClassReader.SourceCompleter thisCompleter =
+ new ClassReader.SourceCompleter() {
+ @Override
+ public void complete(ClassSymbol sym) throws CompletionFailure {
+ JavaCompiler.this.complete(sym);
+ }
+ };
+
+ /**
* Command line options.
*/
protected Options options;
@@ -374,7 +385,7 @@
types = Types.instance(context);
taskListener = MultiTaskListener.instance(context);
- reader.sourceCompleter = this;
+ reader.sourceCompleter = thisCompleter;
options = Options.instance(context);
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Sep 20 19:15:59 2013 -0700
@@ -742,11 +742,6 @@
compiler.misc.incompatible.arg.types.in.mref=\
incompatible parameter types in method reference
-# 0: list of type, 1: message segment
-compiler.misc.bad.arg.types.in.lambda=\
- cannot type-check lambda expression with inferred parameter types\n\
- inferred types: {0}
-
compiler.err.new.not.allowed.in.annotation=\
''new'' not allowed in an annotation
@@ -1397,6 +1392,10 @@
compiler.warn.missing.SVUID=\
serializable class {0} has no definition of serialVersionUID
+# 0: symbol, 1: symbol, 2: symbol, 3: symbol
+compiler.warn.potentially.ambiguous.overload=\
+ {0} in {1} is potentially ambiguous with {2} in {3}
+
# 0: message segment
compiler.warn.override.varargs.missing=\
{0}; overridden method has no ''...''
@@ -1916,10 +1915,6 @@
inferred: {0}\n\
equality constraints(s): {1}
-# 0: list of type
-compiler.misc.cyclic.inference=\
- Cannot instantiate inference variables {0} because of an inference loop
-
# 0: symbol
compiler.misc.diamond=\
{0}<>
@@ -1932,6 +1927,10 @@
compiler.misc.diamond.and.explicit.params=\
cannot use ''<>'' with explicit type parameters for constructor
+# 0: unused
+compiler.misc.mref.infer.and.explicit.params=\
+ cannot use raw constructor reference with explicit type parameters for constructor
+
# 0: type, 1: list of type
compiler.misc.explicit.param.do.not.conform.to.bounds=\
explicit type argument {0} does not conform to declared bound(s) {1}
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Fri Sep 20 19:15:59 2013 -0700
@@ -1596,7 +1596,6 @@
public List<JCVariableDecl> params;
public JCTree body;
public boolean canCompleteNormally = true;
- public List<Type> inferredThrownTypes;
public ParameterKind paramKind;
public JCLambda(List<JCVariableDecl> params,
@@ -1908,6 +1907,7 @@
* Selects a member expression.
*/
public static class JCMemberReference extends JCFunctionalExpression implements MemberReferenceTree {
+
public ReferenceMode mode;
public ReferenceKind kind;
public Name name;
@@ -1917,6 +1917,12 @@
public Type varargsElement;
public PolyKind refPolyKind;
public boolean ownerAccessible;
+ public OverloadKind overloadKind;
+
+ public enum OverloadKind {
+ OVERLOADED,
+ UNOVERLOADED;
+ }
/**
* Javac-dependent classification for member references, based
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Fri Sep 20 19:15:59 2013 -0700
@@ -890,7 +890,7 @@
/** Create a value parameter tree from its name, type, and owner.
*/
public JCVariableDecl Param(Name name, Type argtype, Symbol owner) {
- return VarDef(new VarSymbol(0, name, argtype, owner), null);
+ return VarDef(new VarSymbol(PARAMETER, name, argtype, owner), null);
}
/** Create a a list of value parameter trees x0, ..., xn from a list of
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Bits.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Bits.java Fri Sep 20 19:15:59 2013 -0700
@@ -27,8 +27,6 @@
import java.util.Arrays;
-import static com.sun.tools.javac.util.Bits.BitsOpKind.*;
-
/** A class for extensible, mutable bit sets.
*
* <p><b>This is NOT part of any supported API.
@@ -38,20 +36,6 @@
*/
public class Bits {
- public enum BitsOpKind {
- INIT,
- CLEAR,
- INCL_BIT,
- EXCL_BIT,
- ASSIGN,
- AND_SET,
- OR_SET,
- DIFF_SET,
- XOR_SET,
- INCL_RANGE,
- EXCL_RANGE,
- }
-
// ____________ reset _________
// / UNKNOWN \ <-------- / UNINIT \
// \____________/ | \_________/
@@ -64,11 +48,14 @@
// | |
// -----------
// any
- private enum BitsState {
+ protected enum BitsState {
/* A Bits instance is in UNKNOWN state if it has been explicitly reset.
* It is possible to get to this state from any other by calling the
* reset method. An instance in the UNKNOWN state can pass to the
* NORMAL state after being assigned another Bits instance.
+ *
+ * Bits instances are final fields in Flow so the UNKNOWN state models
+ * the null assignment.
*/
UNKNOWN,
/* A Bits instance is in UNINIT when it is created with the default
@@ -103,13 +90,9 @@
public int[] bits = null;
// This field will store last version of bits after every change.
- public int[] oldBits = null;
-
- public BitsOpKind lastOperation = null;
-
private static final int[] unassignedBits = new int[0];
- private BitsState currentState;
+ protected BitsState currentState;
/** Construct an initially empty set.
*/
@@ -127,27 +110,20 @@
/** Construct a set consisting initially of given bit vector.
*/
- private Bits(int[] bits, BitsState initState) {
+ protected Bits(int[] bits, BitsState initState) {
this.bits = bits;
this.currentState = initState;
switch (initState) {
case UNKNOWN:
- reset(); //this will also set current state;
+ this.bits = null;
break;
case NORMAL:
Assert.check(bits != unassignedBits);
- lastOperation = INIT;
break;
}
}
- /** This method will be called after any operation that causes a change to
- * the bits. Subclasses can thus override it in order to extract information
- * from the changes produced to the bits by the given operation.
- */
- public void changed() {}
-
- private void sizeTo(int len) {
+ protected void sizeTo(int len) {
if (bits.length < len) {
bits = Arrays.copyOf(bits, len);
}
@@ -157,16 +133,18 @@
*/
public void clear() {
Assert.check(currentState != BitsState.UNKNOWN);
- oldBits = bits;
- lastOperation = CLEAR;
- for (int i = 0; i < bits.length; i++) bits[i] = 0;
- changed();
+ for (int i = 0; i < bits.length; i++) {
+ bits[i] = 0;
+ }
currentState = BitsState.NORMAL;
}
public void reset() {
+ internalReset();
+ }
+
+ protected void internalReset() {
bits = null;
- oldBits = null;
currentState = BitsState.UNKNOWN;
}
@@ -175,40 +153,40 @@
}
public Bits assign(Bits someBits) {
- lastOperation = ASSIGN;
- oldBits = bits;
bits = someBits.dup().bits;
- changed();
currentState = BitsState.NORMAL;
return this;
}
/** Return a copy of this set.
*/
- private Bits dup() {
+ public Bits dup() {
Assert.check(currentState != BitsState.UNKNOWN);
Bits tmp = new Bits();
- if (currentState != BitsState.NORMAL) {
- tmp.bits = bits;
- } else {
- tmp.bits = new int[bits.length];
- System.arraycopy(bits, 0, tmp.bits, 0, bits.length);
- }
+ tmp.bits = dupBits();
currentState = BitsState.NORMAL;
return tmp;
}
+ protected int[] dupBits() {
+ int [] result;
+ if (currentState != BitsState.NORMAL) {
+ result = bits;
+ } else {
+ result = new int[bits.length];
+ System.arraycopy(bits, 0, result, 0, bits.length);
+ }
+ return result;
+ }
+
/** Include x in this set.
*/
public void incl(int x) {
Assert.check(currentState != BitsState.UNKNOWN);
- Assert.check(x >= 0);
- oldBits = bits;
- lastOperation = INCL_BIT;
+ Assert.check(x >= 0, "Value of x " + x);
sizeTo((x >>> wordshift) + 1);
bits[x >>> wordshift] = bits[x >>> wordshift] |
(1 << (x & wordmask));
- changed();
currentState = BitsState.NORMAL;
}
@@ -217,14 +195,11 @@
*/
public void inclRange(int start, int limit) {
Assert.check(currentState != BitsState.UNKNOWN);
- oldBits = bits;
- lastOperation = INCL_RANGE;
sizeTo((limit >>> wordshift) + 1);
for (int x = start; x < limit; x++) {
bits[x >>> wordshift] = bits[x >>> wordshift] |
(1 << (x & wordmask));
}
- changed();
currentState = BitsState.NORMAL;
}
@@ -232,13 +207,10 @@
*/
public void excludeFrom(int start) {
Assert.check(currentState != BitsState.UNKNOWN);
- oldBits = bits;
- lastOperation = EXCL_RANGE;
Bits temp = new Bits();
temp.sizeTo(bits.length);
temp.inclRange(0, start);
internalAndSet(temp);
- changed();
currentState = BitsState.NORMAL;
}
@@ -247,12 +219,9 @@
public void excl(int x) {
Assert.check(currentState != BitsState.UNKNOWN);
Assert.check(x >= 0);
- oldBits = bits;
- lastOperation = EXCL_BIT;
sizeTo((x >>> wordshift) + 1);
bits[x >>> wordshift] = bits[x >>> wordshift] &
~(1 << (x & wordmask));
- changed();
currentState = BitsState.NORMAL;
}
@@ -269,15 +238,12 @@
*/
public Bits andSet(Bits xs) {
Assert.check(currentState != BitsState.UNKNOWN);
- oldBits = bits;
- lastOperation = AND_SET;
internalAndSet(xs);
- changed();
currentState = BitsState.NORMAL;
return this;
}
- private void internalAndSet(Bits xs) {
+ protected void internalAndSet(Bits xs) {
Assert.check(currentState != BitsState.UNKNOWN);
sizeTo(xs.bits.length);
for (int i = 0; i < xs.bits.length; i++) {
@@ -289,13 +255,10 @@
*/
public Bits orSet(Bits xs) {
Assert.check(currentState != BitsState.UNKNOWN);
- oldBits = bits;
- lastOperation = OR_SET;
sizeTo(xs.bits.length);
for (int i = 0; i < xs.bits.length; i++) {
bits[i] = bits[i] | xs.bits[i];
}
- changed();
currentState = BitsState.NORMAL;
return this;
}
@@ -304,14 +267,11 @@
*/
public Bits diffSet(Bits xs) {
Assert.check(currentState != BitsState.UNKNOWN);
- oldBits = bits;
- lastOperation = DIFF_SET;
for (int i = 0; i < bits.length; i++) {
if (i < xs.bits.length) {
bits[i] = bits[i] & ~xs.bits[i];
}
}
- changed();
currentState = BitsState.NORMAL;
return this;
}
@@ -320,13 +280,10 @@
*/
public Bits xorSet(Bits xs) {
Assert.check(currentState != BitsState.UNKNOWN);
- oldBits = bits;
- lastOperation = XOR_SET;
sizeTo(xs.bits.length);
for (int i = 0; i < xs.bits.length; i++) {
bits[i] = bits[i] ^ xs.bits[i];
}
- changed();
currentState = BitsState.NORMAL;
return this;
}
@@ -336,7 +293,9 @@
*/
private static int trailingZeroBits(int x) {
Assert.check(wordlen == 32);
- if (x == 0) return 32;
+ if (x == 0) {
+ return 32;
+ }
int n = 1;
if ((x & 0xffff) == 0) { n += 16; x >>>= 16; }
if ((x & 0x00ff) == 0) { n += 8; x >>>= 8; }
@@ -355,24 +314,31 @@
public int nextBit(int x) {
Assert.check(currentState != BitsState.UNKNOWN);
int windex = x >>> wordshift;
- if (windex >= bits.length) return -1;
+ if (windex >= bits.length) {
+ return -1;
+ }
int word = bits[windex] & ~((1 << (x & wordmask))-1);
while (true) {
- if (word != 0)
+ if (word != 0) {
return (windex << wordshift) + trailingZeroBits(word);
+ }
windex++;
- if (windex >= bits.length) return -1;
+ if (windex >= bits.length) {
+ return -1;
+ }
word = bits[windex];
}
}
/** a string representation of this set.
*/
+ @Override
public String toString() {
- if (bits.length > 0) {
+ if (bits != null && bits.length > 0) {
char[] digits = new char[bits.length * wordlen];
- for (int i = 0; i < bits.length * wordlen; i++)
+ for (int i = 0; i < bits.length * wordlen; i++) {
digits[i] = isMember(i) ? '1' : '0';
+ }
return new String(digits);
} else {
return "[]";
@@ -396,6 +362,8 @@
System.out.println("found " + i);
count ++;
}
- if (count != 125) throw new Error();
+ if (count != 125) {
+ throw new Error();
+ }
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java Fri Sep 20 19:15:59 2013 -0700
@@ -33,6 +33,18 @@
public class GraphUtils {
/**
+ * Basic interface for defining various dependency kinds. All dependency kinds
+ * must at least support basic capabilities to tell the DOT engine how to render them.
+ */
+ public interface DependencyKind {
+ /**
+ * Returns the DOT representation (to be used in a {@code style} attribute
+ * that's most suited for this dependency kind.
+ */
+ String getDotStyle();
+ }
+
+ /**
* This class is a basic abstract class for representing a node.
* A node is associated with a given data.
*/
@@ -43,9 +55,20 @@
this.data = data;
}
- public abstract Iterable<? extends Node<D>> getDependencies();
+ /**
+ * Get an array of the dependency kinds supported by this node.
+ */
+ public abstract DependencyKind[] getSupportedDependencyKinds();
- public abstract String printDependency(Node<D> to);
+ /**
+ * Get all dependencies, regardless of their kind.
+ */
+ public abstract Iterable<? extends Node<D>> getAllDependencies();
+
+ /**
+ * Get a name for the dependency (of given kind) linking this node to a given node
+ */
+ public abstract String getDependencyName(Node<D> to, DependencyKind dk);
@Override
public String toString() {
@@ -66,7 +89,9 @@
super(data);
}
- public abstract Iterable<? extends TarjanNode<D>> getDependencies();
+ public abstract Iterable<? extends TarjanNode<D>> getAllDependencies();
+
+ public abstract Iterable<? extends TarjanNode<D>> getDependenciesByKind(DependencyKind dk);
public int compareTo(TarjanNode<D> o) {
return (index < o.index) ? -1 : (index == o.index) ? 0 : 1;
@@ -95,7 +120,7 @@
index++;
stack.prepend(v);
v.active = true;
- for (TarjanNode<D> nd: v.getDependencies()) {
+ for (TarjanNode<D> nd: v.getAllDependencies()) {
@SuppressWarnings("unchecked")
N n = (N)nd;
if (n.index == -1) {
@@ -134,9 +159,11 @@
}
//dump arcs
for (TarjanNode<D> from : nodes) {
- for (TarjanNode<D> to : from.getDependencies()) {
- buf.append(String.format("%s -> %s [label = \" %s \"];\n",
- from.hashCode(), to.hashCode(), from.printDependency(to)));
+ for (DependencyKind dk : from.getSupportedDependencyKinds()) {
+ for (TarjanNode<D> to : from.getDependenciesByKind(dk)) {
+ buf.append(String.format("%s -> %s [label = \" %s \" style = %s ];\n",
+ from.hashCode(), to.hashCode(), from.getDependencyName(to, dk), dk.getDotStyle()));
+ }
}
}
buf.append("}\n");
--- a/langtools/src/share/classes/com/sun/tools/javac/util/List.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/List.java Fri Sep 20 19:15:59 2013 -0700
@@ -116,6 +116,19 @@
return buf.toList();
}
+ /**
+ * Create a new list from the first {@code n} elements of this list
+ */
+ public List<A> take(int n) {
+ ListBuffer<A> buf = ListBuffer.lb();
+ int count = 0;
+ for (A el : this) {
+ if (count++ == n) break;
+ buf.append(el);
+ }
+ return buf.toList();
+ }
+
/** Construct a list consisting of given element.
*/
public static <A> List<A> of(A x1) {
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java Fri Sep 20 19:15:59 2013 -0700
@@ -40,7 +40,7 @@
public class AnnotatedTypeImpl
extends AbstractTypeImpl implements AnnotatedType {
- AnnotatedTypeImpl(DocEnv env, com.sun.tools.javac.code.Type.AnnotatedType type) {
+ AnnotatedTypeImpl(DocEnv env, com.sun.tools.javac.code.Type type) {
super(env, type);
}
@@ -50,7 +50,7 @@
*/
@Override
public AnnotationDesc[] annotations() {
- List<TypeCompound> tas = ((com.sun.tools.javac.code.Type.AnnotatedType)type).typeAnnotations;
+ List<? extends TypeCompound> tas = type.getAnnotationMirrors();
if (tas == null ||
tas.isEmpty()) {
return new AnnotationDesc[0];
@@ -65,7 +65,7 @@
@Override
public com.sun.javadoc.Type underlyingType() {
- return TypeMaker.getType(env, ((com.sun.tools.javac.code.Type.AnnotatedType)type).underlyingType, true, false);
+ return TypeMaker.getType(env, type.unannotatedType(), true, false);
}
@Override
--- a/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java Fri Sep 20 19:15:59 2013 -0700
@@ -289,7 +289,7 @@
}
public boolean isFunctionalInterface() {
- return env.types.isFunctionalInterface(tsym);
+ return env.types.isFunctionalInterface(tsym) && env.source.allowLambda();
}
/**
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java Fri Sep 20 19:15:59 2013 -0700
@@ -124,6 +124,11 @@
private boolean silent = false;
/**
+ * The source language version.
+ */
+ protected Source source;
+
+ /**
* Constructor
*
* @param context Context for this javadoc instance.
@@ -144,6 +149,7 @@
// Default. Should normally be reset with setLocale.
this.doclocale = new DocLocale(this, "", breakiterator);
+ source = Source.instance(context);
}
public void setSilent(boolean silent) {
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -134,7 +134,7 @@
docenv.setEncoding(encoding);
docenv.docClasses = docClasses;
docenv.legacyDoclet = legacyDoclet;
- javadocReader.sourceCompleter = docClasses ? null : this;
+ javadocReader.sourceCompleter = docClasses ? null : thisCompleter;
ListBuffer<String> names = new ListBuffer<String>();
ListBuffer<JCCompilationUnit> classTrees = new ListBuffer<JCCompilationUnit>();
--- a/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java Fri Sep 20 19:15:59 2013 -0700
@@ -63,10 +63,8 @@
t = env.types.erasure(t);
}
- if (considerAnnotations &&
- t.isAnnotated()) {
- Type.AnnotatedType at = (Type.AnnotatedType) t;
- return new AnnotatedTypeImpl(env, at);
+ if (considerAnnotations && t.isAnnotated()) {
+ return new AnnotatedTypeImpl(env, t);
}
switch (t.getTag()) {
@@ -143,8 +141,7 @@
static String getTypeString(DocEnv env, Type t, boolean full) {
// TODO: should annotations be included here?
if (t.isAnnotated()) {
- Type.AnnotatedType at = (Type.AnnotatedType)t;
- t = at.underlyingType;
+ t = t.unannotatedType();
}
switch (t.getTag()) {
case ARRAY:
--- a/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java Fri Sep 20 19:15:59 2013 -0700
@@ -140,7 +140,7 @@
if (!type.isAnnotated()) {
return new AnnotationDesc[0];
}
- List<TypeCompound> tas = ((com.sun.tools.javac.code.Type.AnnotatedType) type).typeAnnotations;
+ List<? extends TypeCompound> tas = type.getAnnotationMirrors();
AnnotationDesc res[] = new AnnotationDesc[tas.length()];
int i = 0;
for (Attribute.Compound a : tas) {
--- a/langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4638136
+ * @bug 4638136 7198273
* @summary Add ability to skip over nav bar for accessibility
* @author dkramer
* @run main AccessSkipNav
@@ -42,7 +42,7 @@
*/
public class AccessSkipNav {
- private static final String BUGID = "4638136";
+ private static final String BUGID = "4638136 - 7198273";
private static final String BUGNAME = "AccessSkipNav";
private static final String FS = System.getProperty("file.separator");
private static final String PS = System.getProperty("path.separator");
@@ -86,7 +86,7 @@
// Testing only for the presence of the <a href> and <a name>
// Top navbar <a href>
- { "<a href=\"#skip-navbar_top\" title=\"Skip navigation links\"></a>",
+ { "<a href=\"#skip-navbar_top\" title=\"Skip navigation links\">Skip navigation links</a>",
TMPDEST_DIR1 + "p1" + FS + "C1.html" },
// Top navbar <a name>
@@ -95,7 +95,7 @@
TMPDEST_DIR1 + "p1" + FS + "C1.html" },
// Bottom navbar <a href>
- { "<a href=\"#skip-navbar_bottom\" title=\"Skip navigation links\"></a>",
+ { "<a href=\"#skip-navbar_bottom\" title=\"Skip navigation links\">Skip navigation links</a>",
TMPDEST_DIR1 + "p1" + FS + "C1.html" },
// Bottom navbar <a name>
--- a/langtools/test/com/sun/javadoc/testGeneratedBy/TestGeneratedBy.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testGeneratedBy/TestGeneratedBy.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8000418
+ * @bug 8000418 8024288
* @summary Verify that files use a common Generated By string
* @library ../lib/
* @build JavadocTester TestGeneratedBy
@@ -50,32 +50,44 @@
"index.html"
};
- private static final String[] ARGS =
+ private static final String[] STD_ARGS =
new String[] {
"-d", OUTPUT_DIR,
"-sourcepath", SRC_DIR,
"pkg"
};
- private static final String BUG_ID = "8000418";
- private static String[][] getTests() {
+ private static final String[] NO_TIMESTAMP_ARGS =
+ new String[] {
+ "-notimestamp",
+ "-d", OUTPUT_DIR,
+ "-sourcepath", SRC_DIR,
+ "pkg"
+ };
+
+ private static final String BUG_ID = "8000418-8024288";
+
+ private static String[][] getTests(boolean timestamp) {
String version = System.getProperty("java.version");
String[][] tests = new String[FILES.length][];
for (int i = 0; i < FILES.length; i++) {
+ String genBy = "Generated by javadoc";
+ if (timestamp) genBy += " (" + version + ") on ";
tests[i] = new String[] {
- OUTPUT_DIR + FS + FILES[i],
- "Generated by javadoc (" + version + ") on "
+ OUTPUT_DIR + FS + FILES[i], genBy
};
}
return tests;
}
- private static String[][] getNegatedTests() {
+ private static String[][] getNegatedTests(boolean timestamp) {
String[][] tests = new String[FILES.length][];
for (int i = 0; i < FILES.length; i++) {
tests[i] = new String[] {
OUTPUT_DIR + FS + FILES[i],
- "Generated by javadoc (version",
+ (timestamp
+ ? "Generated by javadoc (version"
+ : "Generated by javadoc ("),
"Generated by javadoc on"
};
}
@@ -88,9 +100,10 @@
*/
public static void main(String[] args) {
TestGeneratedBy tester = new TestGeneratedBy();
- int exitCode = run(tester, ARGS, getTests(), getNegatedTests());
+ int ec1 = run(tester, STD_ARGS, getTests(true), getNegatedTests(true));
+ int ec2 = run(tester, NO_TIMESTAMP_ARGS, getTests(false), getNegatedTests(false));
tester.printSummary();
- if (exitCode != 0) {
+ if (ec1 != 0 || ec2 != 0) {
throw new Error("Error found while executing Javadoc");
}
}
--- a/langtools/test/com/sun/javadoc/testLambdaFeature/TestLambdaFeature.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testLambdaFeature/TestLambdaFeature.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8004893
+ * @bug 8004893 8022738
* @summary Make sure that the lambda feature changes work fine in
* javadoc.
* @author bpatel
@@ -35,11 +35,15 @@
public class TestLambdaFeature extends JavadocTester {
//Test information.
- private static final String BUG_ID = "8004893";
+ private static final String BUG_ID = "8004893-8022738";
//Javadoc arguments.
private static final String[] ARGS = new String[] {
- "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg"
+ "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", "pkg1"
+ };
+
+ private static final String[] ARGS_1 = new String[] {
+ "-d", BUG_ID + "-2", "-sourcepath", SRC_DIR, "-source", "1.5", "pkg1"
};
//Input for string search tests.
@@ -63,6 +67,11 @@
"<dl>" + NL + "<dt>Functional Interface:</dt>" + NL +
"<dd>This is a functional interface and can therefore be used as " +
"the assignment target for a lambda expression or method " +
+ "reference.</dd>" + NL + "</dl>"},
+ {BUG_ID + FS + "pkg1" + FS + "FuncInf.html",
+ "<dl>" + NL + "<dt>Functional Interface:</dt>" + NL +
+ "<dd>This is a functional interface and can therefore be used as " +
+ "the assignment target for a lambda expression or method " +
"reference.</dd>" + NL + "</dl>"}
};
private static final String[][] NEGATED_TEST = {
@@ -75,6 +84,10 @@
{BUG_ID + FS + "pkg" + FS + "B.html",
"<dl>" + NL + "<dt>Functional Interface:</dt>"}
};
+ private static final String[][] NEGATED_TEST_1 = {
+ {BUG_ID + "-2" + FS + "pkg1" + FS + "FuncInf.html",
+ "<dl>" + NL + "<dt>Functional Interface:</dt>"}
+ };
/**
* The entry point of the test.
@@ -83,6 +96,7 @@
public static void main(String[] args) {
TestLambdaFeature tester = new TestLambdaFeature();
run(tester, ARGS, TEST, NEGATED_TEST);
+ run(tester, ARGS_1, NO_TEST, NEGATED_TEST_1);
tester.printSummary();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testLambdaFeature/pkg1/FuncInf.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,29 @@
+/*
+ * 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 pkg1;
+
+public interface FuncInf<V> {
+
+ V call() throws Exception;
+}
--- a/langtools/test/com/sun/javadoc/testLegacyTaglet/C.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testLegacyTaglet/C.java Fri Sep 20 19:15:59 2013 -0700
@@ -25,5 +25,13 @@
/**
* This is an {@underline underline}.
* @todo Finish this class.
+ * @check Check this.
*/
-public class C {}
+public class C {
+
+ /**
+ * @todo Tag in Method.
+ */
+ public void mtd() {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testLegacyTaglet/Check.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,143 @@
+/*
+ * 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.sun.tools.doclets.Taglet;
+import com.sun.javadoc.*;
+import java.util.Map;
+
+public class Check implements Taglet {
+
+ private static final String TAG_NAME = "check";
+ private static final String TAG_HEADER = "Check:";
+
+ /**
+ * Return true since the tag can be used in package documentation.
+ *
+ * @return true since the tag can be used in package documentation.
+ */
+ public boolean inPackage() {
+ return true;
+ }
+
+ /**
+ * Return true since the tag can be used in overview documentation.
+ *
+ * @return true since the tag can be used in overview documentation.
+ */
+ public boolean inOverview() {
+ return true;
+ }
+
+ /**
+ * Return true since the tag can be used in type (class/interface)
+ * documentation.
+ *
+ * @return true since the tag can be used in type (class/interface)
+ * documentation.
+ */
+ public boolean inType() {
+ return true;
+ }
+
+ /**
+ * Return true since the tag can be used in constructor documentation.
+ *
+ * @return true since the tag can be used in constructor documentation.
+ */
+ public boolean inConstructor() {
+ return true;
+ }
+
+ /**
+ * Return true since the tag can be used in field documentation.
+ *
+ * @return true since the tag can be used in field documentation.
+ */
+ public boolean inField() {
+ return true;
+ }
+
+ /**
+ * Return true since the tag can be used in method documentation.
+ *
+ * @return true since the tag can be used in method documentation.
+ */
+ public boolean inMethod() {
+ return true;
+ }
+
+ /**
+ * Return false since the tag is not an inline tag.
+ *
+ * @return false since the tag is not an inline tag.
+ */
+ public boolean isInlineTag() {
+ return false;
+ }
+
+ /**
+ * Register this taglet.
+ *
+ * @param tagletMap the map to register this tag to.
+ */
+ @SuppressWarnings("unchecked")
+ public static void register(Map tagletMap) {
+ Check tag = new Check();
+ Taglet t = (Taglet) tagletMap.get(tag.getName());
+ if (t != null) {
+ tagletMap.remove(tag.getName());
+ }
+ tagletMap.put(tag.getName(), tag);
+ }
+
+ /**
+ * Return the name of this custom tag.
+ *
+ * @return the name of this tag.
+ */
+ public String getName() {
+ return TAG_NAME;
+ }
+
+ /**
+ * Given the tag representation of this custom tag, return its string
+ * representation.
+ *
+ * @param tag the tag representation of this custom tag.
+ */
+ public String toString(Tag tag) {
+ return "<dt><span class=\"strong\">" + TAG_HEADER + ":</span></dt><dd>" + tag.text() +
+ "</dd>\n";
+ }
+
+ /**
+ * Given an array of tags representing this custom tag, return its string
+ * representation.
+ *
+ * @param tags the array of tags representing of this custom tag.
+ * @return null to test if the javadoc throws an exception or not.
+ */
+ public String toString(Tag[] tags) {
+ return null;
+ }
+}
--- a/langtools/test/com/sun/javadoc/testLegacyTaglet/TestLegacyTaglet.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testLegacyTaglet/TestLegacyTaglet.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,32 +23,33 @@
/*
* @test
- * @bug 4638723
+ * @bug 4638723 8015882
* @summary Test to ensure that the refactored version of the standard
* doclet still works with Taglets that implement the 1.4.0 interface.
* @author jamieh
* @library ../lib/
- * @compile ../lib/JavadocTester.java
- * @compile TestLegacyTaglet.java
- * @compile ToDoTaglet.java
- * @compile UnderlineTaglet.java
+ * @compile ../lib/JavadocTester.java TestLegacyTaglet.java ToDoTaglet.java UnderlineTaglet.java Check.java
* @run main TestLegacyTaglet
*/
public class TestLegacyTaglet extends JavadocTester {
- private static final String BUG_ID = "4638723";
+ private static final String BUG_ID = "4638723-8015882";
private static final String[] ARGS =
new String[] {"-d", BUG_ID, "-sourcepath", SRC_DIR,
- "-tagletpath", SRC_DIR, "-taglet", "ToDoTaglet",
+ "-tagletpath", SRC_DIR, "-taglet", "ToDoTaglet", "-taglet", "Check",
"-taglet", "UnderlineTaglet", SRC_DIR + FS + "C.java"};
private static final String[][] TEST = new String[][] {
{BUG_ID + FS + "C.html", "This is an <u>underline</u>"},
{BUG_ID + FS + "C.html",
"<DT><B>To Do:</B><DD><table cellpadding=2 cellspacing=0><tr>" +
- "<td bgcolor=\"yellow\">Finish this class.</td></tr></table></DD>"}};
+ "<td bgcolor=\"yellow\">Finish this class.</td></tr></table></DD>"},
+ {BUG_ID + FS + "C.html",
+ "<DT><B>To Do:</B><DD><table cellpadding=2 cellspacing=0><tr>" +
+ "<td bgcolor=\"yellow\">Tag in Method.</td></tr></table></DD>"}
+ };
private static final String[][] NEGATED_TEST = NO_TEST;
@@ -59,6 +60,9 @@
public static void main(String[] args) {
TestLegacyTaglet tester = new TestLegacyTaglet();
run(tester, ARGS, TEST, NEGATED_TEST);
+ if (tester.getErrorOutput().contains("NullPointerException")) {
+ throw new AssertionError("javadoc threw NullPointerException");
+ }
tester.printSummary();
}
--- a/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java Fri Sep 20 19:15:59 2013 -0700
@@ -23,13 +23,12 @@
/*
* @test
- * @bug 4131628 4664607 7025314
+ * @bug 4131628 4664607 7025314 8023700 7198273
* @summary Make sure the Next/Prev Class links iterate through all types.
* Make sure the navagation is 2 columns, not 3.
* @author jamieh
* @library ../lib/
- * @build JavadocTester
- * @build TestNavigation
+ * @build JavadocTester TestNavigation
* @run main TestNavigation
*/
@@ -45,23 +44,23 @@
//Input for string search tests.
private static final String[][] TEST = {
- {BUG_ID + FS + "pkg" + FS + "A.html", "<li>Prev Class</li>"},
+ {BUG_ID + FS + "pkg" + FS + "A.html", "<li>Prev Class</li>"},
{BUG_ID + FS + "pkg" + FS + "A.html",
- "<a href=\"../pkg/C.html\" title=\"class in pkg\"><span class=\"strong\">Next Class</span></a>"},
+ "<a href=\"../pkg/C.html\" title=\"class in pkg\"><span class=\"strong\">Next Class</span></a>"},
{BUG_ID + FS + "pkg" + FS + "C.html",
- "<a href=\"../pkg/A.html\" title=\"annotation in pkg\"><span class=\"strong\">Prev Class</span></a>"},
+ "<a href=\"../pkg/A.html\" title=\"annotation in pkg\"><span class=\"strong\">Prev Class</span></a>"},
{BUG_ID + FS + "pkg" + FS + "C.html",
- "<a href=\"../pkg/E.html\" title=\"enum in pkg\"><span class=\"strong\">Next Class</span></a>"},
+ "<a href=\"../pkg/E.html\" title=\"enum in pkg\"><span class=\"strong\">Next Class</span></a>"},
{BUG_ID + FS + "pkg" + FS + "E.html",
- "<a href=\"../pkg/C.html\" title=\"class in pkg\"><span class=\"strong\">Prev Class</span></a>"},
+ "<a href=\"../pkg/C.html\" title=\"class in pkg\"><span class=\"strong\">Prev Class</span></a>"},
{BUG_ID + FS + "pkg" + FS + "E.html",
- "<a href=\"../pkg/I.html\" title=\"interface in pkg\"><span class=\"strong\">Next Class</span></a>"},
+ "<a href=\"../pkg/I.html\" title=\"interface in pkg\"><span class=\"strong\">Next Class</span></a>"},
{BUG_ID + FS + "pkg" + FS + "I.html",
- "<a href=\"../pkg/E.html\" title=\"enum in pkg\"><span class=\"strong\">Prev Class</span></a>"},
- {BUG_ID + FS + "pkg" + FS + "I.html", "<li>Next Class</li>"},
+ "<a href=\"../pkg/E.html\" title=\"enum in pkg\"><span class=\"strong\">Prev Class</span></a>"},
+ {BUG_ID + FS + "pkg" + FS + "I.html", "<li>Next Class</li>"},
// Test for 4664607
{BUG_ID + FS + "pkg" + FS + "I.html",
- "<a href=\"#skip-navbar_top\" title=\"Skip navigation links\"></a><a name=\"navbar_top_firstrow\">" + NL +
+ "<div class=\"skipNav\"><a href=\"#skip-navbar_top\" title=\"Skip navigation links\">Skip navigation links</a></div>" + NL + "<a name=\"navbar_top_firstrow\">" + NL +
"<!-- -->" + NL + "</a>"}
};
private static final String[][] NEGATED_TEST = NO_TEST;
--- a/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java Fri Sep 20 19:15:59 2013 -0700
@@ -23,9 +23,9 @@
/*
* @test
- * @bug 8006124 8009684 8016921
+ * @bug 8006124 8009684 8016921 8023700
* @summary Test javadoc support for profiles.
- * @author Bhavesh Patel
+ * @author Bhavesh Patel, Evgeniya Stepanova
* @library ../lib/
* @build JavadocTester TestProfiles
* @run main TestProfiles
@@ -38,8 +38,9 @@
private static final String PACKAGE_BUG_ID = BUG_ID + "-2";
//Javadoc arguments.
private static final String[] ARGS1 = new String[]{
- "-d", PROFILE_BUG_ID, "-sourcepath", SRC_DIR, "-Xprofilespath", SRC_DIR + FS
- + "profile-rtjar-includes.txt", "pkg1", "pkg2", "pkg3", "pkg4", "pkg5"
+ "-d", PROFILE_BUG_ID, "-sourcepath", SRC_DIR, "-Xprofilespath",
+ SRC_DIR + FS + "profile-rtjar-includes.txt", "pkg1", "pkg2",
+ "pkg3", "pkg4", "pkg5", "pkgDeprecated"
};
private static final String[] ARGS2 = new String[]{
"-d", PACKAGE_BUG_ID, "-sourcepath", SRC_DIR, "pkg1", "pkg2", "pkg3", "pkg4", "pkg5"
@@ -49,7 +50,7 @@
// Tests for profile-overview-frame.html listing all profiles.
{PROFILE_BUG_ID + FS + "profile-overview-frame.html",
"<span><a href=\"overview-frame.html\" "
- + "target=\"packageListFrame\">All Packages</a></span>"
+ + "target=\"packageListFrame\">All Packages</a></span>"
},
{PROFILE_BUG_ID + FS + "profile-overview-frame.html",
"<li><a href=\"compact1-frame.html\" target=\"packageListFrame\">"
@@ -58,8 +59,8 @@
// Tests for profileName-frame.html listing all packages in a profile.
{PROFILE_BUG_ID + FS + "compact2-frame.html",
"<span><a href=\"overview-frame.html\" target=\"packageListFrame\">"
- + "All Packages</a></span><span><a href=\"profile-overview-frame.html\" "
- + "target=\"packageListFrame\">All Profiles</a></span>"
+ + "All Packages</a></span><span><a href=\"profile-overview-frame.html\" "
+ + "target=\"packageListFrame\">All Profiles</a></span>"
},
{PROFILE_BUG_ID + FS + "compact2-frame.html",
"<li><a href=\"pkg4/compact2-package-frame.html\" "
@@ -74,8 +75,8 @@
},
// Tests for profileName-summary.html listing the summary for a profile.
{PROFILE_BUG_ID + FS + "compact2-summary.html",
- "<li><a href=\"compact1-summary.html\">Prev Profile</a></li>" + NL
- + "<li><a href=\"compact3-summary.html\">Next Profile</a></li>"
+ "<li><a href=\"compact1-summary.html\">Prev Profile</a></li>" + NL
+ + "<li><a href=\"compact3-summary.html\">Next Profile</a></li>"
},
{PROFILE_BUG_ID + FS + "compact2-summary.html",
"<h1 title=\"Profile\" class=\"title\">Profile compact2</h1>"
@@ -87,7 +88,7 @@
// Tests for profileName-package-summary.html listing the summary for a
// package in a profile.
{PROFILE_BUG_ID + FS + "pkg5" + FS + "compact3-package-summary.html",
- "<li><a href=\"../pkg4/compact3-package-summary.html\">Prev Package"
+ "<li><a href=\"../pkg4/compact3-package-summary.html\">Prev Package"
+ "</a></li>"
},
{PROFILE_BUG_ID + FS + "pkg5" + FS + "compact3-package-summary.html",
@@ -96,7 +97,7 @@
//Test for "overview-frame.html" showing the "All Profiles" link.
{PROFILE_BUG_ID + FS + "overview-frame.html",
"<span><a href=\"profile-overview-frame.html\" "
- + "target=\"packageListFrame\">All Profiles</a></span>"
+ + "target=\"packageListFrame\">All Profiles</a></span>"
},
//Test for "className.html" showing the profile information for the type.
{PROFILE_BUG_ID + FS + "pkg2" + FS + "Class1Pkg2.html",
@@ -113,6 +114,49 @@
"target=\"classFrame\">compact2</a></li>" + NL + "<li><a href=\"" +
"compact3-summary.html\" target=\"classFrame\">compact3</a></li>" + NL +
"</ul>"
+ },
+ //Test deprecated class in profiles
+ {PROFILE_BUG_ID + FS + "compact1-summary.html","<td class=\"colFirst\">"
+ + "<a href=\"pkg2/Class1Pkg2.html\" title=\"class in pkg2\">Class1Pkg2</a></td>"
+ + NL + "<td class=\"colLast\">Deprecated"
+ },
+ {PROFILE_BUG_ID + FS + "deprecated-list.html","<td class=\"colOne\">"
+ + "<a href=\"pkg2/Class1Pkg2.html\" title=\"class in pkg2\">pkg2.Class1Pkg2</a>"
+ + NL +"<div class=\"block\"><span class=\"italic\">Class1Pkg2. This class is deprecated</span></div>"
+ },
+ //Test deprecated package in profile
+ {PROFILE_BUG_ID + FS + "deprecated-list.html","<td class=\"colOne\">"
+ + "<a href=\"pkgDeprecated/package-summary.html\">pkgDeprecated</a>"
+ + NL +"<div class=\"block\"><span class=\"italic\">This package is <b>Deprecated</b>."
+ + " Use pkg1.</span></div>"
+ },
+ {PROFILE_BUG_ID + FS + "pkgDeprecated" + FS + "package-summary.html",
+ "<div class=\"deprecatedContent\"><span class=\"strong\">Deprecated.</span>"
+ + NL + "<div class=\"block\"><span class=\"italic\">This package is <b>Deprecated</b>."
+ + " Use pkg1.</span></div>"
+ },
+ // need to add teststring when JDK-8015496 will be fixed
+ //Test exception in profiles
+ {PROFILE_BUG_ID + FS + "compact1-summary.html","<table class=\"packageSummary\" "
+ + "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" "
+ + "summary=\"Exception Summary table, listing exceptions, and an explanation\">"
+ + NL + "<caption><span>Exception Summary</span><span class=\"tabEnd\">"
+ + " </span></caption>" + NL + "<tr>" + NL + "<th class=\"colFirst\" "
+ + "scope=\"col\">Exception</th>" + NL + "<th class=\"colLast\" scope=\"col\">"
+ + "Description</th>" + NL + "</tr>" + NL + "<tbody>" + NL + "<tr class=\"altColor\">"
+ + NL + "<td class=\"colFirst\"><a href=\"pkg2/ClassException.html\""
+ + " title=\"class in pkg2\">ClassException</a></td>"
+ },
+ //Test errors in profiles
+ {PROFILE_BUG_ID + FS + "compact1-summary.html",
+ "<table class=\"packageSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" "
+ + "summary=\"Error Summary table, listing errors, and an explanation\">"
+ + NL + "<caption><span>Error Summary</span><span class=\"tabEnd\"> "
+ + "</span></caption>" + NL + "<tr>" + NL + "<th class=\"colFirst\""
+ + " scope=\"col\">Error</th>" + NL + "<th class=\"colLast\" "
+ + "scope=\"col\">Description</th>" + NL + "</tr>" + NL + "<tbody>"
+ + NL + "<tr class=\"altColor\">" + NL + "<td class=\"colFirst\">"
+ + "<a href=\"pkg2/ClassError.html\" title=\"class in pkg2\">ClassError</a></td>"
}
};
private static final String[][] PROFILES_NEGATED_TEST = {
@@ -125,6 +169,8 @@
{PROFILE_BUG_ID + FS + "pkg4" + FS + "compact2-package-frame.html",
"<li><a href=\"Anno1Pkg4.html\" title=\"annotation in pkg4\" "
+ "target=\"classFrame\">Anno1Pkg4</a></li>"
+ },
+ {PROFILE_BUG_ID + FS + "compact1-summary.html","<li>Use</li>"
}
};
private static final String[][] PACKAGES_TEST = {
@@ -143,12 +189,12 @@
private static final String[][] PACKAGES_NEGATED_TEST = {
{PACKAGE_BUG_ID + FS + "profile-overview-frame.html",
"<span><a href=\"overview-frame.html\" "
- + "target=\"packageListFrame\">All Packages</a></span>"
+ + "target=\"packageListFrame\">All Packages</a></span>"
},
{PACKAGE_BUG_ID + FS + "compact2-frame.html",
"<span><a href=\"overview-frame.html\" target=\"packageListFrame\">"
- + "All Packages</a></span><span><a href=\"profile-overview-frame.html\" "
- + "target=\"packageListFrame\">All Profiles</a></span>"
+ + "All Packages</a></span><span><a href=\"profile-overview-frame.html\" "
+ + "target=\"packageListFrame\">All Profiles</a></span>"
},
{PACKAGE_BUG_ID + FS + "pkg2" + FS + "compact2-package-frame.html",
"<a href=\"../compact2-summary.html\" target=\"classFrame\">"
@@ -163,7 +209,7 @@
},
{PACKAGE_BUG_ID + FS + "overview-frame.html",
"<span><a href=\"profile-overview-frame.html\" "
- + "target=\"packageListFrame\">All Profiles</a></span>"
+ + "target=\"packageListFrame\">All Profiles</a></span>"
},
{PACKAGE_BUG_ID + FS + "pkg2" + FS + "Class1Pkg2.html",
"<div class=\"subTitle\">compact1, compact2, compact3</div>"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testProfiles/TestProfilesConfiguration.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,127 @@
+/*
+ * 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 8006124 8009684 8015663 8015496
+ * @summary Test javadoc options support for profiles.
+ * @author Evgeniya Stepanova
+ * @library ../lib/
+ * @build JavadocTester TestProfilesConfiguration
+ * @run main TestProfilesConfiguration
+ */
+public class TestProfilesConfiguration extends JavadocTester {
+
+ //Test information.
+ private static final String BUG_ID = "8006124-8009684";
+ private static final String PROFILE_CONFIGURATION_BUG_ID = BUG_ID + "-3";
+ private static final String NODEPR_NOPKGS_BUG_ID = BUG_ID + "-4";
+ //Javadoc arguments.
+ private static final String[] ARGS3 = new String[]{
+ "-d", PROFILE_CONFIGURATION_BUG_ID, "-sourcepath", SRC_DIR, "-nocomment",
+ "-keywords", "-Xprofilespath", SRC_DIR + FS + "profile-rtjar-includes.txt",
+ "-doctitle", "Simple doctitle", "-use", "pkg3", "pkg1", "pkg2", "pkg4",
+ "pkg5", "-packagesheader", "Simple packages header","pkgDeprecated"
+ };
+ private static final String[] ARGS4 = new String[]{
+ "-d", NODEPR_NOPKGS_BUG_ID, "-sourcepath", SRC_DIR, "-nocomment", "-nodeprecated",
+ "-keywords", "-Xprofilespath", SRC_DIR + FS + "profile-rtjar-includes-nopkgs.txt",
+ "-doctitle", "Simple doctitle", "-use", "-packagesheader", "Simple packages header",
+ "pkg1", "pkg2", "pkg3", "pkg4", "pkg5", "pkgDeprecated"
+ };
+ private static final String[][] NODEPR_NOPKGS_TEST = {
+ {NODEPR_NOPKGS_BUG_ID + FS + "overview-summary.html",
+ "<ul>" + NL + "<li><a href=\"compact2-summary.html\" target=\"classFrame\">" +
+ "compact2</a></li>" + NL + "<li><a href=\"compact3-summary.html\" target=\"" +
+ "classFrame\">compact3</a></li>" + NL + "</ul>"
+ },
+ {NODEPR_NOPKGS_BUG_ID + FS + "profile-overview-frame.html",
+ "<ul title=\"Profiles\">" + NL + "<li><a href=\"compact2-frame.html\" target=\"packageListFrame\">" +
+ "compact2</a></li>" + NL + "<li><a href=\"compact3-frame.html\" target=\"" +
+ "packageListFrame\">compact3</a></li>" + NL + "</ul>"
+ }
+ };
+ private static final String[][] NODEPR_NOPKGS_NEGATED_TEST = {
+ {NODEPR_NOPKGS_BUG_ID + FS + "overview-summary.html",
+ "compact1"
+ }
+ };
+
+ private static final String[][] PROFILES_CONFIGURATION_TEST = {
+ //-use option test string fo profile view page
+ {PROFILE_CONFIGURATION_BUG_ID + FS + "compact1-summary.html","<li>Use</li>"
+ },
+ //-doctitle option test string
+ {PROFILE_CONFIGURATION_BUG_ID + FS + "overview-summary.html",
+ "<div class=\"header\">" + NL + "<h1 class=\"title\">Simple doctitle</h1>"
+ },
+ //-packagesheader option test string fo profiles
+ {PROFILE_CONFIGURATION_BUG_ID + FS + "profile-overview-frame.html",
+ "<h1 title=\"Simple packages header\" class=\"bar\">Simple packages header</h1>"
+ },
+ //-keywords option test string for profiles
+ {PROFILE_CONFIGURATION_BUG_ID + FS + "compact1-summary.html",
+ "<meta name=\"keywords\" content=\"compact1 profile\">"
+ },
+ //Deprecated information on a package
+ {PROFILE_CONFIGURATION_BUG_ID + FS + "compact1-summary.html",
+ "<h3><a href=\"pkgDeprecated/compact1-package-summary.html\" target=\"" +
+ "classFrame\">pkgDeprecated</a></h3>" + NL + "<div class=\"deprecatedContent\">" +
+ "<span class=\"strong\">Deprecated.</span></div>"
+ }
+ };
+ private static final String[][] PROFILES_CONFIGURATION_NEGATED_TEST = {
+ //-nocomments option test string
+ {PROFILE_CONFIGURATION_BUG_ID + FS + "compact1-summary.html",
+ "<div class=\"block\"><i>Class1Pkg2.</i></div>"
+ }
+ };
+
+ /**
+ * The entry point of the test.
+ *
+ * @param args the array of command line arguments.
+ */
+ public static void main(String[] args) {
+ TestProfilesConfiguration tester = new TestProfilesConfiguration();
+ run(tester, ARGS3, PROFILES_CONFIGURATION_TEST,
+ PROFILES_CONFIGURATION_NEGATED_TEST);
+ run(tester, ARGS4, NODEPR_NOPKGS_TEST,
+ NODEPR_NOPKGS_NEGATED_TEST);
+ tester.printSummary();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getBugId() {
+ return BUG_ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getBugName() {
+ return getClass().getName();
+ }
+}
--- a/langtools/test/com/sun/javadoc/testProfiles/pkg2/Class1Pkg2.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg2/Class1Pkg2.java Fri Sep 20 19:15:59 2013 -0700
@@ -24,7 +24,7 @@
package pkg2;
/**
- * Another test class.
+ * @deprecated Class1Pkg2. This class is deprecated
*
* @author Bhavesh Patel
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg2/ClassError.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,31 @@
+/*
+ * 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 pkg2;
+
+/**
+ * Simple error class.
+ *
+ * @author Evgeniya Stepanova
+ */
+public class ClassError extends Error {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg2/ClassException.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,31 @@
+/*
+ * 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 pkg2;
+
+/**
+ * Simple exception class.
+ *
+ * @author Evgeniya Stepanova
+ */
+public class ClassException extends Exception {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkgDeprecated/Class1PkgDeprecated.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,36 @@
+/*
+ * 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 pkgDeprecated;
+
+/**
+ * Simple deprecated class of deprecated package.
+ *
+ * @author Evgeniya Stepanova
+ */
+public class Class1PkgDeprecated {
+
+ public void method(int t) {
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkgDeprecated/package-info.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+/**
+ * Deprecated package.
+ *
+ * @deprecated This package is <b>Deprecated</b>. Use pkg1.
+ */
+package pkgDeprecated;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testProfiles/profile-rtjar-includes-nopkgs.txt Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,41 @@
+PROFILE_1_RTJAR_INCLUDE_PACKAGES :=
+
+PROFILE_1_RTJAR_INCLUDE_TYPES :=
+
+PROFILE_1_RTJAR_EXCLUDE_TYPES :=
+
+PROFILE_1_INCLUDE_METAINF_SERVICES :=
+
+
+PROFILE_2_RTJAR_INCLUDE_PACKAGES := \
+ pkg4 \
+ pkgDeprecated
+
+PROFILE_2_RTJAR_INCLUDE_TYPES :=
+
+PROFILE_2_RTJAR_EXCLUDE_TYPES := \
+ pkg4/Anno1Pkg4.class
+
+PROFILE_2_INCLUDE_METAINF_SERVICES :=
+
+
+PROFILE_3_RTJAR_INCLUDE_PACKAGES := \
+ pkg5
+
+PROFILE_3_RTJAR_INCLUDE_TYPES :=
+
+PROFILE_3_RTJAR_EXCLUDE_TYPES :=
+
+PROFILE_3_INCLUDE_METAINF_SERVICES :=
+
+
+PROFILE_4_RTJAR_INCLUDE_PACKAGES := \
+ pkg1
+
+PROFILE_4_RTJAR_INCLUDE_TYPES :=
+
+PROFILE_4_RTJAR_EXCLUDE_TYPES :=
+
+PROFILE_4_INCLUDE_METAINF_SERVICES :=
+
+
--- a/langtools/test/com/sun/javadoc/testProfiles/profile-rtjar-includes.txt Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testProfiles/profile-rtjar-includes.txt Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,6 @@
PROFILE_1_RTJAR_INCLUDE_PACKAGES := \
- pkg2
+ pkg2 \
+ pkgDeprecated
PROFILE_1_RTJAR_INCLUDE_TYPES := \
pkg3/Class1Pkg3.class
--- a/langtools/test/com/sun/javadoc/testStylesheet/TestStylesheet.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testStylesheet/TestStylesheet.java Fri Sep 20 19:15:59 2013 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4494033 7028815 7052425 8007338
+ * @bug 4494033 7028815 7052425 8007338 8023608
* @summary Run tests on doclet stylesheet.
* @author jamieh
* @library ../lib/
@@ -72,7 +72,46 @@
" overflow:hidden;" + NL +
" padding:0px;" + NL +
" margin:0px;" + NL +
- " white-space:pre;" + NL +
+ "}"},
+ {BUG_ID + FS + "stylesheet.css",
+ ".overviewSummary caption span, .packageSummary caption span, " +
+ ".contentContainer ul.blockList li.blockList caption span, " +
+ ".summary caption span, .classUseContainer caption span, " +
+ ".constantValuesContainer caption span {" + NL +
+ " white-space:nowrap;" + NL +
+ " padding-top:8px;" + NL +
+ " padding-left:8px;" + NL +
+ " display:inline-block;" + NL +
+ " float:left;" + NL +
+ " background-image:url(resources/titlebar.gif);" + NL +
+ "}"},
+ {BUG_ID + FS + "stylesheet.css",
+ ".contentContainer ul.blockList li.blockList caption " +
+ "span.activeTableTab span {" + NL +
+ " white-space:nowrap;" + NL +
+ " padding-top:8px;" + NL +
+ " padding-left:8px;" + NL +
+ " display:inline-block;" + NL +
+ " float:left;" + NL +
+ " background-image:url(resources/activetitlebar.gif);" + NL +
+ "}"},
+ {BUG_ID + FS + "stylesheet.css",
+ ".contentContainer ul.blockList li.blockList caption span.tableTab span {" + NL +
+ " white-space:nowrap;" + NL +
+ " padding-top:8px;" + NL +
+ " padding-left:8px;" + NL +
+ " display:inline-block;" + NL +
+ " float:left;" + NL +
+ " background-image:url(resources/titlebar.gif);" + NL +
+ "}"},
+ {BUG_ID + FS + "stylesheet.css",
+ ".contentContainer ul.blockList li.blockList caption span.tableTab, " +
+ ".contentContainer ul.blockList li.blockList caption span.activeTableTab {" + NL +
+ " padding-top:0px;" + NL +
+ " padding-left:0px;" + NL +
+ " background-image:none;" + NL +
+ " float:none;" + NL +
+ " display:inline-block;" + NL +
"}"},
// Test whether a link to the stylesheet file is inserted properly
// in the class documentation.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/lib/combo/TEST.properties Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,4 @@
+# This file identifies root(s) of the test-ng hierarchy.
+
+
+TestNG.dirs = .
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/lib/combo/tools/javac/combo/Diagnostics.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,82 @@
+/*
+ * 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 tools.javac.combo;
+
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+import java.util.ArrayList;
+import java.util.List;
+
+import static java.util.stream.Collectors.toList;
+
+/**
+* A container for compiler diagnostics, separated into errors and warnings,
+ * used by JavacTemplateTestBase.
+ *
+ * @author Brian Goetz
+*/
+public class Diagnostics implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+ protected List<Diagnostic<? extends JavaFileObject>> diags = new ArrayList<>();
+ protected boolean foundErrors = false;
+
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ diags.add(diagnostic);
+ foundErrors = foundErrors || diagnostic.getKind() == Diagnostic.Kind.ERROR;
+ }
+
+ /** Were there any errors found? */
+ public boolean errorsFound() {
+ return foundErrors;
+ }
+
+ /** Get all diagnostic keys */
+ public List<String> keys() {
+ return diags.stream()
+ .map(Diagnostic::getCode)
+ .collect(toList());
+ }
+
+ /** Do the diagnostics contain the specified error key? */
+ public boolean containsErrorKey(String key) {
+ return diags.stream()
+ .filter(d -> d.getKind() == Diagnostic.Kind.ERROR)
+ .anyMatch(d -> d.getCode().equals(key));
+ }
+
+ /** Get the error keys */
+ public List<String> errorKeys() {
+ return diags.stream()
+ .filter(d -> d.getKind() == Diagnostic.Kind.ERROR)
+ .map(Diagnostic::getCode)
+ .collect(toList());
+ }
+
+ public String toString() { return keys().toString(); }
+
+ /** Clear all diagnostic state */
+ public void reset() {
+ diags.clear();
+ foundErrors = false;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/lib/combo/tools/javac/combo/JavacTemplateTestBase.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,362 @@
+/*
+ * 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 tools.javac.combo;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.util.Pair;
+import org.testng.ITestResult;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.fail;
+
+/**
+ * Base class for template-driven TestNG javac tests that support on-the-fly
+ * source file generation, compilation, classloading, execution, and separate
+ * compilation.
+ *
+ * <p>Manages a set of templates (which have embedded tags of the form
+ * {@code #\{NAME\}}), source files (which are also templates), and compile
+ * options. Test cases can register templates and source files, cause them to
+ * be compiled, validate whether the set of diagnostic messages output by the
+ * compiler is correct, and optionally load and run the compiled classes.
+ *
+ * @author Brian Goetz
+ */
+@Test
+public abstract class JavacTemplateTestBase {
+ private static final Set<String> suiteErrors = Collections.synchronizedSet(new HashSet<>());
+ private static final AtomicInteger counter = new AtomicInteger();
+ private static final File root = new File("gen");
+ private static final File nullDir = new File("empty");
+
+ protected final Map<String, Template> templates = new HashMap<>();
+ protected final Diagnostics diags = new Diagnostics();
+ protected final List<Pair<String, Template>> sourceFiles = new ArrayList<>();
+ protected final List<String> compileOptions = new ArrayList<>();
+ protected final List<File> classpaths = new ArrayList<>();
+ protected final Template.Resolver defaultResolver = new MapResolver(templates);
+
+ private Template.Resolver currentResolver = defaultResolver;
+
+ /** Add a template with a specified name */
+ protected void addTemplate(String name, Template t) {
+ templates.put(name, t);
+ }
+
+ /** Add a template with a specified name */
+ protected void addTemplate(String name, String s) {
+ templates.put(name, new StringTemplate(s));
+ }
+
+ /** Add a source file */
+ protected void addSourceFile(String name, Template t) {
+ sourceFiles.add(new Pair<>(name, t));
+ }
+
+ /** Add a File to the class path to be used when loading classes; File values
+ * will generally be the result of a previous call to {@link #compile()}.
+ * This enables testing of separate compilation scenarios if the class path
+ * is set up properly.
+ */
+ protected void addClassPath(File path) {
+ classpaths.add(path);
+ }
+
+ /**
+ * Add a set of compilation command-line options
+ */
+ protected void addCompileOptions(String... opts) {
+ Collections.addAll(compileOptions, opts);
+ }
+
+ /** Reset the compile options to the default (empty) value */
+ protected void resetCompileOptions() { compileOptions.clear(); }
+
+ /** Remove all templates */
+ protected void resetTemplates() { templates.clear(); }
+
+ /** Remove accumulated diagnostics */
+ protected void resetDiagnostics() { diags.reset(); }
+
+ /** Remove all source files */
+ protected void resetSourceFiles() { sourceFiles.clear(); }
+
+ /** Remove registered class paths */
+ protected void resetClassPaths() { classpaths.clear(); }
+
+ // Before each test method, reset everything
+ @BeforeMethod
+ public void reset() {
+ resetCompileOptions();
+ resetDiagnostics();
+ resetSourceFiles();
+ resetTemplates();
+ resetClassPaths();
+ }
+
+ // After each test method, if the test failed, capture source files and diagnostics and put them in the log
+ @AfterMethod
+ public void copyErrors(ITestResult result) {
+ if (!result.isSuccess()) {
+ suiteErrors.addAll(diags.errorKeys());
+
+ List<Object> list = new ArrayList<>();
+ Collections.addAll(list, result.getParameters());
+ list.add("Test case: " + getTestCaseDescription());
+ for (Pair<String, Template> e : sourceFiles)
+ list.add("Source file " + e.fst + ": " + e.snd);
+ if (diags.errorsFound())
+ list.add("Compile diagnostics: " + diags.toString());
+ result.setParameters(list.toArray(new Object[list.size()]));
+ }
+ }
+
+ @AfterSuite
+ // After the suite is done, dump any errors to output
+ public void dumpErrors() {
+ if (!suiteErrors.isEmpty())
+ System.err.println("Errors found in test suite: " + suiteErrors);
+ }
+
+ /**
+ * Get a description of this test case; since test cases may be combinatorially
+ * generated, this should include all information needed to describe the test case
+ */
+ protected String getTestCaseDescription() {
+ return this.toString();
+ }
+
+ /** Assert that all previous calls to compile() succeeded */
+ protected void assertCompileSucceeded() {
+ if (diags.errorsFound())
+ fail("Expected successful compilation");
+ }
+
+ /**
+ * If the provided boolean is true, assert all previous compiles succeeded,
+ * otherwise assert that a compile failed.
+ * */
+ protected void assertCompileSucceededIff(boolean b) {
+ if (b)
+ assertCompileSucceeded();
+ else
+ assertCompileFailed();
+ }
+
+ /** Assert that a previous call to compile() failed */
+ protected void assertCompileFailed() {
+ if (!diags.errorsFound())
+ fail("Expected failed compilation");
+ }
+
+ /** Assert that a previous call to compile() failed with a specific error key */
+ protected void assertCompileFailed(String message) {
+ if (!diags.errorsFound())
+ fail("Expected failed compilation: " + message);
+ }
+
+ /** Assert that a previous call to compile() failed with all of the specified error keys */
+ protected void assertCompileErrors(String... keys) {
+ if (!diags.errorsFound())
+ fail("Expected failed compilation");
+ for (String k : keys)
+ if (!diags.containsErrorKey(k))
+ fail("Expected compilation error " + k);
+ }
+
+ /** Convert an object, which may be a Template or a String, into a Template */
+ protected Template asTemplate(Object o) {
+ if (o instanceof Template)
+ return (Template) o;
+ else if (o instanceof String)
+ return new StringTemplate((String) o);
+ else
+ return new StringTemplate(o.toString());
+ }
+
+ /** Compile all registered source files */
+ protected void compile() throws IOException {
+ compile(false);
+ }
+
+ /** Compile all registered source files, optionally generating class files
+ * and returning a File describing the directory to which they were written */
+ protected File compile(boolean generate) throws IOException {
+ List<JavaFileObject> files = new ArrayList<>();
+ for (Pair<String, Template> e : sourceFiles)
+ files.add(new FileAdapter(e.fst, asTemplate(e.snd)));
+ return compile(classpaths, files, generate);
+ }
+
+ /** Compile all registered source files, using the provided list of class paths
+ * for finding required classfiles, optionally generating class files
+ * and returning a File describing the directory to which they were written */
+ protected File compile(List<File> classpaths, boolean generate) throws IOException {
+ List<JavaFileObject> files = new ArrayList<>();
+ for (Pair<String, Template> e : sourceFiles)
+ files.add(new FileAdapter(e.fst, asTemplate(e.snd)));
+ return compile(classpaths, files, generate);
+ }
+
+ private File compile(List<File> classpaths, List<JavaFileObject> files, boolean generate) throws IOException {
+ JavaCompiler systemJavaCompiler = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager fm = systemJavaCompiler.getStandardFileManager(null, null, null);
+ if (classpaths.size() > 0)
+ fm.setLocation(StandardLocation.CLASS_PATH, classpaths);
+ JavacTask ct = (JavacTask) systemJavaCompiler.getTask(null, fm, diags, compileOptions, null, files);
+ if (generate) {
+ File destDir = new File(root, Integer.toString(counter.incrementAndGet()));
+ // @@@ Assert that this directory didn't exist, or start counter at max+1
+ destDir.mkdirs();
+ fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(destDir));
+ ct.generate();
+ return destDir;
+ }
+ else {
+ ct.analyze();
+ return nullDir;
+ }
+ }
+
+ /** Load the given class using the provided list of class paths */
+ protected Class<?> loadClass(String className, File... destDirs) {
+ try {
+ List<URL> list = new ArrayList<>();
+ for (File f : destDirs)
+ list.add(new URL("file:" + f.toString().replace("\\", "/") + "/"));
+ return Class.forName(className, true, new URLClassLoader(list.toArray(new URL[list.size()])));
+ } catch (ClassNotFoundException | MalformedURLException e) {
+ throw new RuntimeException("Error loading class " + className, e);
+ }
+ }
+
+ /** An implementation of Template which is backed by a String */
+ protected class StringTemplate implements Template {
+ protected final String template;
+
+ public StringTemplate(String template) {
+ this.template = template;
+ }
+
+ public String expand(String selector) {
+ return Behavior.expandTemplate(template, currentResolver);
+ }
+
+ public String toString() {
+ return expand("");
+ }
+
+ public StringTemplate with(final String key, final String value) {
+ return new StringTemplateWithResolver(template, new KeyResolver(key, value));
+ }
+
+ }
+
+ /** An implementation of Template which is backed by a String and which
+ * encapsulates a Resolver for resolving embedded tags. */
+ protected class StringTemplateWithResolver extends StringTemplate {
+ private final Resolver localResolver;
+
+ public StringTemplateWithResolver(String template, Resolver localResolver) {
+ super(template);
+ this.localResolver = localResolver;
+ }
+
+ @Override
+ public String expand(String selector) {
+ Resolver saved = currentResolver;
+ currentResolver = new ChainedResolver(currentResolver, localResolver);
+ try {
+ return super.expand(selector);
+ }
+ finally {
+ currentResolver = saved;
+ }
+ }
+
+ @Override
+ public StringTemplate with(String key, String value) {
+ return new StringTemplateWithResolver(template, new ChainedResolver(localResolver, new KeyResolver(key, value)));
+ }
+ }
+
+ /** A Resolver which uses a Map to resolve tags */
+ private class KeyResolver implements Template.Resolver {
+ private final String key;
+ private final String value;
+
+ public KeyResolver(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ @Override
+ public Template lookup(String k) {
+ return key.equals(k) ? new StringTemplate(value) : null;
+ }
+ }
+
+ private class FileAdapter extends SimpleJavaFileObject {
+ private final String filename;
+ private final Template template;
+
+ public FileAdapter(String filename, Template template) {
+ super(URI.create("myfo:/" + filename), Kind.SOURCE);
+ this.template = template;
+ this.filename = filename;
+ }
+
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return toString();
+ }
+
+ public String toString() {
+ return Template.Behavior.expandTemplate(template.expand(filename), defaultResolver);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/lib/combo/tools/javac/combo/Template.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,123 @@
+/*
+ * 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 tools.javac.combo;
+
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A template into which tags of the form {@code #\{KEY\}} or
+ * {@code #\{KEY.SUBKEY\}} can be expanded.
+ */
+public interface Template {
+ String expand(String selector);
+
+ interface Resolver {
+ public Template lookup(String key);
+ }
+
+ public static class Behavior {
+ /* Looks for expandable keys. An expandable key can take the form:
+ * #{MAJOR}
+ * #{MAJOR.}
+ * #{MAJOR.MINOR}
+ * where MAJOR can be IDENTIFIER or IDENTIFIER[NUMERIC_INDEX]
+ * and MINOR can be an identifier.
+ *
+ * The ability to have an empty minor is provided on the
+ * assumption that some tests that can be written with this
+ * will find it useful to make a distinction akin to
+ * distinguishing F from F(), where F is a function pointer,
+ * and also cases of #{FOO.#{BAR}}, where BAR expands to an
+ * empty string.
+ *
+ * However, this being a general-purpose framework, the exact
+ * use is left up to the test writers.
+ */
+ private static final Pattern pattern = Pattern.compile("#\\{([A-Z_][A-Z0-9_]*(?:\\[\\d+\\])?)(?:\\.([A-Z0-9_]*))?\\}");
+
+ public static String expandTemplate(String template, final Map<String, Template> vars) {
+ return expandTemplate(template, new MapResolver(vars));
+ }
+
+ public static String expandTemplate(String template, Resolver res) {
+ CharSequence in = template;
+ StringBuffer out = new StringBuffer();
+ while (true) {
+ boolean more = false;
+ Matcher m = pattern.matcher(in);
+ while (m.find()) {
+ String major = m.group(1);
+ String minor = m.group(2);
+ Template key = res.lookup(major);
+ if (key == null)
+ throw new IllegalStateException("Unknown major key " + major);
+
+ String replacement = key.expand(minor == null ? "" : minor);
+ more |= pattern.matcher(replacement).find();
+ m.appendReplacement(out, replacement);
+ }
+ m.appendTail(out);
+ if (!more)
+ return out.toString();
+ else {
+ in = out;
+ out = new StringBuffer();
+ }
+ }
+ }
+
+ }
+}
+
+class MapResolver implements Template.Resolver {
+ private final Map<String, Template> vars;
+
+ public MapResolver(Map<String, Template> vars) {this.vars = vars;}
+
+ public Template lookup(String key) {
+ return vars.get(key);
+ }
+}
+
+class ChainedResolver implements Template.Resolver {
+ private final Template.Resolver upstreamResolver, thisResolver;
+
+ public ChainedResolver(Template.Resolver upstreamResolver, Template.Resolver thisResolver) {
+ this.upstreamResolver = upstreamResolver;
+ this.thisResolver = thisResolver;
+ }
+
+ public Template.Resolver getUpstreamResolver() {
+ return upstreamResolver;
+ }
+
+ @Override
+ public Template lookup(String key) {
+ Template result = thisResolver.lookup(key);
+ if (result == null)
+ result = upstreamResolver.lookup(key);
+ return result;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/lib/combo/tools/javac/combo/TemplateTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,94 @@
+/*
+ * 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 tools.javac.combo;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * TemplateTest
+ */
+@Test
+public class TemplateTest {
+ Map<String, Template> vars = new HashMap<>();
+
+ @BeforeTest
+ void before() { vars.clear(); }
+
+ private void assertTemplate(String expected, String template) {
+ String result = Template.Behavior.expandTemplate(template, vars);
+ assertEquals(result, expected, "for " + template);
+ }
+
+ private String dotIf(String s) {
+ return s == null || s.isEmpty() ? "" : "." + s;
+ }
+
+ public void testTemplateExpansion() {
+ vars.put("A", s -> "a" + dotIf(s));
+ vars.put("B", s -> "b" + dotIf(s));
+ vars.put("C", s -> "#{A}#{B}");
+ vars.put("D", s -> "#{A" + dotIf(s) + "}#{B" + dotIf(s) + "}");
+ vars.put("_D", s -> "d");
+
+ assertTemplate("", "");
+ assertTemplate("foo", "foo");
+ assertTemplate("a", "#{A}");
+ assertTemplate("a", "#{A.}");
+ assertTemplate("a.FOO", "#{A.FOO}");
+ assertTemplate("aa", "#{A}#{A}");
+ assertTemplate("ab", "#{C}");
+ assertTemplate("ab", "#{C.FOO}");
+ assertTemplate("ab", "#{C.}");
+ assertTemplate("a.FOOb.FOO", "#{D.FOO}");
+ assertTemplate("ab", "#{D}");
+ assertTemplate("d", "#{_D}");
+ assertTemplate("#{A", "#{A");
+ }
+
+ public void testIndexedTemplate() {
+ vars.put("A[0]", s -> "a" );
+ vars.put("A[1]", s -> "b" );
+ vars.put("A[2]", s -> "c" );
+ vars.put("X", s -> "0");
+ assertTemplate("a", "#{A[0]}");
+ assertTemplate("b", "#{A[1]}");
+ assertTemplate("c", "#{A[2]}");
+ }
+
+ public void testAngleBrackets() {
+ vars.put("X", s -> "xyz");
+ assertTemplate("List<String> ls = xyz;", "List<String> ls = #{X};");
+ }
+
+ @Test(expectedExceptions = IllegalStateException.class )
+ public void testUnknownKey() {
+ assertTemplate("#{Q}", "#{Q}");
+ }
+}
--- a/langtools/test/tools/javac/Diagnostics/compressed/T8012003c.out Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/Diagnostics/compressed/T8012003c.out Fri Sep 20 19:15:59 2013 -0700
@@ -1,3 +1,2 @@
T8012003c.java:18:15: compiler.err.report.access: m(), private, P
-- compiler.note.compressed.diags
1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8022162/IncorrectSignatureDeterminationForInnerClassesTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,89 @@
+/*
+ * 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 8022162
+ * @summary Incorrect signature determination for certain inner class generics
+ * @library /tools/javac/lib
+ * @build ToolBox
+ * @run main IncorrectSignatureDeterminationForInnerClassesTest
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+public class IncorrectSignatureDeterminationForInnerClassesTest {
+
+ private static final String DSrc =
+ "package p1;\n" +
+
+ "public class D<T> {\n" +
+ "}\n" +
+
+ "abstract class Q<T> {\n" +
+ " protected void m(M.E e) {}\n" +
+
+ " public class M extends D<T> {\n" +
+ " public class E {}\n" +
+ " }\n" +
+ "}";
+
+ private static final String HSrc =
+ "package p1;\n" +
+
+ "public class H {\n" +
+ " static class EQ extends Q<Object> {\n" +
+ " private void m2(M.E item) {\n" +
+ " m(item);\n" +
+ " }\n" +
+ " }\n" +
+ "}";
+
+ public static void main(String args[]) throws Exception {
+ new IncorrectSignatureDeterminationForInnerClassesTest().run();
+ }
+
+ void run() throws Exception {
+ compile();
+ }
+
+ void compile() throws Exception {
+ Files.createDirectory(Paths.get("classes"));
+
+ ToolBox.JavaToolArgs javacParams =
+ new ToolBox.JavaToolArgs()
+ .appendArgs("-d", "classes")
+ .setSources(DSrc);
+
+ ToolBox.javac(javacParams);
+
+ // compile class H against the class files for classes D and Q
+ javacParams =
+ new ToolBox.JavaToolArgs()
+ .appendArgs("-d", "classes", "-cp", "classes")
+ .setSources(HSrc);
+ ToolBox.javac(javacParams);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8023545/MisleadingErrorMsgDiamondPlusPrivateCtorTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8023545
+ * @summary Misleading error message when using diamond operator with private constructor
+ * @compile/fail/ref=MisleadingErrorMsgDiamondPlusPrivateCtorTest.out -XDrawDiagnostics MisleadingErrorMsgDiamondPlusPrivateCtorTest.java
+ */
+
+public class MisleadingErrorMsgDiamondPlusPrivateCtorTest {
+ public void foo() {
+ MyClass<Object> foo = new MyClass<>();
+ }
+}
+
+class MyClass<E> {
+ private MyClass() {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8023545/MisleadingErrorMsgDiamondPlusPrivateCtorTest.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,2 @@
+MisleadingErrorMsgDiamondPlusPrivateCtorTest.java:10:31: compiler.err.report.access: <E>MyClass(), private, MyClass
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8024039
+ * @summary javac, previous solution for JDK-8022186 was incorrect
+ * @library /tools/javac/lib
+ * @build ToolBox
+ * @run main NoDeadCodeGenerationOnTrySmtTest
+ */
+
+import java.io.File;
+import java.nio.file.Paths;
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.Code_attribute;
+import com.sun.tools.classfile.Code_attribute.Exception_data;
+import com.sun.tools.classfile.Method;
+import com.sun.tools.javac.util.Assert;
+
+public class NoDeadCodeGenerationOnTrySmtTest {
+
+ static final String testSource =
+ "public class Test {\n" +
+ " void m1(int arg) {\n" +
+ " synchronized (new Integer(arg)) {\n" +
+ " {\n" +
+ " label0:\n" +
+ " do {\n" +
+ " break label0;\n" +
+ " } while (arg != 0);\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+
+ " void m2(int arg) {\n" +
+ " synchronized (new Integer(arg)) {\n" +
+ " {\n" +
+ " label0:\n" +
+ " {\n" +
+ " break label0;\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}";
+
+ static final int[][] expectedExceptionTable = {
+ // {from, to, target, type},
+ {11, 13, 16, 0},
+ {16, 19, 16, 0}
+ };
+
+ static final String[] methodsToLookFor = {"m1", "m2"};
+
+ public static void main(String[] args) throws Exception {
+ new NoDeadCodeGenerationOnTrySmtTest().run();
+ }
+
+ void run() throws Exception {
+ compileTestClass();
+ checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
+ "Test.class").toUri()), methodsToLookFor);
+ }
+
+ void compileTestClass() throws Exception {
+ ToolBox.JavaToolArgs javacSuccessArgs =
+ new ToolBox.JavaToolArgs().setSources(testSource);
+ ToolBox.javac(javacSuccessArgs);
+ }
+
+ void checkClassFile(final File cfile, String[] methodsToFind) throws Exception {
+ ClassFile classFile = ClassFile.read(cfile);
+ int numberOfmethodsFound = 0;
+ for (String methodToFind : methodsToFind) {
+ for (Method method : classFile.methods) {
+ if (method.getName(classFile.constant_pool).equals(methodToFind)) {
+ numberOfmethodsFound++;
+ Code_attribute code = (Code_attribute) method.attributes.get("Code");
+ Assert.check(code.exception_table_langth == expectedExceptionTable.length,
+ "The ExceptionTable found has a length different to the expected one");
+ int i = 0;
+ for (Exception_data entry: code.exception_table) {
+ Assert.check(entry.start_pc == expectedExceptionTable[i][0] &&
+ entry.end_pc == expectedExceptionTable[i][1] &&
+ entry.handler_pc == expectedExceptionTable[i][2] &&
+ entry.catch_type == expectedExceptionTable[i][3],
+ "Exception table entry at pos " + i + " differ from expected.");
+ i++;
+ }
+ }
+ }
+ }
+ Assert.check(numberOfmethodsFound == 2, "Some seek methods were not found");
+ }
+
+ void error(String msg) {
+ throw new AssertionError(msg);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8024207/FlowCrashTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,23 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8024207
+ * @summary javac crash in Flow$AssignAnalyzer.visitIdent
+ * @compile/fail/ref=FlowCrashTest.out -XDrawDiagnostics FlowCrashTest.java
+ */
+
+import java.util.*;
+import java.util.stream.*;
+
+public class FlowCrashTest {
+ static class ViewId { }
+
+ public void crash() {
+
+ Map<ViewId,String> viewToProfile = null;
+ new TreeMap<>(viewToProfile.entrySet().stream()
+ .collect(Collectors.toMap((vid, prn) -> prn,
+ (vid, prn) -> Arrays.asList(vid),
+ (a, b) -> { a.addAll(b); return a; })));
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8024207/FlowCrashTest.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,2 @@
+FlowCrashTest.java:18:42: compiler.err.cant.apply.symbols: kindname.method, toMap, @475,@542,@624,{(compiler.misc.inapplicable.method: kindname.method, java.util.stream.Collectors, <T,K,U>toMap(java.util.function.Function<? super T,? extends K>,java.util.function.Function<? super T,? extends U>), (compiler.misc.infer.arg.length.mismatch: T,K,U)),(compiler.misc.inapplicable.method: kindname.method, java.util.stream.Collectors, <T,K,U>toMap(java.util.function.Function<? super T,? extends K>,java.util.function.Function<? super T,? extends U>,java.util.function.BinaryOperator<U>), (compiler.misc.infer.no.conforming.assignment.exists: T,K,U, (compiler.misc.incompatible.arg.types.in.lambda))),(compiler.misc.inapplicable.method: kindname.method, java.util.stream.Collectors, <T,K,U,M>toMap(java.util.function.Function<? super T,? extends K>,java.util.function.Function<? super T,? extends U>,java.util.function.BinaryOperator<U>,java.util.function.Supplier<M>), (compiler.misc.infer.arg.length.mismatch: T,K,U,M))}
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8024398/NPETryTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8024398
+ * @summary javac, compiler crashes with try with empty body
+ * @compile NPETryTest.java
+ */
+
+public class NPETryTest {
+ void m()
+ {
+ /* This is the statement provoking the error the rest are provided as
+ * additional tests
+ */
+ try {}
+ catch (Exception e) {}
+
+ try {}
+ catch (Exception e) {}
+ finally {}
+
+ try {}
+ finally {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoDefault.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,9 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8022322
+ * @summary Default methods are not allowed in an annotation.
+ * @compile/fail/ref=NoDefault.out -XDrawDiagnostics NoDefault.java
+ */
+@interface NoDefault {
+ default int m() {return 0;}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoDefault.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,3 @@
+NoDefault.java:8:17: compiler.err.mod.not.allowed.here: default
+NoDefault.java:8:21: compiler.err.intf.meth.cant.have.body
+2 errors
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoDefaultAbstract.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,9 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8022322
+ * @summary Default methods are not allowed in an annotation.
+ * @compile/fail/ref=NoDefaultAbstract.out -XDrawDiagnostics NoDefaultAbstract.java
+ */
+@interface NoDefaultAbstract {
+ default int m();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoDefaultAbstract.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,2 @@
+NoDefaultAbstract.java:8:17: compiler.err.mod.not.allowed.here: default
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoStatic.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,10 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8022322
+ * @summary Static methods are not allowed in an annotation.
+ * @compile/fail/ref=NoStatic.out -XDrawDiagnostics NoStatic.java
+ */
+
+@interface NoStatic {
+ static int m() {return 0;}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoStatic.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,3 @@
+NoStatic.java:9:16: compiler.err.mod.not.allowed.here: static
+NoStatic.java:9:20: compiler.err.intf.meth.cant.have.body
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoStaticAbstract.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,10 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8022322
+ * @summary Static methods are not allowed in an annotation.
+ * @compile/fail/ref=NoStaticAbstract.out -XDrawDiagnostics NoStaticAbstract.java
+ */
+
+@interface NoStaticAbstract {
+ static int m();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoStaticAbstract.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,2 @@
+NoStaticAbstract.java:9:16: compiler.err.mod.not.allowed.here: static
+1 error
--- a/langtools/test/tools/javac/defaultMethods/ClassReaderTest/ClassReaderTest.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/ClassReaderTest/ClassReaderTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that default methods don't cause ClassReader to complete classes recursively
* @author Maurizio Cimadamore
* @compile pkg/Foo.java
--- a/langtools/test/tools/javac/defaultMethods/Neg01.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg01.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary negative test for ambiguous defaults
* @compile/fail/ref=Neg01.out -XDrawDiagnostics Neg01.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg02.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg02.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that ill-formed MI hierarchies do not compile
* @compile/fail/ref=Neg02.out -XDrawDiagnostics Neg02.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg03.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg03.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that re-abstraction works properly
* @compile/fail/ref=Neg03.out -XDrawDiagnostics Neg03.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg04.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg04.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that default method must have most specific return type
* @compile/fail/ref=Neg04.out -XDrawDiagnostics Neg04.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg05.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg05.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that abstract methods are compatible with inherited defaults
* @compile/fail/ref=Neg05.out -XDrawDiagnostics Neg05.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg06.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg06.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary flow analysis is not run on inlined default bodies
* @compile/fail/ref=Neg06.out -XDrawDiagnostics Neg06.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg07.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg07.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that default overrides are properly type-checked
* @compile/fail/ref=Neg07.out -XDrawDiagnostics Neg07.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg08.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg08.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that default overrides are properly type-checked
* @compile/fail/ref=Neg08.out -XDrawDiagnostics Neg08.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg09.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg09.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that default overrides are properly type-checked
* @compile/fail/ref=Neg09.out -Werror -Xlint:unchecked -XDrawDiagnostics Neg09.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg10.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg10.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that default overrides are properly type-checked
* @compile/fail/ref=Neg10.out -Werror -Xlint:unchecked -XDrawDiagnostics Neg10.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg11.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg11.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that default overrides are properly type-checked
* @compile/fail/ref=Neg11.out -XDrawDiagnostics Neg11.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg12.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg12.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that abstract methods are discarded in overload resolution diags
* @compile/fail/ref=Neg12.out -XDrawDiagnostics Neg12.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg13.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg13.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that default method overriding object members are flagged as error
* @compile/fail/ref=Neg13.out -XDrawDiagnostics Neg13.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg14.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg14.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that a class cannot have two sibling interfaces with a default and abstract method
* @compile/fail/ref=Neg14.out -XDrawDiagnostics Neg14.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg15.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg15.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that level skipping in default super calls is correctly rejected
* @compile/fail/ref=Neg15.out -XDrawDiagnostics Neg15.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg16.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg16.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that level skipping in default super calls is correctly rejected
* @compile/fail/ref=Neg16.out -XDrawDiagnostics Neg16.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Pos01.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos01.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary basic test for default methods
* @author Maurizio Cimadamore
*/
--- a/langtools/test/tools/javac/defaultMethods/Pos02.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos02.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary test for explicit resolution of ambiguous default methods
* @author Maurizio Cimadamore
* @compile Pos02.java
--- a/langtools/test/tools/javac/defaultMethods/Pos04.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos04.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary test for overriding with default method
* @author Maurizio Cimadamore
* @compile Pos04.java
--- a/langtools/test/tools/javac/defaultMethods/Pos05.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos05.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that indirectly inherited default methods are discovered during resolution
* @author Maurizio Cimadamore
* @compile Pos05.java
--- a/langtools/test/tools/javac/defaultMethods/Pos06.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos06.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that well-formed MI hierarchies behaves well w.r.t. method resolution (i.e. no ambiguities)
* @author Maurizio Cimadamore
* @compile Pos06.java
--- a/langtools/test/tools/javac/defaultMethods/Pos07.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos07.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that compilation order does not matter
* @author Maurizio Cimadamore
* @compile Pos07.java
--- a/langtools/test/tools/javac/defaultMethods/Pos08.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos08.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that common overrider solves default method conflicts
* @author Maurizio Cimadamore
* @compile Pos08.java
--- a/langtools/test/tools/javac/defaultMethods/Pos10.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos10.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that type-variables in generic extension decl can be accessed from default impl
* @author Maurizio Cimadamore
* @compile Pos10.java
--- a/langtools/test/tools/javac/defaultMethods/Pos11.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos11.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary complex test with conflict resolution via overriding
* @author Brian Goetz
* @compile Pos11.java
--- a/langtools/test/tools/javac/defaultMethods/Pos12.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos12.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that 'this' can be used from within an extension method
* @compile Pos12.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Pos13.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos13.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary qualified 'this' inside default method causes StackOverflowException
* @compile Pos13.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Pos14.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos14.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that overload resolution selects most specific signature
* @compile Pos14.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Pos15.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos15.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that overload resolution selects most specific signature
* @compile Pos15.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Pos16.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos16.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary 'class wins' should not short-circuit overload resolution
* @compile Pos16.java
*/
--- a/langtools/test/tools/javac/defaultMethods/TestDefaultBody.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/TestDefaultBody.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that code attributed for default methods is correctly generated
*/
--- a/langtools/test/tools/javac/defaultMethods/TestNoBridgeOnDefaults.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/TestNoBridgeOnDefaults.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that javac does not generate bridge methods for defaults
*/
--- a/langtools/test/tools/javac/defaultMethods/crossCompile/CrossCompile.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/crossCompile/CrossCompile.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that clinit in interface doesn't cause spurious default method diagnostics
* @compile -source 1.4 -target 1.4 Clinit.java
* @compile CrossCompile.java
--- a/langtools/test/tools/javac/defaultMethods/separate/Separate.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/separate/Separate.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary smoke test for separate compilation of default methods
* @author Maurizio Cimadamore
* @compile pkg1/A.java
--- a/langtools/test/tools/javac/defaultMethods/super/TestDefaultSuperCall.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/super/TestDefaultSuperCall.java Fri Sep 20 19:15:59 2013 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8006694
+ * @bug 7192246 8006694
* @summary Automatic test for checking correctness of default super/this resolution
* temporarily workaround combo tests are causing time out in several platforms
* @library ../../lib
--- a/langtools/test/tools/javac/depDocComment/SuppressDeprecation.out Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/depDocComment/SuppressDeprecation.out Fri Sep 20 19:15:59 2013 -0700
@@ -1,8 +1,8 @@
-SuppressDeprecation.java:130:17: compiler.warn.has.been.deprecated: X, compiler.misc.unnamed.package
SuppressDeprecation.java:82:10: compiler.warn.has.been.deprecated: g(), T
SuppressDeprecation.java:83:14: compiler.warn.has.been.deprecated: g(), T
SuppressDeprecation.java:84:9: compiler.warn.has.been.deprecated: var, T
SuppressDeprecation.java:87:9: compiler.warn.has.been.deprecated: T(), T
SuppressDeprecation.java:90:9: compiler.warn.has.been.deprecated: T(int), T
SuppressDeprecation.java:98:1: compiler.warn.has.been.deprecated: T(), T
+SuppressDeprecation.java:130:17: compiler.warn.has.been.deprecated: X, compiler.misc.unnamed.package
7 warnings
--- a/langtools/test/tools/javac/diags/examples/BadArgTypesInLambda.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/diags/examples/BadArgTypesInLambda.java Fri Sep 20 19:15:59 2013 -0700
@@ -21,9 +21,6 @@
* questions.
*/
-// key: compiler.err.cant.apply.symbol
-// key: compiler.misc.no.conforming.assignment.exists
-// key: compiler.misc.bad.arg.types.in.lambda
// key: compiler.err.prob.found.req
// key: compiler.misc.inconvertible.types
// options: -Xdiags:verbose
--- a/langtools/test/tools/javac/diags/examples/CyclicInference.java Fri Sep 20 17:11:32 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.prob.found.req
-// key: compiler.misc.cyclic.inference
-
-class CyclicInference {
- interface SAM<X> {
- void m(X x);
- }
-
- <Z> void g(SAM<Z> sz) { }
-
- void test() {
- g(x-> {});
- }
-}
--- a/langtools/test/tools/javac/diags/examples/IncompatibleArgTypesInMethodRef.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/diags/examples/IncompatibleArgTypesInMethodRef.java Fri Sep 20 19:15:59 2013 -0700
@@ -31,6 +31,7 @@
}
void g(String s, Integer i) { }
+ void g(Integer i, String s) { }
<Z> void m(SAM<Z> s) { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/MrefInferAndExplicitParams.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.invalid.mref
+// key: compiler.misc.mref.infer.and.explicit.params
+
+public class MrefInferAndExplicitParams {
+ static class Foo<X> {}
+
+ interface Supplier<X> {
+ X make();
+ }
+
+ Supplier<Foo<String>> sfs = Foo::<Number>new;
+}
--- a/langtools/test/tools/javac/diags/examples/MrefStat.java.rej Fri Sep 20 17:11:32 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
---- MrefStat.java
-+++ MrefStat.java
-@@ -0,0 +1,31 @@
-+/*
-+ * 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.
-+ */
-+
-+// key: compiler.note.mref.stat
-+// options: -XDdumpLambdaToMethodStats
-+
-+class MrefStat {
-+ Runnable r = MrefStat::m;
-+
-+ static void m() { }
-+}
--- a/langtools/test/tools/javac/diags/examples/MrefStat1.java.rej Fri Sep 20 17:11:32 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
---- MrefStat1.java
-+++ MrefStat1.java
-@@ -0,0 +1,34 @@
-+/*
-+ * 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.
-+ */
-+
-+// key: compiler.note.mref.stat.1
-+// options: -XDdumpLambdaToMethodStats
-+
-+class MrefStat1 {
-+
-+ void m() { }
-+
-+ static class Sub extends MrefStat1 {
-+ Runnable r = super::m;
-+ }
-+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/PotentiallyAmbiguousOverload.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+// key: compiler.warn.potentially.ambiguous.overload
+// options: -Xlint:overloads
+
+class PotentiallyAmbiguousOverload {
+ interface F1 {
+ void m(String s);
+ }
+
+ interface F2 {
+ void m(Integer s);
+ }
+
+ void m(F1 f1) { }
+ void m(F2 f2) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/AliveRanges.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,34 @@
+/*
+ * 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.annotation.*;
+
+@Repeatable(AliveRanges.class)
+@Target({ElementType.METHOD})
+@interface AliveRange {
+ String varName();
+ int bytecodeStart();
+ int bytecodeLength();
+}
+
+@Target({ElementType.METHOD})
+@interface AliveRanges {AliveRange[] value();}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/LVTHarness.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,280 @@
+/*
+ * 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 7047734
+ * @summary The LVT is not generated correctly during some try/catch scenarios
+ * @library /tools/javac/lib
+ * @build JavacTestingAbstractProcessor LVTHarness
+ * @run main LVTHarness
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.util.Set;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Code_attribute;
+import com.sun.tools.classfile.ConstantPool.InvalidIndex;
+import com.sun.tools.classfile.ConstantPool.UnexpectedEntry;
+import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
+import com.sun.tools.classfile.LocalVariableTable_attribute;
+import com.sun.tools.classfile.Method;
+
+import static javax.tools.StandardLocation.*;
+import static com.sun.tools.classfile.LocalVariableTable_attribute.Entry;
+
+public class LVTHarness {
+
+ static int nerrors = 0;
+
+ static final JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+ static final StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+
+ public static void main(String[] args) throws Exception {
+ fm.setLocation(SOURCE_PATH,
+ Arrays.asList(new File(System.getProperty("test.src"), "tests")));
+ for (JavaFileObject jfo : fm.list(SOURCE_PATH, "",
+ Collections.singleton(JavaFileObject.Kind.SOURCE), true)) {
+ new LVTHarness(jfo).check();
+ }
+ if (nerrors > 0) {
+ throw new AssertionError("Errors were found");
+ }
+ }
+
+
+ JavaFileObject jfo;
+ Map<ElementKey, AliveRanges> aliveRangeMap =
+ new HashMap<ElementKey, AliveRanges>();
+ Set<String> declaredKeys = new HashSet<>();
+ List<ElementKey> seenAliveRanges = new ArrayList<>();
+
+ protected LVTHarness(JavaFileObject jfo) {
+ this.jfo = jfo;
+ }
+
+ protected void check() throws Exception {
+ JavacTask ct = (JavacTask)comp.getTask(null, fm, null, Arrays.asList("-g"),
+ null, Arrays.asList(jfo));
+ System.err.println("compiling code " + jfo.toString());
+ ct.setProcessors(Collections.singleton(new AliveRangeFinder()));
+ if (!ct.call()) {
+ throw new AssertionError("Error during compilation");
+ }
+
+ checkClassFile(new File(jfo.getName().replace(".java", ".class")));
+
+ //check all candidates have been used up
+ for (Map.Entry<ElementKey, AliveRanges> entry : aliveRangeMap.entrySet()) {
+ if (!seenAliveRanges.contains(entry.getKey())) {
+ error("Redundant @AliveRanges annotation on method " +
+ entry.getKey().elem);
+ }
+ }
+ }
+
+ void checkClassFile(File file)
+ throws IOException, ConstantPoolException, InvalidDescriptor {
+ ClassFile classFile = ClassFile.read(file);
+ ConstantPool constantPool = classFile.constant_pool;
+
+ //lets get all the methods in the class file.
+ for (Method method : classFile.methods) {
+ for (ElementKey elementKey: aliveRangeMap.keySet()) {
+ String methodDesc = method.getName(constantPool) +
+ method.descriptor.getParameterTypes(constantPool);
+ if (methodDesc.equals(elementKey.elem.toString())) {
+ checkMethod(constantPool, method, aliveRangeMap.get(elementKey));
+ seenAliveRanges.add(elementKey);
+ }
+ }
+ }
+ }
+
+ void checkMethod(ConstantPool constantPool, Method method, AliveRanges ranges)
+ throws InvalidIndex, UnexpectedEntry {
+ Code_attribute code = (Code_attribute) method.attributes.get(Attribute.Code);
+ LocalVariableTable_attribute lvt =
+ (LocalVariableTable_attribute) (code.attributes.get(Attribute.LocalVariableTable));
+ List<String> infoFromRanges = convertToStringList(ranges);
+ List<String> infoFromLVT = convertToStringList(constantPool, lvt);
+
+ // infoFromRanges most be contained in infoFromLVT
+ int i = 0;
+ int j = 0;
+ while (i < infoFromRanges.size() && j < infoFromLVT.size()) {
+ int comparison = infoFromRanges.get(i).compareTo(infoFromLVT.get(j));
+ if (comparison == 0) {
+ i++; j++;
+ } else if (comparison > 0) {
+ j++;
+ } else {
+ break;
+ }
+ }
+
+ if (i < infoFromRanges.size()) {
+ error(infoFromLVT, infoFromRanges);
+ }
+ }
+
+ List<String> convertToStringList(AliveRanges ranges) {
+ List<String> result = new ArrayList<>();
+ for (Annotation anno : ranges.value()) {
+ AliveRange range = (AliveRange)anno;
+ String str = formatLocalVariableData(range.varName(),
+ range.bytecodeStart(), range.bytecodeLength());
+ result.add(str);
+ }
+ Collections.sort(result);
+ return result;
+ }
+
+ List<String> convertToStringList(ConstantPool constantPool,
+ LocalVariableTable_attribute lvt) throws InvalidIndex, UnexpectedEntry {
+ List<String> result = new ArrayList<>();
+ for (Entry entry : lvt.local_variable_table) {
+ String str = formatLocalVariableData(constantPool.getUTF8Value(entry.name_index),
+ entry.start_pc, entry.length);
+ result.add(str);
+ }
+ Collections.sort(result);
+ return result;
+ }
+
+ String formatLocalVariableData(String varName, int start, int length) {
+ StringBuilder sb = new StringBuilder()
+ .append("var name: ").append(varName)
+ .append(" start: ").append(start)
+ .append(" length: ").append(length);
+ return sb.toString();
+ }
+
+ protected void error(List<String> infoFromLVT, List<String> infoFromRanges) {
+ nerrors++;
+ System.err.printf("Error occurred while checking file: %s\n", jfo.getName());
+ System.err.println("The range info from the annotations is");
+ printStringListToErrOutput(infoFromRanges);
+ System.err.println();
+ System.err.println("And the range info from the class file is");
+ printStringListToErrOutput(infoFromLVT);
+ System.err.println();
+ }
+
+ void printStringListToErrOutput(List<String> list) {
+ for (String s : list) {
+ System.err.println("\t" + s);
+ }
+ }
+
+ protected void error(String msg) {
+ nerrors++;
+ System.err.printf("Error occurred while checking file: %s\nreason: %s\n",
+ jfo.getName(), msg);
+ }
+
+ class AliveRangeFinder extends JavacTestingAbstractProcessor {
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations,
+ RoundEnvironment roundEnv) {
+ if (roundEnv.processingOver())
+ return true;
+
+ TypeElement aliveRangeAnno = elements.getTypeElement("AliveRanges");
+
+ if (!annotations.contains(aliveRangeAnno)) {
+ error("no @AliveRanges annotation found in test class");
+ }
+
+ for (Element elem: roundEnv.getElementsAnnotatedWith(aliveRangeAnno)) {
+ Annotation annotation = elem.getAnnotation(AliveRanges.class);
+ aliveRangeMap.put(new ElementKey(elem), (AliveRanges)annotation);
+ }
+ return true;
+ }
+ }
+
+ class ElementKey {
+
+ String key;
+ Element elem;
+
+ public ElementKey(Element elem) {
+ this.elem = elem;
+ this.key = computeKey(elem);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof ElementKey) {
+ ElementKey other = (ElementKey)obj;
+ return other.key.equals(key);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return key.hashCode();
+ }
+
+ String computeKey(Element e) {
+ StringBuilder buf = new StringBuilder();
+ while (e != null) {
+ buf.append(e.toString());
+ e = e.getEnclosingElement();
+ }
+ buf.append(jfo.getName());
+ return buf.toString();
+ }
+
+ @Override
+ public String toString() {
+ return "Key{" + key + "}";
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseConditional.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,16 @@
+/* /nodynamiccopyright/ */
+
+public class TestCaseConditional {
+
+ @AliveRange(varName="o", bytecodeStart=5, bytecodeLength=33)
+ @AliveRange(varName="oo", bytecodeStart=23, bytecodeLength=15)
+ void m(String[] args) {
+ Boolean o;
+ Boolean oo = ((o = Boolean.TRUE).booleanValue()) ?
+ o = Boolean.TRUE :
+ Boolean.FALSE;
+ oo.hashCode();
+ o = Boolean.FALSE;
+ o.hashCode();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseDoLoop.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,15 @@
+/* /nodynamiccopyright/ */
+
+public class TestCaseDoLoop {
+
+ @AliveRange(varName="o", bytecodeStart=3, bytecodeLength=15)
+ @AliveRange(varName="args", bytecodeStart=0, bytecodeLength=18)
+ void m(String[] args) {
+ Object o;
+ do {
+ o = "";
+ o.hashCode();
+ } while (args[0] != null);
+ o = "";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseFor.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,27 @@
+/* /nodynamiccopyright/ */
+
+public class TestCaseFor {
+
+ @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8)
+ @AliveRange(varName="o", bytecodeStart=24, bytecodeLength=1)
+ void m1(String[] args) {
+ Object o;
+ for (int i = 0; i < 5; i++) {
+ o = "";
+ o.hashCode();
+ }
+ o = "";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8)
+ @AliveRange(varName="o", bytecodeStart=24, bytecodeLength=1)
+ void m2(String[] args) {
+ Object o;
+ for (int i = 0; i < 5; i++) {
+ o = "";
+ o.hashCode();
+ continue;
+ }
+ o = "";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseForEach.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,15 @@
+/* /nodynamiccopyright/ */
+
+public class TestCaseForEach {
+
+ @AliveRange(varName="o", bytecodeStart=25, bytecodeLength=8)
+ @AliveRange(varName="o", bytecodeStart=39, bytecodeLength=1)
+ void m(String[] args) {
+ Object o;
+ for (String s : args) {
+ o = "";
+ o.hashCode();
+ }
+ o = "";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseIf.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,61 @@
+/* /nodynamiccopyright/ */
+
+public class TestCaseIf {
+
+ @AliveRange(varName="o", bytecodeStart=9, bytecodeLength=5)
+ @AliveRange(varName="o", bytecodeStart=17, bytecodeLength=1)
+ void m0(String[] args) {
+ Object o;
+ if (args[0] != null) {
+ o = "";
+ o.hashCode();
+ }
+ o = "";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=5)
+ @AliveRange(varName="o", bytecodeStart=18, bytecodeLength=1)
+ void m1() {
+ Object o;
+ int i = 5;
+ if (i == 5) {
+ o = "";
+ o.hashCode();
+ }
+ o = "";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=5)
+ @AliveRange(varName="o", bytecodeStart=18, bytecodeLength=1)
+ void m2() {
+ Object o;
+ int i = 5;
+ if (!(i == 5)) {
+ o = "";
+ o.hashCode();
+ }
+ o = "";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=15, bytecodeLength=5)
+ @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=1)
+ void m3(String[] args) {
+ Object o;
+ if (args[0] != null && args[1] != null) {
+ o = "";
+ o.hashCode();
+ }
+ o = "";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=15, bytecodeLength=5)
+ @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=1)
+ void m4(String[] args) {
+ Object o;
+ if (args[0] != null || args[1] != null) {
+ o = "";
+ o.hashCode();
+ }
+ o = "";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseIfElse.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,48 @@
+/* /nodynamiccopyright/ */
+
+public class TestCaseIfElse {
+
+ @AliveRange(varName="o", bytecodeStart=9, bytecodeLength=8)
+ @AliveRange(varName="o", bytecodeStart=20, bytecodeLength=9)
+ void m0(String[] args) {
+ Object o;
+ if (args[0] != null) {
+ o = "then";
+ o.hashCode();
+ } else {
+ o = "else";
+ o.hashCode();
+ }
+ o = "finish";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8)
+ @AliveRange(varName="o", bytecodeStart=21, bytecodeLength=9)
+ void m1() {
+ Object o;
+ int i = 5;
+ if (i == 5) {
+ o = "then";
+ o.hashCode();
+ } else {
+ o = "else";
+ o.hashCode();
+ }
+ o = "finish";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8)
+ @AliveRange(varName="o", bytecodeStart=21, bytecodeLength=9)
+ void m2(String[] args) {
+ Object o;
+ int i = 5;
+ if (i != 5) {
+ o = "then";
+ o.hashCode();
+ } else {
+ o = "else";
+ o.hashCode();
+ }
+ o = "finish";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseSwitch.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,73 @@
+/* /nodynamiccopyright/ */
+
+public class TestCaseSwitch {
+
+ @AliveRange(varName="o", bytecodeStart=31, bytecodeLength=16)
+ @AliveRange(varName="o", bytecodeStart=50, bytecodeLength=15)
+ @AliveRange(varName="o", bytecodeStart=68, bytecodeLength=1)
+ @AliveRange(varName="oo", bytecodeStart=39, bytecodeLength=26)
+ @AliveRange(varName="uu", bytecodeStart=59, bytecodeLength=6)
+ void m1(String[] args) {
+ Object o;
+ switch (args.length) {
+ case 0:
+ o = "0";
+ o.hashCode();
+ Object oo = "oo";
+ oo.hashCode();
+ break;
+ case 1:
+ o = "1";
+ o.hashCode();
+ Object uu = "uu";
+ uu.hashCode();
+ break;
+ }
+ o = "return";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=95, bytecodeLength=18)
+ @AliveRange(varName="o", bytecodeStart=116, bytecodeLength=15)
+ @AliveRange(varName="o", bytecodeStart=134, bytecodeLength=1)
+ @AliveRange(varName="oo", bytecodeStart=104, bytecodeLength=27)
+ @AliveRange(varName="uu", bytecodeStart=125, bytecodeLength=6)
+ void m2(String[] args) {
+ Object o;
+ switch (args[0]) {
+ case "string0":
+ o = "0";
+ o.hashCode();
+ Object oo = "oo";
+ oo.hashCode();
+ break;
+ case "string1":
+ o = "1";
+ o.hashCode();
+ Object uu = "uu";
+ uu.hashCode();
+ break;
+ }
+ o = "return";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=31, bytecodeLength=8)
+ @AliveRange(varName="o", bytecodeStart=42, bytecodeLength=8)
+ @AliveRange(varName="o", bytecodeStart=53, bytecodeLength=9)
+ void m3(String[] args) {
+ Object o;
+ switch (args.length) {
+ case 0:
+ o = "0";
+ o.hashCode();
+ break;
+ case 1:
+ o = "1";
+ o.hashCode();
+ break;
+ default:
+ o = "default";
+ o.hashCode();
+ }
+ o = "finish";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseTry.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,76 @@
+/* /nodynamiccopyright/ */
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+
+public class TestCaseTry {
+
+ @AliveRange(varName="o", bytecodeStart=3, bytecodeLength=8)
+ @AliveRange(varName="o", bytecodeStart=15, bytecodeLength=1)
+ void m0(String[] args) {
+ Object o;
+ try {
+ o = "";
+ o.hashCode();
+ } catch (RuntimeException e) {}
+ o = "";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=3, bytecodeLength=16)
+ @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=23)
+ void m1() {
+ Object o;
+ try {
+ o = "";
+ o.hashCode();
+ } catch (RuntimeException e) {
+ }
+ finally {
+ o = "finally";
+ o.hashCode();
+ }
+ o = "";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=3, bytecodeLength=16)
+ @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=31)
+ void m2() {
+ Object o;
+ try {
+ o = "";
+ o.hashCode();
+ } catch (RuntimeException e) {
+ o = "catch";
+ o.hashCode();
+ }
+ finally {
+ o = "finally";
+ o.hashCode();
+ }
+ o = "";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=22, bytecodeLength=38)
+ @AliveRange(varName="o", bytecodeStart=103, bytecodeLength=8)
+ void m3() {
+ Object o;
+ try (BufferedReader br =
+ new BufferedReader(new FileReader("aFile"))) {
+ o = "inside try";
+ o.hashCode();
+ } catch (Exception e) {}
+ o = "";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=12, bytecodeLength=96)
+ @AliveRange(varName="o", bytecodeStart=112, bytecodeLength=1)
+ void m4() {
+ String o;
+ try (BufferedReader br =
+ new BufferedReader(new FileReader(o = "aFile"))) {
+ o = "inside try";
+ o.hashCode();
+ } catch (Exception e) {}
+ o = "";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseWhile.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,15 @@
+/* /nodynamiccopyright/ */
+
+public class TestCaseWhile {
+
+ @AliveRange(varName="o", bytecodeStart=9, bytecodeLength=5)
+ @AliveRange(varName="o", bytecodeStart=20, bytecodeLength=1)
+ void m(String[] args) {
+ Object o;
+ while (args[0] != null) {
+ o = "";
+ o.hashCode();
+ }
+ o = "";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/neg/OrderedIntersections.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6962494
+ * @summary The order of elements of intersection types shouldn't matter
+ * @compile/fail/ref=OrderedIntersections.out -XDrawDiagnostics OrderedIntersections.java
+ */
+
+interface i1 {}
+interface i2 {}
+
+public class OrderedIntersections {
+ static <t1 extends i1 & i2> Object smf(t1 x) {
+ System.out.println( " smf1 " );
+ return null;
+ }
+
+ static <t2 extends i2 & i1> Object smf(t2 x) {
+ System.out.println( " smf2 " );
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/neg/OrderedIntersections.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,2 @@
+OrderedIntersections.java:17:40: compiler.err.already.defined: kindname.method, <t1>smf(t1), kindname.class, OrderedIntersections
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177a.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,45 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8016177 8016178
+ * @summary structural most specific and stuckness
+ * @compile/fail/ref=T8016177a.out -XDrawDiagnostics T8016177a.java
+ */
+import java.util.List;
+
+class T8016177a {
+
+ interface ToIntFunction<X> {
+ int m(X x);
+ }
+
+ interface Function<X, Y> {
+ Y m(X x);
+ }
+
+ <T,R> void m1(List<T> s, Function<T,R> f) { }
+ <T,R> void m1(List<T> s, ToIntFunction<T> f) { }
+
+ <T,R> List<R> m2(List<T> s, Function<T,R> f) { return null; }
+ <T,R> List<R> m2(List<T> s, ToIntFunction<T> f) { return null; }
+
+ <T,R> List<T> m3(List<T> s, Function<T,R> f) { return null; }
+ <T,R> List<R> m3(List<T> s, ToIntFunction<T> f) { return null; }
+
+ <T,R> List<T> m4(List<T> s, Function<T,R> f) { return null; }
+ <T,R> List<T> m4(List<T> s, ToIntFunction<T> f) { return null; }
+
+ <T,R> List<R> m5(List<T> s, Function<T,R> f) { return null; }
+ <T,R> List<T> m5(List<T> s, ToIntFunction<T> f) { return null; }
+
+ <T extends R,R> List<R> m6(List<T> s, Function<T,R> f) { return null; }
+ <T extends R,R> List<T> m6(List<T> s, ToIntFunction<T> f) { return null; }
+
+ void test(List<String> ss) {
+ m1(ss, s->s.length()); //ambiguous
+ m2(ss, s->s.length()); //ambiguous
+ m3(ss, s->s.length()); //ambiguous
+ m4(ss, s->s.length()); //ambiguous
+ m5(ss, s->s.length()); //ambiguous
+ m6(ss, s->s.length()); //ambiguous
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177a.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,8 @@
+T8016177a.java:38:10: compiler.err.ref.ambiguous: m1, kindname.method, <T,R>m1(java.util.List<T>,T8016177a.Function<T,R>), T8016177a, kindname.method, <T,R>m1(java.util.List<T>,T8016177a.ToIntFunction<T>), T8016177a
+T8016177a.java:39:10: compiler.err.ref.ambiguous: m2, kindname.method, <T,R>m2(java.util.List<T>,T8016177a.Function<T,R>), T8016177a, kindname.method, <T,R>m2(java.util.List<T>,T8016177a.ToIntFunction<T>), T8016177a
+T8016177a.java:40:10: compiler.err.ref.ambiguous: m3, kindname.method, <T,R>m3(java.util.List<T>,T8016177a.Function<T,R>), T8016177a, kindname.method, <T,R>m3(java.util.List<T>,T8016177a.ToIntFunction<T>), T8016177a
+T8016177a.java:41:10: compiler.err.ref.ambiguous: m4, kindname.method, <T,R>m4(java.util.List<T>,T8016177a.Function<T,R>), T8016177a, kindname.method, <T,R>m4(java.util.List<T>,T8016177a.ToIntFunction<T>), T8016177a
+T8016177a.java:42:10: compiler.err.ref.ambiguous: m5, kindname.method, <T,R>m5(java.util.List<T>,T8016177a.Function<T,R>), T8016177a, kindname.method, <T,R>m5(java.util.List<T>,T8016177a.ToIntFunction<T>), T8016177a
+T8016177a.java:43:10: compiler.err.ref.ambiguous: m6, kindname.method, <T,R>m6(java.util.List<T>,T8016177a.Function<T,R>), T8016177a, kindname.method, <T,R>m6(java.util.List<T>,T8016177a.ToIntFunction<T>), T8016177a
+T8016177a.java:43:12: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: T,R, (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: int, java.lang.String)))
+7 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177b.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,34 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8016177 8016178
+ * @summary structural most specific and stuckness
+ * @compile/fail/ref=T8016177b.out -XDrawDiagnostics T8016177b.java
+ */
+class T8016177b {
+ interface ToIntFunction<X> {
+ int m(X x);
+ }
+
+ interface Function<X, Y> {
+ Y m(X x);
+ }
+
+ <U, V> Function<U, V> id(Function<U, V> arg) { return null; }
+
+ <U, V> Function<U, V> id2(Function<U, V> arg) { return null; }
+ <U> ToIntFunction<U> id2(ToIntFunction<U> arg) { return null; }
+
+
+ <X,Y,Z> X f(Y arg, Function<Y, Z> f) { return null; }
+
+ <X,Y,Z> X f2(Y arg, Function<Y, Z> f) { return null; }
+ <X,Y> X f2(Y arg, ToIntFunction<Y> f) { return null; }
+
+ <T> T g(T arg) { return null; }
+
+ void test() {
+ g(f("hi", id(x->1))); //ok
+ g(f("hi", id2(x->1))); //ambiguous
+ g(f2("hi", id(x->1))); //ok
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177b.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,2 @@
+T8016177b.java:31:19: compiler.err.ref.ambiguous: id2, kindname.method, <U,V>id2(T8016177b.Function<U,V>), T8016177b, kindname.method, <U>id2(T8016177b.ToIntFunction<U>), T8016177b
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177c.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,47 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8016081 8016178
+ * @summary structural most specific and stuckness
+ * @compile/fail/ref=T8016177c.out -XDrawDiagnostics T8016177c.java
+ */
+
+class T8016177c {
+
+ interface Function<X, Y> {
+ Y m(X x);
+ }
+
+ interface ExtFunction<X, Y> extends Function<X, Y> { }
+
+ <U, V> U m1(Function<U, V> f) { return null; }
+ <U, V> U m1(ExtFunction<U, V> f) { return null; }
+
+ void m2(Function<Integer, Integer> f) { }
+ void m2(ExtFunction<Integer, Integer> f) { }
+
+ void m3(Function<Integer, Integer> f) { }
+ void m3(ExtFunction<Object, Integer> f) { }
+
+ int g1(Object s) { return 1; }
+
+ int g2(Number s) { return 1; }
+ int g2(Object s) { return 1; }
+
+ void test() {
+ m1((Integer x)->x); //ok - explicit lambda - subtyping picks most specific
+ m2((Integer x)->x); //ok - explicit lambda - subtyping picks most specific
+ m3((Integer x)->x); //ok - explicit lambda (only one applicable)
+
+ m1(x->1); //ok - stuck lambda but nominal most specific wins
+ m2(x->1); //ok - stuck lambda but nominal most specific wins
+ m3(x->1); //ambiguous - implicit lambda & different params
+
+ m1(this::g1); //ok - unambiguous ref - subtyping picks most specific
+ m2(this::g1); //ok - unambiguous ref - subtyping picks most specific
+ m3(this::g1); //ambiguous - both applicable, neither most specific
+
+ m1(this::g2); //ok - stuck mref but nominal most specific wins
+ m2(this::g2); //ok - stuck mref but nominal most specific wins
+ m3(this::g2); //ambiguous - different params
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177c.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,4 @@
+T8016177c.java:37:9: compiler.err.ref.ambiguous: m3, kindname.method, m3(T8016177c.Function<java.lang.Integer,java.lang.Integer>), T8016177c, kindname.method, m3(T8016177c.ExtFunction<java.lang.Object,java.lang.Integer>), T8016177c
+T8016177c.java:41:9: compiler.err.ref.ambiguous: m3, kindname.method, m3(T8016177c.Function<java.lang.Integer,java.lang.Integer>), T8016177c, kindname.method, m3(T8016177c.ExtFunction<java.lang.Object,java.lang.Integer>), T8016177c
+T8016177c.java:45:9: compiler.err.ref.ambiguous: m3, kindname.method, m3(T8016177c.Function<java.lang.Integer,java.lang.Integer>), T8016177c, kindname.method, m3(T8016177c.ExtFunction<java.lang.Object,java.lang.Integer>), T8016177c
+3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177d.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
+ * @bug 8016081 8016178
+ * @summary structural most specific and stuckness
+ * @compile T8016177d.java
+ */
+import java.util.*;
+
+class T8016177d {
+
+ interface UnaryOperator<X> {
+ X m(X x);
+ }
+
+ interface IntStream {
+ IntStream sorted();
+ IntStream distinct();
+ IntStream limit(int i);
+ }
+
+ abstract class WrappingUnaryOperator<S> implements UnaryOperator<S> { }
+
+ <S1> WrappingUnaryOperator<S1> wrap1(UnaryOperator<S1> uo) { return null; }
+ <S2> WrappingUnaryOperator<S2> wrap2(UnaryOperator<S2> uo) { return null; }
+ <S3> WrappingUnaryOperator<S3> wrap3(UnaryOperator<S3> uo) { return null; }
+
+ <P> List<List<P>> perm(List<P> l) { return null; }
+
+ List<List<WrappingUnaryOperator<IntStream>>> intPermutationOfFunctions =
+ perm(Arrays.asList(
+ wrap1(s -> s.sorted()),
+ wrap2(s -> s.distinct()),
+ wrap3(s -> s.limit(5))
+ ));
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177e.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,46 @@
+/*
+ * 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 8016081 8016178
+ * @summary structural most specific and stuckness
+ * @compile T8016177e.java
+ */
+import java.util.*;
+
+class T8016177e {
+
+ interface TerminalOp<X, Y> { }
+
+ interface Consumer<X> {
+ void m(X x);
+ }
+
+ <T> TerminalOp<T, Void> makeRef(Consumer<? super T> action) { return null; }
+
+ <T> void test() {
+ Map<T, Boolean> map = null;
+ TerminalOp<T, Void> forEachOp = makeRef(t -> { map.put(t, null); });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177f.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,94 @@
+/*
+ * 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 8016081 8016178
+ * @summary structural most specific and stuckness
+ * @compile T8016177f.java
+ */
+import java.util.*;
+
+class T8016177f {
+
+ interface Function<S, T> {
+ T apply(S s);
+ }
+
+ interface IntFunction<T> {
+ T apply(int s);
+ }
+
+
+ interface BiConsumer<X,Y> {
+ void m(X x, Y y);
+ }
+
+ interface Consumer<X> {
+ void m(X x);
+ }
+
+ interface Supplier<X> {
+ X make();
+ }
+
+ interface TestData<T, S extends BaseStream<T, S>> {
+ interface OfRef<T> extends TestData<T, Stream<T>> { }
+ interface OfDouble extends TestData<Double, DoubleStream> { }
+ }
+
+ interface BaseStream<T, S extends BaseStream<T, S>> { }
+
+ interface Stream<T> extends BaseStream<T, Stream<T>> {
+ <M> Stream<M> map(Function<T, M> s);
+ <R> R collect(Supplier<R> resultFactory, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner);
+ <Z> Z[] toArray(IntFunction<Z[]> s);
+ }
+
+ interface DoubleStream extends BaseStream<Double, DoubleStream> {
+ DoubleStream filter(DoublePredicate dp);
+ double[] toArray();
+ }
+
+ interface DoublePredicate {
+ boolean p(double d);
+ }
+
+ <T, U, R, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
+ R exerciseTerminalOps(TestData<T, S_IN> data,
+ Function<S_IN, S_OUT> streamF,
+ Function<S_OUT, R> terminalF) { return null; }
+
+ <O> TestData.OfRef<O> ofCollection(Collection<O> collection) { return null; }
+
+ void test1(TestData.OfDouble data, DoublePredicate dp) {
+ exerciseTerminalOps(data, s -> s.filter(dp), s -> s.toArray());
+ }
+
+ void test2(Function<Double, Integer> fdi, TestData.OfRef<Double> td, Stream<Integer> si) {
+ exerciseTerminalOps(
+ ofCollection((List<Double>)null),
+ s -> s.map(fdi),
+ s -> s.toArray(Integer[]::new));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177g.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,37 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8016081 8016178
+ * @summary structural most specific and stuckness
+ * @compile/fail/ref=T8016177g.out -XDrawDiagnostics T8016177g.java
+ */
+
+
+class Test {
+
+ interface Function<X, Y> {
+ Y m(X x);
+ }
+
+ interface Box<T> {
+ T get();
+ <R> R map(Function<T,R> f);
+ }
+
+ static class Person {
+ Person(String name) { }
+ }
+
+ void print(Object arg) { }
+ void print(String arg) { }
+
+ int abs(int a) { return 0; }
+ long abs(long a) { return 0; }
+ float abs(float a) { return 0; }
+ double abs(double a) { return 0; }
+
+ void test() {
+ Box<String> b = null;
+ print(b.map(s -> new Person(s)));
+ int i = abs(b.map(s -> Double.valueOf(s)));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177g.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,2 @@
+T8016177g.java:35:20: compiler.err.prob.found.req: (compiler.misc.possible.loss.of.precision: double, int)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8023389/T8023389.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,46 @@
+/*
+ * 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 8023389
+ * @summary Javac fails to infer type for lambda used with intersection type and wildcards
+ * @compile T8023389.java
+ */
+public class T8023389 {
+
+ static class U1 {}
+ static class X1 extends U1 {}
+
+ interface I { }
+
+ interface SAM<T> {
+ void m(T t);
+ }
+
+ /* Strictly speaking only the second of the following declarations provokes the bug.
+ * But the first line is also a useful test case.
+ */
+ SAM<? extends U1> sam1 = (SAM<? extends U1>) (X1 x) -> { };
+ SAM<? extends U1> sam2 = (SAM<? extends U1> & I) (X1 x) -> { };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8023549/T8023549.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,27 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8023549
+ * @summary Compiler emitting spurious errors when constructor reference type is inferred and explicit type arguments are supplied
+ * @compile/fail/ref=T8023549.out -XDrawDiagnostics T8023549.java
+ */
+
+public class T8023549 {
+ static class Foo<X> { }
+
+ interface Supplier<X> {
+ X make();
+ }
+
+ interface ExtSupplier<X> extends Supplier<X> { }
+
+ void m1(Supplier<Foo<String>> sfs) { }
+
+ void m2(Supplier<Foo<String>> sfs) { }
+ void m2(ExtSupplier<Foo<Integer>> sfs) { }
+
+ void test() {
+ Supplier<Foo<String>> sfs = Foo::<Number>new;
+ m1(Foo::<Number>new);
+ m2(Foo::<Number>new);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8023549/T8023549.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,5 @@
+T8023549.java:23:37: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.mref.infer.and.explicit.params)
+T8023549.java:24:12: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.mref.infer.and.explicit.params)
+T8023549.java:25:9: compiler.err.ref.ambiguous: m2, kindname.method, m2(T8023549.Supplier<T8023549.Foo<java.lang.String>>), T8023549, kindname.method, m2(T8023549.ExtSupplier<T8023549.Foo<java.lang.Integer>>), T8023549
+T8023549.java:25:12: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.mref.infer.and.explicit.params)
+4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8023558/T8023558a.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,38 @@
+/*
+ * 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 8023558
+ * @summary Javac creates invalid bootstrap methods for complex lambda/methodref case
+ */
+public class T8023558a {
+ interface SAM<T> {
+ T get();
+ }
+
+ public static void main(String[] args) {
+ SAM<SAM> sam = new SAM<SAM>() { public SAM get() { return null; } };
+ SAM temp = sam.get()::get;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8023558/T8023558b.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
+ * @bug 8023558
+ * @summary Javac creates invalid bootstrap methods for complex lambda/methodref case
+ */
+public class T8023558b {
+
+ interface Supplier<X> {
+ X get();
+ }
+
+ static class A {
+ public A(Supplier<B> supplier) { }
+ }
+
+ static class B { }
+
+ static class C {
+ public B getB() {
+ return new B();
+ }
+ }
+
+ public static void main(String[] args) {
+ new T8023558b().test(T8023558b::getC);
+ }
+
+ private static C getC() {
+ return new C();
+ }
+
+ public void test(Supplier<C> supplier) {
+ new A(supplier.get()::getB);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8023558/T8023558c.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,39 @@
+/*
+ * 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 8023558
+ * @summary Javac creates invalid bootstrap methods for complex lambda/methodref case
+ */
+
+interface SAM<T> {
+ T get();
+}
+
+public class T8023558c {
+ public static void main(String[] args) {
+ SAM<SAM> sam = () -> Object::new;
+ SAM temp = sam.get()::get;
+ }
+}
--- a/langtools/test/tools/javac/lambda/BadRecovery.out Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/BadRecovery.out Fri Sep 20 19:15:59 2013 -0700
@@ -1,2 +1,3 @@
+BadRecovery.java:17:9: compiler.err.cant.apply.symbol: kindname.method, m, BadRecovery.SAM1, @369, kindname.class, BadRecovery, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.lambda))
BadRecovery.java:17:77: compiler.err.cant.resolve.location: kindname.variable, f, , , (compiler.misc.location: kindname.class, BadRecovery, null)
-1 error
+2 errors
--- a/langtools/test/tools/javac/lambda/EffectivelyFinalTest.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/EffectivelyFinalTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,6 +1,6 @@
/*
* @test /nodynamiccopyright/
- * @bug 8003280
+ * @bug 7175538 8003280
* @summary Add lambda tests
* Integrate effectively final check with DA/DU analysis
* @compile/fail/ref=EffectivelyFinalTest01.out -XDrawDiagnostics EffectivelyFinalTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/EffectivelyFinalThrows.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,25 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8019521
+ * @summary Check that enhanced rethrow/effectivelly final works correctly inside lambdas
+ * @compile EffectivelyFinalThrows.java
+ */
+
+class EffectivelyFinalThrows {
+ interface SAM<E extends Throwable> {
+ public void t() throws E;
+ }
+ <E extends Throwable> void test(SAM<E> s) throws E {
+ s.t();
+ }
+ void test2(SAM<Checked> s) throws Checked {
+ test(() -> {
+ try {
+ s.t();
+ } catch (Throwable t) {
+ throw t;
+ }
+ });
+ }
+ static class Checked extends Exception {}
+}
--- a/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -26,6 +26,7 @@
* @bug 8003280
* @summary Add lambda tests
* stale state after speculative attribution round leads to missing classfiles
+ * @compile/fail/ref=ErroneousLambdaExpr.out -XDrawDiagnostics ErroneousLambdaExpr.java
*/
public class ErroneousLambdaExpr<T> {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,2 @@
+ErroneousLambdaExpr.java:63:13: compiler.err.ref.ambiguous: call, kindname.method, call(ErroneousLambdaExpr.SAM1<T>), ErroneousLambdaExpr, kindname.method, call(ErroneousLambdaExpr.SAM2), ErroneousLambdaExpr
+1 error
--- a/langtools/test/tools/javac/lambda/MethodReference22.out Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference22.out Fri Sep 20 19:15:59 2013 -0700
@@ -3,13 +3,17 @@
MethodReference22.java:46:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String))
MethodReference22.java:47:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String))
MethodReference22.java:51:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m1, kindname.method, m1(MethodReference22,java.lang.String), MethodReference22, kindname.method, m1(java.lang.String), MethodReference22))
-MethodReference22.java:52:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1401, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m1, kindname.method, m1(MethodReference22,java.lang.String), MethodReference22, kindname.method, m1(java.lang.String), MethodReference22)))
+MethodReference22.java:52:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1401, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m1, kindname.method, m1(MethodReference22,java.lang.String), MethodReference22, kindname.method, m1(java.lang.String), MethodReference22)))
MethodReference22.java:53:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference22,java.lang.String), MethodReference22, kindname.method, m2(java.lang.String), MethodReference22))
-MethodReference22.java:54:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1504, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference22,java.lang.String), MethodReference22, kindname.method, m2(java.lang.String), MethodReference22)))
+MethodReference22.java:54:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1504, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference22,java.lang.String), MethodReference22, kindname.method, m2(java.lang.String), MethodReference22)))
MethodReference22.java:55:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference22,java.lang.String), MethodReference22, kindname.method, m3(java.lang.String), MethodReference22))
-MethodReference22.java:56:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1607, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference22,java.lang.String), MethodReference22, kindname.method, m3(java.lang.String), MethodReference22)))
+MethodReference22.java:56:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1607, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference22,java.lang.String), MethodReference22, kindname.method, m3(java.lang.String), MethodReference22)))
MethodReference22.java:57:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22))
-MethodReference22.java:58:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1710, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22)))
+MethodReference22.java:58:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1710, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22)))
+MethodReference22.java:62:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22
MethodReference22.java:62:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.String))
+MethodReference22.java:63:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22
+MethodReference22.java:64:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22
+MethodReference22.java:65:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22
MethodReference22.java:65:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String))
-14 errors
+18 errors
--- a/langtools/test/tools/javac/lambda/MethodReference23.out Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference23.out Fri Sep 20 19:15:59 2013 -0700
@@ -1,6 +1,6 @@
MethodReference23.java:52:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, MethodReference23, MethodReference23))
-MethodReference23.java:53:9: compiler.err.cant.apply.symbol: kindname.method, call11, MethodReference23.SAM11, @1140, kindname.class, MethodReference23, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, MethodReference23, MethodReference23)))
+MethodReference23.java:53:15: compiler.err.cant.apply.symbol: kindname.method, call11, MethodReference23.SAM11, @1140, kindname.class, MethodReference23, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, MethodReference23, MethodReference23)))
MethodReference23.java:57:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, , MethodReference23))
-MethodReference23.java:58:9: compiler.err.cant.apply.symbol: kindname.method, call12, MethodReference23.SAM12, @1282, kindname.class, MethodReference23, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, , MethodReference23)))
+MethodReference23.java:58:15: compiler.err.cant.apply.symbol: kindname.method, call12, MethodReference23.SAM12, @1282, kindname.class, MethodReference23, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, , MethodReference23)))
MethodReference23.java:72:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference23.SAM21), MethodReference23, kindname.method, call3(MethodReference23.SAM22), MethodReference23
5 errors
--- a/langtools/test/tools/javac/lambda/MethodReference41.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference41.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,42 +1,12 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 8003280
* @summary Add lambda tests
* check that diamond inference is applied when using raw constructor reference qualifier
- * @run main MethodReference41
+ * @compile/fail/ref=MethodReference41.out -XDrawDiagnostics MethodReference41.java
*/
-public class MethodReference41 {
-
- static int assertionCount = 0;
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
+public class MethodReference41 {
interface SAM1 {
void m(String s);
@@ -54,13 +24,20 @@
Foo(X x) { }
}
+ static void m1(SAM1 s) { }
- static void m(SAM1 s) { assertTrue(false); }
- static void m(SAM2 s) { assertTrue(true); }
- static void m(SAM3 s) { assertTrue(false); }
+ static void m2(SAM2 s) { }
+
+ static void m3(SAM3 s) { }
+
+ static void m4(SAM1 s) { }
+ static void m4(SAM2 s) { }
+ static void m4(SAM3 s) { }
public static void main(String[] args) {
- m(Foo::new);
- assertTrue(assertionCount == 1);
+ m1(Foo::new);
+ m2(Foo::new);
+ m3(Foo::new);
+ m4(Foo::new);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference41.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,4 @@
+MethodReference41.java:38:11: compiler.err.cant.apply.symbol: kindname.method, m1, MethodReference41.SAM1, @767, kindname.class, MethodReference41, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.String, kindname.class, MethodReference41.Foo<X>, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number))))
+MethodReference41.java:40:11: compiler.err.cant.apply.symbol: kindname.method, m3, MethodReference41.SAM3, @811, kindname.class, MethodReference41, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.Object, kindname.class, MethodReference41.Foo<X>, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number))))
+MethodReference41.java:41:9: compiler.err.ref.ambiguous: m4, kindname.method, m4(MethodReference41.SAM2), MethodReference41, kindname.method, m4(MethodReference41.SAM3), MethodReference41
+3 errors
--- a/langtools/test/tools/javac/lambda/MethodReference42.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference42.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,42 +1,12 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 8003280
* @summary Add lambda tests
* check that diamond inference is applied when using raw constructor reference qualifier
- * @run main MethodReference42
+ * @compile/fail/ref=MethodReference42.out -XDrawDiagnostics MethodReference42.java
*/
-public class MethodReference42 {
-
- static int assertionCount = 0;
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
+public class MethodReference42 {
static class SuperFoo<X> { }
@@ -54,12 +24,20 @@
SuperFoo<Object> m();
}
- static void m(SAM1 s) { assertTrue(false); }
- static void m(SAM2 s) { assertTrue(true); }
- static void m(SAM3 s) { assertTrue(false); }
+ static void m1(SAM1 s) { }
+
+ static void m2(SAM2 s) { }
+
+ static void m3(SAM3 s) { }
+
+ static void m4(SAM1 s) { }
+ static void m4(SAM2 s) { }
+ static void m4(SAM3 s) { }
public static void main(String[] args) {
- m(Foo::new);
- assertTrue(assertionCount == 1);
+ m1(Foo::new);
+ m2(Foo::new);
+ m3(Foo::new);
+ m4(Foo::new);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference42.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,4 @@
+MethodReference42.java:38:11: compiler.err.cant.apply.symbol: kindname.method, m1, MethodReference42.SAM1, @811, kindname.class, MethodReference42, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String, java.lang.Number))
+MethodReference42.java:40:11: compiler.err.cant.apply.symbol: kindname.method, m3, MethodReference42.SAM3, @855, kindname.class, MethodReference42, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.Object, java.lang.Number))
+MethodReference42.java:41:9: compiler.err.ref.ambiguous: m4, kindname.method, m4(MethodReference42.SAM2), MethodReference42, kindname.method, m4(MethodReference42.SAM3), MethodReference42
+3 errors
--- a/langtools/test/tools/javac/lambda/MethodReference43.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference43.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,42 +1,12 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 8003280
* @summary Add lambda tests
* check that diamond inference is applied when using raw constructor reference qualifier
- * @run main MethodReference43
+ * @compile/fail/ref=MethodReference43.out -XDrawDiagnostics MethodReference43.java
*/
-public class MethodReference43 {
-
- static int assertionCount = 0;
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
+public class MethodReference43 {
interface SAM1 {
Foo<?> m(String s);
@@ -58,14 +28,24 @@
Foo(X x) { }
}
+ static void m1(SAM1 s) { }
- static void m(SAM1 s) { assertTrue(false); }
- static void m(SAM2 s) { assertTrue(false); }
- static void m(SAM3 s) { assertTrue(false); }
- static void m(SAM4 s) { assertTrue(true); }
+ static void m2(SAM2 s) { }
+
+ static void m3(SAM3 s) { }
+
+ static void m4(SAM4 s) { }
+
+ static void m5(SAM1 s) { }
+ static void m5(SAM2 s) { }
+ static void m5(SAM3 s) { }
+ static void m5(SAM4 s) { }
public static void main(String[] args) {
- m(Foo::new);
- assertTrue(assertionCount == 1);
+ m1(Foo::new);
+ m2(Foo::new);
+ m3(Foo::new);
+ m4(Foo::new);
+ m5(Foo::new);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference43.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,5 @@
+MethodReference43.java:45:11: compiler.err.cant.apply.symbol: kindname.method, m1, MethodReference43.SAM1, @897, kindname.class, MethodReference43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.String, kindname.class, MethodReference43.Foo<X>, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number))))
+MethodReference43.java:47:11: compiler.err.cant.apply.symbol: kindname.method, m3, MethodReference43.SAM3, @941, kindname.class, MethodReference43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.Object, kindname.class, MethodReference43.Foo<X>, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number))))
+MethodReference43.java:49:9: compiler.err.ref.ambiguous: m5, kindname.method, m5(MethodReference43.SAM3), MethodReference43, kindname.method, m5(MethodReference43.SAM4), MethodReference43
+MethodReference43.java:49:11: compiler.err.cant.apply.symbol: kindname.method, m5, MethodReference43.SAM3, @985, kindname.class, MethodReference43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.Object, kindname.class, MethodReference43.Foo<X>, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number))))
+4 errors
--- a/langtools/test/tools/javac/lambda/MethodReference44.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference44.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,42 +1,12 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 8003280
* @summary Add lambda tests
* check that generic method reference is inferred when type parameters are omitted
- * @run main MethodReference44
+ * @compile/fail/ref=MethodReference44.out -XDrawDiagnostics MethodReference44.java
*/
-public class MethodReference44 {
-
- static int assertionCount = 0;
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
+public class MethodReference44 {
static class SuperFoo<X> { }
@@ -56,12 +26,20 @@
static <X extends Number> Foo<X> m() { return null; }
- static void g(SAM1 s) { assertTrue(false); }
- static void g(SAM2 s) { assertTrue(true); }
- static void g(SAM3 s) { assertTrue(false); }
+ static void g1(SAM1 s) { }
+
+ static void g2(SAM2 s) { }
+
+ static void g3(SAM3 s) { }
+
+ static void g4(SAM1 s) { }
+ static void g4(SAM2 s) { }
+ static void g4(SAM3 s) { }
public static void main(String[] args) {
- g(MethodReference44::m);
- assertTrue(assertionCount == 1);
+ g1(MethodReference44::m);
+ g2(MethodReference44::m);
+ g3(MethodReference44::m);
+ g4(MethodReference44::m);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference44.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,4 @@
+MethodReference44.java:40:11: compiler.err.cant.apply.symbol: kindname.method, g1, MethodReference44.SAM1, @864, kindname.class, MethodReference44, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String, java.lang.Number))
+MethodReference44.java:42:11: compiler.err.cant.apply.symbol: kindname.method, g3, MethodReference44.SAM3, @932, kindname.class, MethodReference44, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.Object, java.lang.Number))
+MethodReference44.java:43:9: compiler.err.ref.ambiguous: g4, kindname.method, g4(MethodReference44.SAM2), MethodReference44, kindname.method, g4(MethodReference44.SAM3), MethodReference44
+3 errors
--- a/langtools/test/tools/javac/lambda/MethodReference46.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference46.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,42 +1,12 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 8003280
* @summary Add lambda tests
* check that generic method reference is inferred when type parameters are omitted
- * @run main MethodReference46
+ * @compile/fail/ref=MethodReference46.out -XDrawDiagnostics MethodReference46.java
*/
-public class MethodReference46 {
-
- static int assertionCount = 0;
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
+public class MethodReference46 {
interface SAM1 {
void m(String s);
@@ -56,12 +26,20 @@
static <X extends Number> void m(X fx) { }
- static void g(SAM1 s) { assertTrue(false); }
- static void g(SAM2 s) { assertTrue(true); }
- static void g(SAM3 s) { assertTrue(false); }
+ static void g1(SAM1 s) { }
+
+ static void g2(SAM2 s) { }
+
+ static void g3(SAM3 s) { }
+
+ static void g4(SAM1 s) { }
+ static void g4(SAM2 s) { }
+ static void g4(SAM3 s) { }
public static void main(String[] args) {
- g(MethodReference46::m);
- assertTrue(assertionCount == 1);
+ g1(MethodReference46::m);
+ g2(MethodReference46::m);
+ g3(MethodReference46::m);
+ g4(MethodReference46::m);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference46.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,4 @@
+MethodReference46.java:40:11: compiler.err.cant.apply.symbol: kindname.method, g1, MethodReference46.SAM1, @809, kindname.class, MethodReference46, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m, X, java.lang.String, kindname.class, MethodReference46, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number))))
+MethodReference46.java:42:11: compiler.err.cant.apply.symbol: kindname.method, g3, MethodReference46.SAM3, @877, kindname.class, MethodReference46, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m, X, java.lang.Object, kindname.class, MethodReference46, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number))))
+MethodReference46.java:43:9: compiler.err.ref.ambiguous: g4, kindname.method, g4(MethodReference46.SAM2), MethodReference46, kindname.method, g4(MethodReference46.SAM3), MethodReference46
+3 errors
--- a/langtools/test/tools/javac/lambda/MethodReference47.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference47.java Fri Sep 20 19:15:59 2013 -0700
@@ -7,14 +7,6 @@
*/
public class MethodReference47 {
- static int assertionCount = 0;
-
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
-
interface SAM1 {
void m(Integer s);
}
@@ -34,7 +26,7 @@
static void g2(SAM2 s) { }
public static void main(String[] args) {
- g1(MethodReference46::m);
- g2(MethodReference46::m);
+ g1(MethodReference47::m);
+ g2(MethodReference47::m);
}
}
--- a/langtools/test/tools/javac/lambda/MethodReference47.out Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference47.out Fri Sep 20 19:15:59 2013 -0700
@@ -1,2 +1,2 @@
-MethodReference47.java:38:9: compiler.err.ref.ambiguous: g2, kindname.method, g2(MethodReference47.SAM1), MethodReference47, kindname.method, g2(MethodReference47.SAM2), MethodReference47
+MethodReference47.java:30:9: compiler.err.ref.ambiguous: g2, kindname.method, g2(MethodReference47.SAM1), MethodReference47, kindname.method, g2(MethodReference47.SAM2), MethodReference47
1 error
--- a/langtools/test/tools/javac/lambda/MethodReference48.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference48.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,42 +1,12 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 8003280
* @summary Add lambda tests
* check that raw qualifier in unbound method reference is inferred from descriptor
- * @run main MethodReference48
+ * @compile/fail/ref=MethodReference48.out -XDrawDiagnostics MethodReference48.java
*/
-public class MethodReference48 {
-
- static int assertionCount = 0;
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
+public class MethodReference48 {
static class Foo<X> {
X m() { return null; };
@@ -54,12 +24,20 @@
Object m(Foo<Integer> fi);
}
- static void g(SAM1 s) { assertTrue(false); } //return type not compatible
- static void g(SAM2 s) { assertTrue(true); } //ok
- static void g(SAM3 s) { assertTrue(false); } //ok but less specific
+ static void g1(SAM1 s) { } //return type not compatible
+
+ static void g2(SAM2 s) { } //ok
+
+ static void g3(SAM3 s) { } //ok
+
+ static void g4(SAM1 s) { } //return type not compatible
+ static void g4(SAM2 s) { } //ok
+ static void g4(SAM3 s) { } //ok
public static void main(String[] args) {
- g(Foo::m);
- assertTrue(assertionCount == 1);
+ g1(Foo::m);
+ g2(Foo::m);
+ g3(Foo::m);
+ g4(Foo::m);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference48.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,3 @@
+MethodReference48.java:38:11: compiler.err.cant.apply.symbol: kindname.method, g1, MethodReference48.SAM1, @869, kindname.class, MethodReference48, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: java.lang.String, MethodReference48.Foo<java.lang.Object>)))
+MethodReference48.java:41:9: compiler.err.ref.ambiguous: g4, kindname.method, g4(MethodReference48.SAM2), MethodReference48, kindname.method, g4(MethodReference48.SAM3), MethodReference48
+2 errors
--- a/langtools/test/tools/javac/lambda/MethodReference70.out Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference70.out Fri Sep 20 19:15:59 2013 -0700
@@ -1,3 +1,3 @@
MethodReference70.java:26:10: compiler.err.ref.ambiguous: g, kindname.method, <Z>g(MethodReference70.F<Z>), MethodReference70, kindname.method, <Z>g(MethodReference70.G<Z>), MethodReference70
-MethodReference70.java:26:11: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: Z)
+MethodReference70.java:26:11: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: Z, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbols: kindname.method, m2, java.lang.Object,{(compiler.misc.inapplicable.method: kindname.method, MethodReference70, m2(java.lang.Integer), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.Integer))),(compiler.misc.inapplicable.method: kindname.method, MethodReference70, m2(java.lang.String), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.String)))})))
2 errors
--- a/langtools/test/tools/javac/lambda/MethodReference71.out Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference71.out Fri Sep 20 19:15:59 2013 -0700
@@ -1,3 +1,3 @@
MethodReference71.java:24:10: compiler.err.ref.ambiguous: g, kindname.method, <Z>g(MethodReference71.F<Z>), MethodReference71, kindname.method, <Z>g(MethodReference71.G<Z>), MethodReference71
-MethodReference71.java:24:11: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: Z)
+MethodReference71.java:24:11: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: Z, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m2, java.lang.Integer[], java.lang.Object, kindname.class, MethodReference71, (compiler.misc.varargs.argument.mismatch: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.Integer)))))
2 errors
--- a/langtools/test/tools/javac/lambda/MostSpecific04.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MostSpecific04.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -26,17 +26,10 @@
* @bug 8003280
* @summary Add lambda tests
* Structural most specific doesn't handle cases with wildcards in functional interfaces
+ * @compile/fail/ref=MostSpecific04.out -XDrawDiagnostics MostSpecific04.java
*/
public class MostSpecific04 {
- static int assertionCount = 0;
-
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
-
interface DoubleMapper<T> {
double map(T t);
}
@@ -46,13 +39,13 @@
}
static class MyList<E> {
- void map(DoubleMapper<? super E> m) { assertTrue(false); }
- void map(LongMapper<? super E> m) { assertTrue(true); }
+ void map(DoubleMapper<? super E> m) { }
+ void map(LongMapper<? super E> m) { }
}
public static void main(String[] args) {
MyList<String> ls = new MyList<String>();
- ls.map(e->e.length());
- assertTrue(assertionCount == 1);
+ ls.map(e->e.length()); //ambiguous - implicit
+ ls.map((String e)->e.length()); //ok
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific04.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,2 @@
+MostSpecific04.java:48:11: compiler.err.ref.ambiguous: map, kindname.method, map(MostSpecific04.DoubleMapper<? super E>), MostSpecific04.MyList, kindname.method, map(MostSpecific04.LongMapper<? super E>), MostSpecific04.MyList
+1 error
--- a/langtools/test/tools/javac/lambda/MostSpecific05.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MostSpecific05.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -26,17 +26,10 @@
* @bug 8003280
* @summary Add lambda tests
* Structural most specific doesn't handle cases with wildcards in functional interfaces
+ * @compile/fail/ref=MostSpecific05.out -XDrawDiagnostics MostSpecific05.java
*/
public class MostSpecific05 {
- static int assertionCount = 0;
-
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
-
interface ObjectConverter<T extends Object> {
T map(Object o);
}
@@ -46,13 +39,13 @@
}
static class MyMapper<A extends Object, B extends Number> {
- void map(ObjectConverter<? extends A> m) { assertTrue(false); }
- void map(NumberConverter<? extends B> m) { assertTrue(true); }
+ void map(ObjectConverter<? extends A> m) { }
+ void map(NumberConverter<? extends B> m) { }
}
public static void main(String[] args) {
MyMapper<Number, Double> mm = new MyMapper<Number, Double>();
- mm.map(e->1.0);
- assertTrue(assertionCount == 1);
+ mm.map(e->1.0); //ambiguous - implicit
+ mm.map((Object e)->1.0); //ok
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific05.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,2 @@
+MostSpecific05.java:48:11: compiler.err.ref.ambiguous: map, kindname.method, map(MostSpecific05.ObjectConverter<? extends A>), MostSpecific05.MyMapper, kindname.method, map(MostSpecific05.NumberConverter<? extends B>), MostSpecific05.MyMapper
+1 error
--- a/langtools/test/tools/javac/lambda/MostSpecific08.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MostSpecific08.java Fri Sep 20 19:15:59 2013 -0700
@@ -25,7 +25,7 @@
* @test
* @bug 8008813
* @summary Structural most specific fails when method reference is passed to overloaded method
- * @compile MostSpecific08.java
+ * @compile/fail/ref=MostSpecific08.out -XDrawDiagnostics MostSpecific08.java
*/
class MostSpecific08 {
@@ -51,12 +51,14 @@
}
void testMref(Tester t) {
- IntResult pr = t.apply(C::getInt);
- ReferenceResult<Integer> rr = t.apply(C::getInteger);
+ IntResult pr = t.apply(C::getInt); //ok - unoverloaded mref
+ ReferenceResult<Integer> rr = t.apply(C::getInteger); //ok - unoverloaded mref
}
void testLambda(Tester t) {
- IntResult pr = t.apply(c->c.getInt());
- ReferenceResult<Integer> rr = t.apply(c->c.getInteger());
+ IntResult pr1 = t.apply(c->c.getInt()); //ambiguous - implicit
+ IntResult pr2 = t.apply((C c)->c.getInt()); //ok
+ ReferenceResult<Integer> rr1 = t.apply(c->c.getInteger()); //ambiguous - implicit
+ ReferenceResult<Integer> rr2 = t.apply((C c)->c.getInteger()); //ok
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific08.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,4 @@
+MostSpecific08.java:59:26: compiler.err.ref.ambiguous: apply, kindname.method, apply(MostSpecific08.PrimitiveFunction), MostSpecific08.Tester, kindname.method, <Z>apply(MostSpecific08.ReferenceFunction<Z>), MostSpecific08.Tester
+MostSpecific08.java:61:41: compiler.err.ref.ambiguous: apply, kindname.method, apply(MostSpecific08.PrimitiveFunction), MostSpecific08.Tester, kindname.method, <Z>apply(MostSpecific08.ReferenceFunction<Z>), MostSpecific08.Tester
+MostSpecific08.java:61:47: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: MostSpecific08.IntResult, MostSpecific08.ReferenceResult<java.lang.Integer>)
+3 errors
--- a/langtools/test/tools/javac/lambda/TargetType01.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType01.java Fri Sep 20 19:15:59 2013 -0700
@@ -26,7 +26,7 @@
* @bug 8003280 8009131
* @summary Add lambda tests
* check nested case of overload resolution and lambda parameter inference
- * @compile TargetType01.java
+ * @compile/fail/ref=TargetType01.out -XDrawDiagnostics TargetType01.java
*/
class TargetType01 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType01.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,3 @@
+TargetType01.java:45:9: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01
+TargetType01.java:45:26: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01
+2 errors
--- a/langtools/test/tools/javac/lambda/TargetType02.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType02.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 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,19 +27,11 @@
* @summary Add lambda tests
* check overload resolution and target type inference w.r.t. generic methods
* @author Maurizio Cimadamore
- * @run main TargetType02
+ * @compile/fail/ref=TargetType02.out -XDrawDiagnostics TargetType02.java
*/
public class TargetType02 {
- static int assertionCount = 0;
-
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
-
interface S1<X extends Number> {
X m(Integer x);
}
@@ -48,15 +40,16 @@
abstract X m(Integer x);
}
- static <Z extends Number> void call(S1<Z> s) { s.m(1); assertTrue(true); }
- static <Z extends String> void call(S2<Z> s) { s.m(2); assertTrue(false); }
+ static <Z extends Number> void call1(S1<Z> s) { }
+
+ static <Z extends String> void call2(S2<Z> s) { }
+
+ static <Z extends Number> void call3(S1<Z> s) { }
+ static <Z extends String> void call3(S2<Z> s) { }
void test() {
- call(i -> { toString(); return i; });
- }
-
- public static void main(String[] args) {
- new TargetType02().test();
- assertTrue(assertionCount == 1);
+ call1(i -> { toString(); return i; });
+ call2(i -> { toString(); return i; });
+ call3(i -> { toString(); return i; });
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType02.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,3 @@
+TargetType02.java:52:14: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.String)
+TargetType02.java:53:9: compiler.err.ref.ambiguous: call3, kindname.method, <Z>call3(TargetType02.S1<Z>), TargetType02, kindname.method, <Z>call3(TargetType02.S2<Z>), TargetType02
+2 errors
--- a/langtools/test/tools/javac/lambda/TargetType10.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType10.java Fri Sep 20 19:15:59 2013 -0700
@@ -1,10 +1,10 @@
/*
* @test /nodynamiccopyright/
- * @bug 8003280
+ * @bug 8003280 8016177
* @summary Add lambda tests
* check that wildcards in the target method of a lambda conversion is handled correctly
* @author Maurizio Cimadamore
- * @compile/fail/ref=TargetType10.out -XDrawDiagnostics TargetType10.java
+ * @compile TargetType10.java
*/
class TargetType10 {
--- a/langtools/test/tools/javac/lambda/TargetType10.out Fri Sep 20 17:11:32 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-TargetType10.java:17:18: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: B,A)
-1 error
--- a/langtools/test/tools/javac/lambda/TargetType21.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType21.java Fri Sep 20 19:15:59 2013 -0700
@@ -26,8 +26,10 @@
void test() {
call(x -> { throw new Exception(); }); //ambiguous
+ call((Integer x) -> { System.out.println(""); }); //ok (only one is void)
+ call((Integer x) -> { return (Object) null; }); //ok (only one returns Object)
call(x -> { System.out.println(""); }); //ambiguous
- call(x -> { return (Object) null; }); //cyclic inference
+ call(x -> { return (Object) null; }); //ambiguous
call(x -> { return null; }); //ambiguous
}
}
--- a/langtools/test/tools/javac/lambda/TargetType21.out Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType21.out Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,7 @@
TargetType21.java:28:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
-TargetType21.java:29:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
-TargetType21.java:30:13: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: A)
-TargetType21.java:31:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM1), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
-4 errors
+TargetType21.java:31:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
+TargetType21.java:32:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
+TargetType21.java:32:13: compiler.err.cant.apply.symbol: kindname.method, call, TargetType21.SAM2, @888, kindname.class, TargetType21, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.unexpected.ret.val)))
+TargetType21.java:33:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
+TargetType21.java:33:13: compiler.err.cant.apply.symbol: kindname.method, call, TargetType21.SAM2, @946, kindname.class, TargetType21, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.unexpected.ret.val)))
+6 errors
--- a/langtools/test/tools/javac/lambda/TargetType24.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType24.java Fri Sep 20 19:15:59 2013 -0700
@@ -29,11 +29,14 @@
}
void test(Array<String> as, final Array<Character> ac) {
- final boolean b1 = as.forAll(s -> ac.forAll(c -> false)); //ok
+ final boolean b1 = as.forAll((String s) -> ac.forAll((Character c) -> false)); //ok
+ final boolean b2 = as.forAll(s -> ac.forAll(c -> false)); //ambiguous
+ final boolean b3 = as.forAll((String s) -> ac.forAll(c -> false)); //ambiguous
+ final boolean b4 = as.forAll(s -> ac.forAll((Character c) -> false)); //ambiguous
final String s1 = as.forAll2(s -> ac.forAll2(c -> "")); //ok
- final boolean b2 = as.forAll(s -> ac.forAll(c -> "" )); //fail
+ final boolean b5 = as.forAll(s -> ac.forAll(c -> "" )); //fail
final String s2 = as.forAll2(s -> ac.forAll2(c -> false)); //fail
- final boolean b3 = as.forAll((F<String, Boolean>)s -> ac.forAll((F<Character, Boolean>)c -> "")); //fail
+ final boolean b6 = as.forAll((F<String, Boolean>)s -> ac.forAll((F<Character, Boolean>)c -> "")); //fail
final String s3 = as.forAll((FSub<String, String>)s -> ac.forAll((FSub<Character, String>)c -> false)); //fail
}
}
--- a/langtools/test/tools/javac/lambda/TargetType24.out Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType24.out Fri Sep 20 19:15:59 2013 -0700
@@ -1,5 +1,11 @@
-TargetType24.java:34:37: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, boolean)
-TargetType24.java:35:45: compiler.err.cant.apply.symbol: kindname.method, forAll2, TargetType24.FSub<java.lang.Character,java.lang.String>, @945, kindname.class, TargetType24.Array<A>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: boolean, java.lang.String)))
-TargetType24.java:36:101: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Boolean))
-TargetType24.java:37:104: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: boolean, java.lang.String))
-4 errors
+TargetType24.java:33:30: compiler.err.ref.ambiguous: forAll, kindname.method, forAll(TargetType24.F<A,java.lang.Boolean>), TargetType24.Array, kindname.method, forAll(TargetType24.FSub<A,java.lang.String>), TargetType24.Array
+TargetType24.java:33:45: compiler.err.ref.ambiguous: forAll, kindname.method, forAll(TargetType24.F<A,java.lang.Boolean>), TargetType24.Array, kindname.method, forAll(TargetType24.FSub<A,java.lang.String>), TargetType24.Array
+TargetType24.java:34:54: compiler.err.ref.ambiguous: forAll, kindname.method, forAll(TargetType24.F<A,java.lang.Boolean>), TargetType24.Array, kindname.method, forAll(TargetType24.FSub<A,java.lang.String>), TargetType24.Array
+TargetType24.java:35:30: compiler.err.ref.ambiguous: forAll, kindname.method, forAll(TargetType24.F<A,java.lang.Boolean>), TargetType24.Array, kindname.method, forAll(TargetType24.FSub<A,java.lang.String>), TargetType24.Array
+TargetType24.java:37:30: compiler.err.ref.ambiguous: forAll, kindname.method, forAll(TargetType24.F<A,java.lang.Boolean>), TargetType24.Array, kindname.method, forAll(TargetType24.FSub<A,java.lang.String>), TargetType24.Array
+TargetType24.java:37:45: compiler.err.ref.ambiguous: forAll, kindname.method, forAll(TargetType24.F<A,java.lang.Boolean>), TargetType24.Array, kindname.method, forAll(TargetType24.FSub<A,java.lang.String>), TargetType24.Array
+TargetType24.java:37:52: compiler.err.cant.apply.symbol: kindname.method, forAll, TargetType24.F<java.lang.Character,java.lang.Boolean>, @1149, kindname.class, TargetType24.Array<A>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Boolean)))
+TargetType24.java:38:53: compiler.err.cant.apply.symbol: kindname.method, forAll2, TargetType24.FSub<java.lang.Character,java.lang.String>, @1221, kindname.class, TargetType24.Array<A>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: boolean, java.lang.String)))
+TargetType24.java:39:101: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Boolean))
+TargetType24.java:40:104: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: boolean, java.lang.String))
+10 errors
--- a/langtools/test/tools/javac/lambda/TargetType26.out Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType26.out Fri Sep 20 19:15:59 2013 -0700
@@ -1,2 +1,2 @@
-TargetType26.java:16:11: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: Z)
+TargetType26.java:16:11: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: Z, (compiler.misc.not.a.functional.intf: java.lang.Object))
1 error
--- a/langtools/test/tools/javac/lambda/TargetType27.out Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType27.out Fri Sep 20 19:15:59 2013 -0700
@@ -1,2 +1,2 @@
-TargetType27.java:18:10: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: R)
+TargetType27.java:18:10: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: A,R, (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.not.a.functional.intf: java.lang.Object)))
1 error
--- a/langtools/test/tools/javac/lambda/TargetType39.out Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType39.out Fri Sep 20 19:15:59 2013 -0700
@@ -1,3 +1,3 @@
-TargetType39.java:19:13: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: U)
-TargetType39.java:20:13: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: V)
+TargetType39.java:19:13: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: U,V, (compiler.misc.incompatible.type.in.conditional: (compiler.misc.inconvertible.types: TargetType39.SAM<java.lang.String,java.lang.Void>, TargetType39.SAM<java.lang.Object,V>)))
+TargetType39.java:20:13: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: U,V, (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.incompatible.type.in.conditional: (compiler.misc.not.a.functional.intf: java.lang.Object))))
2 errors
--- a/langtools/test/tools/javac/lambda/TargetType43.out Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType43.out Fri Sep 20 19:15:59 2013 -0700
@@ -1,4 +1,5 @@
TargetType43.java:13:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
TargetType43.java:13:30: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null)
+TargetType43.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Object, @359, kindname.class, TargetType43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: java.lang.Object))
TargetType43.java:14:21: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null)
-3 errors
+4 errors
--- a/langtools/test/tools/javac/lambda/TargetType66.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType66.java Fri Sep 20 19:15:59 2013 -0700
@@ -17,8 +17,8 @@
void g(SAM2 s2) { }
void test() {
- g(x->{ String s = x; }); //g(SAM1)
- g(x->{ Integer i = x; }); //g(SAM2)
+ g(x->{ String s = x; }); //ambiguous
+ g(x->{ Integer i = x; }); //ambiguous
g(x->{ Object o = x; }); //ambiguous
g(x->{ Character c = x; }); //error: inapplicable methods
g(x->{ Character c = ""; }); //error: incompatible types
--- a/langtools/test/tools/javac/lambda/TargetType66.out Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType66.out Fri Sep 20 19:15:59 2013 -0700
@@ -1,4 +1,9 @@
+TargetType66.java:20:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66
+TargetType66.java:21:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66
+TargetType66.java:21:28: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer)
TargetType66.java:22:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66
-TargetType66.java:23:9: compiler.err.cant.apply.symbols: kindname.method, g, @578,{(compiler.misc.inapplicable.method: kindname.method, TargetType66, g(TargetType66.SAM1), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.arg.types.in.lambda: java.lang.String, (compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Character))))),(compiler.misc.inapplicable.method: kindname.method, TargetType66, g(TargetType66.SAM2), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.arg.types.in.lambda: java.lang.Integer, (compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Integer, java.lang.Character)))))}
+TargetType66.java:23:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66
+TargetType66.java:23:30: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Character)
+TargetType66.java:24:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66
TargetType66.java:24:30: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Character)
-3 errors
+8 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/bridge/template_tests/BridgeMethodTestCase.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,421 @@
+/*
+ * 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.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringJoiner;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import tools.javac.combo.*;
+
+import static org.testng.Assert.fail;
+
+/**
+ * BridgeMethodTestCase -- used for asserting linkage to bridges under separate compilation.
+ *
+ * Example test case:
+ * public void test1() throws IOException, ReflectiveOperationException {
+ * compileSpec("C(Bc1(A))");
+ * assertLinkage("C", LINKAGE_ERROR, "B1");
+ * recompileSpec("C(Bc1(Ac0))", "A");
+ * assertLinkage("C", "A0", "B1");
+ * }
+ *
+ * This compiles A, B, and C, asserts that C.m()Object does not exist, asserts
+ * that C.m()Number eventually invokes B.m()Number, recompiles B, and then asserts
+ * that the result of calling C.m()Object now arrives at A.
+ *
+ * @author Brian Goetz
+ */
+
+@Test
+public abstract class BridgeMethodTestCase extends JavacTemplateTestBase {
+
+ private static final String TYPE_LETTERS = "ABCDIJK";
+
+ private static final String BASE_INDEX_CLASS = "class C0 {\n" +
+ " int val;\n" +
+ " C0(int val) { this.val = val; }\n" +
+ " public int getVal() { return val; }\n" +
+ "}\n";
+ private static final String INDEX_CLASS_TEMPLATE = "class C#ID extends C#PREV {\n" +
+ " C#ID(int val) { super(val); }\n" +
+ "}\n";
+
+
+
+ protected static String LINKAGE_ERROR = "-1";
+
+ private List<File> compileDirs = new ArrayList<>();
+
+ /**
+ * Compile all the classes in a class spec, and put them on the classpath.
+ *
+ * The spec is the specification for a nest of classes, using the following notation
+ * A, B represent abstract classes
+ * C represents a concrete class
+ * I, J, K represent interfaces
+ * Lowercase 'c' following a class means that the method m() is concrete
+ * Lowercase 'a' following a class or interface means that the method m() is abstract
+ * Lowercase 'd' following an interface means that the method m() is default
+ * A number 0, 1, or 2 following the lowercase letter indicates the return type of that method
+ * 0 = Object, 1 = Number, 2 = Integer (these form an inheritance chain so bridges are generated)
+ * A classes supertypes follow its method spec, in parentheses
+ * Examples:
+ * C(Ia0, Jd0) -- C extends I and J, I has abstract m()Object, J has default m()Object
+ * Cc1(Ia0) -- C has concrete m()Number, extends I with abstract m()Object
+ * If a type must appear multiple times, its full spec must be in the first occurrence
+ * Example:
+ * C(I(Kd0), J(K))
+ */
+ protected void compileSpec(String spec) throws IOException {
+ compileSpec(spec, false);
+ }
+
+ /**
+ * Compile all the classes in a class spec, and assert that there were compilation errors.
+ */
+ protected void compileSpec(String spec, String... errorKeys) throws IOException {
+ compileSpec(spec, false, errorKeys);
+ }
+
+ protected void compileSpec(String spec, boolean debug, String... errorKeys) throws IOException {
+ ClassModel cm = new Parser(spec).parseClassModel();
+ for (int i = 0; i <= cm.maxIndex() ; i++) {
+ if (debug) System.out.println(indexClass(i));
+ addSourceFile(String.format("C%d.java", i), new StringTemplate(indexClass(i)));
+ }
+ for (Map.Entry<String, ClassModel> e : classes(cm).entrySet()) {
+ if (debug) System.out.println(e.getValue().toSource());
+ addSourceFile(e.getKey() + ".java", new StringTemplate(e.getValue().toSource()));
+ }
+ compileDirs.add(compile(true));
+ resetSourceFiles();
+ if (errorKeys.length == 0)
+ assertCompileSucceeded();
+ else
+ assertCompileErrors(errorKeys);
+ }
+
+ /**
+ * Recompile only a subset of classes in the class spec, as named by names,
+ * and put them on the classpath such that they shadow earlier versions of that class.
+ */
+ protected void recompileSpec(String spec, String... names) throws IOException {
+ List<String> nameList = Arrays.asList(names);
+ ClassModel cm = new Parser(spec).parseClassModel();
+ for (int i = 0; i <= cm.maxIndex() ; i++) {
+ addSourceFile(String.format("C%d.java", i), new StringTemplate(indexClass(i)));
+ }
+ for (Map.Entry<String, ClassModel> e : classes(cm).entrySet())
+ if (nameList.contains(e.getKey()))
+ addSourceFile(e.getKey() + ".java", new StringTemplate(e.getValue().toSource()));
+ compileDirs.add(compile(Arrays.asList(classPaths()), true));
+ resetSourceFiles();
+ assertCompileSucceeded();
+ }
+
+ protected void assertLinkage(String name, String... expected) throws ReflectiveOperationException {
+ for (int i=0; i<expected.length; i++) {
+ String e = expected[i];
+ if (e.equals(LINKAGE_ERROR)) {
+ try {
+ int actual = invoke(name, i);
+ fail("Expected linkage error, got" + fromNum(actual));
+ }
+ catch (LinkageError x) {
+ // success
+ }
+ }
+ else {
+ if (e.length() == 1)
+ e += "0";
+ int expectedInt = toNum(e);
+ int actual = invoke(name, i);
+ if (expectedInt != actual)
+ fail(String.format("Expected %s but found %s for %s.m()%d", fromNum(expectedInt), fromNum(actual), name, i));
+ }
+ }
+ }
+
+ private Map<String, ClassModel> classes(ClassModel cm) {
+ HashMap<String, ClassModel> m = new HashMap<>();
+ classesHelper(cm, m);
+ return m;
+ }
+
+ private String indexClass(int index) {
+ if (index == 0) {
+ return BASE_INDEX_CLASS;
+ } else {
+ return INDEX_CLASS_TEMPLATE
+ .replace("#ID", String.valueOf(index))
+ .replace("#PREV", String.valueOf(index - 1));
+ }
+ }
+
+ private static String overrideName(int index) {
+ return "C" + index;
+ }
+
+ private void classesHelper(ClassModel cm, Map<String, ClassModel> m) {
+ if (!m.containsKey(cm.name))
+ m.put(cm.name, cm);
+ for (ClassModel s : cm.supertypes)
+ classesHelper(s, m);
+ }
+
+ private static String fromNum(int num) {
+ return String.format("%c%d", TYPE_LETTERS.charAt(num / 10), num % 10);
+ }
+
+ private static int toNum(String name, int index) {
+ return 10*(TYPE_LETTERS.indexOf(name.charAt(0))) + index;
+ }
+
+ private static int toNum(String string) {
+ return 10*(TYPE_LETTERS.indexOf(string.charAt(0))) + Integer.parseInt(string.substring(1, 2));
+ }
+
+ private int invoke(String name, int index) throws ReflectiveOperationException {
+ File[] files = classPaths();
+ Class clazz = loadClass(name, files);
+ Method[] ms = clazz.getMethods();
+ for (Method m : ms) {
+ if (m.getName().equals("m") && m.getReturnType().getName().equals(overrideName(index))) {
+ m.setAccessible(true);
+ Object instance = clazz.newInstance();
+ Object c0 = m.invoke(instance);
+ Method getVal = c0.getClass().getMethod("getVal");
+ getVal.setAccessible(true);
+ return (int)getVal.invoke(c0);
+ }
+ }
+ throw new NoSuchMethodError("cannot find method m()" + index + " in class " + name);
+ }
+
+ private File[] classPaths() {
+ File[] files = new File[compileDirs.size()];
+ for (int i=0; i<files.length; i++)
+ files[files.length - i - 1] = compileDirs.get(i);
+ return files;
+ }
+
+ @BeforeMethod
+ @Override
+ public void reset() {
+ compileDirs.clear();
+ super.reset();
+ }
+
+ private static class ClassModel {
+
+ enum MethodType {
+ ABSTRACT('a'), CONCRETE('c'), DEFAULT('d');
+
+ public final char designator;
+
+ MethodType(char designator) {
+ this.designator = designator;
+ }
+
+ public static MethodType find(char c) {
+ for (MethodType m : values())
+ if (m.designator == c)
+ return m;
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private final String name;
+ private final boolean isInterface;
+ private final List<ClassModel> supertypes;
+ private final MethodType methodType;
+ private final int methodIndex;
+
+ private ClassModel(String name,
+ boolean anInterface,
+ List<ClassModel> supertypes,
+ MethodType methodType,
+ int methodIndex) {
+ this.name = name;
+ isInterface = anInterface;
+ this.supertypes = supertypes;
+ this.methodType = methodType;
+ this.methodIndex = methodIndex;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(name);
+ if (methodType != null) {
+ sb.append(methodType.designator);
+ sb.append(methodIndex);
+ }
+ if (!supertypes.isEmpty()) {
+ sb.append("(");
+ for (int i=0; i<supertypes.size(); i++) {
+ if (i > 0)
+ sb.append(",");
+ sb.append(supertypes.get(i).toString());
+ }
+ sb.append(")");
+ }
+ return sb.toString();
+ }
+
+ int maxIndex() {
+ int maxSoFar = methodIndex;
+ for (ClassModel cm : supertypes) {
+ maxSoFar = Math.max(cm.maxIndex(), maxSoFar);
+ }
+ return maxSoFar;
+ }
+
+ public String toSource() {
+ String extendsClause = "";
+ String implementsClause = "";
+ String methodBody = "";
+ boolean isAbstract = "AB".contains(name);
+
+ for (ClassModel s : supertypes) {
+ if (!s.isInterface) {
+ extendsClause = String.format("extends %s", s.name);
+ break;
+ }
+ }
+
+ StringJoiner sj = new StringJoiner(", ");
+ for (ClassModel s : supertypes)
+ if (s.isInterface)
+ sj.add(s.name);
+ if (sj.length() > 0) {
+ if (isInterface)
+ implementsClause = "extends " + sj.toString();
+ else
+ implementsClause = "implements " + sj.toString();
+ }
+ if (methodType != null) {
+ switch (methodType) {
+ case ABSTRACT:
+ methodBody = String.format("public abstract %s m();", overrideName(methodIndex));
+ break;
+ case CONCRETE:
+ methodBody = String.format("public %s m() { return new %s(%d); };",
+ overrideName(methodIndex), overrideName(methodIndex), toNum(name, methodIndex));
+ break;
+ case DEFAULT:
+ methodBody = String.format("public default %s m() { return new %s(%d); };",
+ overrideName(methodIndex), overrideName(methodIndex), toNum(name, methodIndex));
+ break;
+
+ }
+ }
+
+ return String.format("public %s %s %s %s %s { %s }", isAbstract ? "abstract" : "",
+ isInterface ? "interface" : "class",
+ name, extendsClause, implementsClause, methodBody);
+ }
+ }
+
+ private static class Parser {
+ private final String input;
+ private final char[] chars;
+ private int index;
+
+ private Parser(String s) {
+ input = s;
+ chars = s.toCharArray();
+ }
+
+ private char peek() {
+ return index < chars.length ? chars[index] : 0;
+ }
+
+ private boolean peek(String validChars) {
+ return validChars.indexOf(peek()) >= 0;
+ }
+
+ private char advanceIf(String validChars) {
+ if (peek(validChars))
+ return chars[index++];
+ else
+ return 0;
+ }
+
+ private char advanceIfDigit() {
+ return advanceIf("0123456789");
+ }
+
+ private int index() {
+ StringBuilder buf = new StringBuilder();
+ char c = advanceIfDigit();
+ while (c != 0) {
+ buf.append(c);
+ c = advanceIfDigit();
+ }
+ return Integer.valueOf(buf.toString());
+ }
+
+ private char advance() {
+ return chars[index++];
+ }
+
+ private char expect(String validChars) {
+ char c = advanceIf(validChars);
+ if (c == 0)
+ throw new IllegalArgumentException(String.format("Expecting %s at position %d of %s", validChars, index, input));
+ return c;
+ }
+
+ public ClassModel parseClassModel() {
+ List<ClassModel> supers = new ArrayList<>();
+ char name = expect(TYPE_LETTERS);
+ boolean isInterface = "IJK".indexOf(name) >= 0;
+ ClassModel.MethodType methodType = peek(isInterface ? "ad" : "ac") ? ClassModel.MethodType.find(advance()) : null;
+ int methodIndex = 0;
+ if (methodType != null) {
+ methodIndex = index();
+ }
+ if (peek() == '(') {
+ advance();
+ supers.add(parseClassModel());
+ while (peek() == ',') {
+ advance();
+ supers.add(parseClassModel());
+ }
+ expect(")");
+ }
+ return new ClassModel(new String(new char[]{ name }), isInterface, supers, methodType, methodIndex);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/bridge/template_tests/BridgeMethodsTemplateTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,1082 @@
+/*
+ * 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.io.IOException;
+
+import org.testng.annotations.Test;
+
+/**
+ * BridgeMethodsTemplateTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class BridgeMethodsTemplateTest extends BridgeMethodTestCase {
+
+ /*
+ * Cc1(A) -> Cc1(Ac0)
+ *
+ * 0*: Inherited from A
+ * 1: Declared in C
+ */
+ public void test1() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc1(A)");
+ assertLinkage("C", LINKAGE_ERROR, "C1");
+ recompileSpec("Cc1(Ac0)", "A");
+ assertLinkage("C", "A0", "C1");
+ }
+
+ /*
+ * Cc1(I) -> Cc1(Id0)
+ *
+ * 0*: Inherited default from I
+ * 1: Declared in C
+ */
+ public void test2() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc1(I)");
+ assertLinkage("C", LINKAGE_ERROR, "C1");
+ recompileSpec("Cc1(Id0)", "I");
+ assertLinkage("C", "I0", "C1");
+ }
+
+ /*
+ * C(Bc1(A)) -> C(Bc1(Ac0))
+ *
+ * 0*: Inherited from A
+ * 1: Inherited from B
+ */
+ public void test3() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Bc1(A))");
+ assertLinkage("C", LINKAGE_ERROR, "B1");
+ recompileSpec("C(Bc1(Ac0))", "A");
+ assertLinkage("C", "A0", "B1");
+ }
+
+ /*
+ * C(B(Ac0)) -> C(Bc1(Ac0))
+ *
+ * 0: Inherited from B (through bridge)
+ * 1: Inherited from B
+ */
+ public void test4() throws IOException, ReflectiveOperationException {
+ compileSpec("C(B(Ac0))");
+ assertLinkage("C", "A0", LINKAGE_ERROR);
+ recompileSpec("C(Bc1(Ac0))", "B");
+ assertLinkage("C", "B1", "B1");
+ }
+
+ /*
+ * C(B(A)) -> C(Bc1(Ac0))
+ *
+ * 0: Inherited from B (through bridge)
+ * 1: Inherited from B
+ */
+ public void test5() throws IOException, ReflectiveOperationException {
+ compileSpec("C(B(A))");
+ assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR);
+ recompileSpec("C(Bc1(Ac0))", "A", "B");
+ assertLinkage("C", "B1", "B1");
+ }
+
+ /*
+ * C(Ac1(I)) -> C(Ac1(Id0))
+ *
+ * 0*: Inherited default from I
+ * 1: Inherited from A
+ */
+ public void test6() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Ac1(I))");
+ assertLinkage("C", LINKAGE_ERROR, "A1");
+ recompileSpec("C(Ac1(Id0))", "I");
+ assertLinkage("C", "I0", "A1");
+ }
+
+ /*
+ * C(A(Id0)) -> C(Ac1(Id0))
+ *
+ * 0: Inherited from A (through bridge)
+ * 1: Inherited from A
+ */
+ public void test7() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Id0))");
+ assertLinkage("C", "I0", LINKAGE_ERROR);
+ recompileSpec("C(Ac1(Id0))", "A");
+ assertLinkage("C", "A1", "A1");
+ }
+
+ /*
+ * C(A(I)) -> C(Ac1(Id0))
+ *
+ * 0*: Inherited from A (through bridge)
+ * 1*: Inherited from A
+ */
+ public void test8() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(I))");
+ assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR);
+ recompileSpec("C(Ac1(Id0))", "A", "I");
+ assertLinkage("C", "A1", "A1");
+ }
+
+ /*
+ * C(Id1(J)) -> C(Id1(Jd0))
+ *
+ * 0*: Inherited default from J
+ * 1: Inherited default from I
+ */
+ public void test9() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Id1(J))");
+ assertLinkage("C", LINKAGE_ERROR, "I1");
+ recompileSpec("C(Id1(Jd0))", "J");
+ assertLinkage("C", "J0", "I1");
+ }
+
+ /*
+ * C(I(Jd0)) -> C(Id1(Jd0))
+ *
+ * 0: Inherited default from I (through bridge)
+ * 1: Inherited default from I
+ */
+ public void test10() throws IOException, ReflectiveOperationException {
+ compileSpec("C(I(Jd0))");
+ assertLinkage("C", "J0", LINKAGE_ERROR);
+ recompileSpec("C(Id1(Jd0))", "I");
+ assertLinkage("C", "I1", "I1");
+ }
+
+ /*
+ * C(I(J)) -> C(Id1(Jd0))
+ *
+ * 0: Inherited default from I (through bridge)
+ * 1: Inherited default from I
+ */
+ public void test11() throws IOException, ReflectiveOperationException {
+ compileSpec("C(I(J))");
+ assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR);
+ recompileSpec("C(Id1(Jd0))", "I", "J");
+ assertLinkage("C", "I1", "I1");
+ }
+
+ /*
+ * Cc2(B(Ac0)) -> Cc2(Bc1(Ac0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from B
+ * 2: Declared in C
+ */
+ public void test12() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(B(Ac0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Bc1(Ac0))", "B");
+ assertLinkage("C", "C2", "B1", "C2");
+ }
+
+ /*
+ * Cc2(B(Aa0)) -> Cc2(Bc1(Aa0))
+ *
+ * 0: Bridge in C (through bridge)
+ * 1*: Inherited from B
+ * 2: Declared in C
+ */
+ public void test13() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(B(Aa0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Bc1(Aa0))", "B");
+ assertLinkage("C", "C2", "B1", "C2");
+ }
+
+ /*
+ * Cc2(Bc1(A)) -> Cc2(Bc1(Ac0))
+ *
+ * 0*: Inherited from A
+ * 1: Declared in C (through bridge)
+ * 2: Declared in C
+ */
+ public void test14() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Bc1(A))");
+ assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+ recompileSpec("Cc2(Bc1(Ac0))", "A");
+ assertLinkage("C", "A0", "C2", "C2");
+ }
+
+ /*
+ * Cc2(Ba1(A)) -> Cc2(Ba1(Ac0))
+ *
+ * 0*: Inherited from A
+ * 1: Declared in C (through bridge)
+ * 2: Declared in C
+ */
+ public void test15() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Ba1(A))");
+ assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+ recompileSpec("Cc2(Ba1(Ac0))", "A");
+ assertLinkage("C", "A0", "C2", "C2");
+ }
+
+ /*
+ * Cc2(B(A)) -> Cc2(Bc1(Ac0))
+ *
+ * 0*: Inherited from B (through bridge)
+ * 1*: Inherited from B
+ * 2: Declared in C
+ */
+ public void test16() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(B(A))");
+ assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Bc1(Ac0))", "B", "A");
+ assertLinkage("C", "B1", "B1", "C2");
+ }
+
+ /*
+ * Cc2(A(Id0)) -> Cc2(Ac1(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C
+ */
+ public void test17() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A(Id0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Ac1(Id0))", "A");
+ assertLinkage("C", "C2", "A1", "C2");
+ }
+
+ /*
+ * Cc2(A(Ia0)) -> Cc2(Ac1(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C
+ */
+ public void test18() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A(Ia0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Ac1(Ia0))", "A");
+ assertLinkage("C", "C2", "A1", "C2");
+ }
+
+ /*
+ * Cc2(Ac1(I)) -> Cc2(Ac1(Id0))
+ *
+ * 0*: Inherited from I
+ * 1: Declared in C (through bridge)
+ * 2: Declared in C
+ */
+ public void test19() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Ac1(I))");
+ assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+ recompileSpec("Cc2(Ac1(Id0))", "I");
+ assertLinkage("C", "I0", "C2", "C2");
+ }
+
+ /*
+ * Cc2(Aa1(I)) -> Cc2(Aa1(Id0))
+ *
+ * 0*: Inherited from I
+ * 1: Declared in C (through bridge)
+ * 2: Declared in C
+ */
+ public void test20() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Aa1(I))");
+ assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+ recompileSpec("Cc2(Aa1(Id0))", "I");
+ assertLinkage("C", "I0", "C2", "C2");
+ }
+
+ /*
+ * Cc2(A(I)) -> Cc2(Ac1(Id0))
+ *
+ * 0*: Inherited from A (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C
+ */
+ public void test21() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A(I))");
+ assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Ac1(Id0))", "A", "I");
+ assertLinkage("C", "A1", "A1", "C2");
+ }
+
+ /*
+ * Cc2(J(Id0)) -> Cc2(Jd1(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test22() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(J(Id0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Jd1(Id0))", "J");
+ assertLinkage("C", "C2", "J1", "C2");
+ }
+
+ /*
+ * Cc2(J(Ia0)) -> Cc2(Jd1(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test23() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(J(Ia0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Jd1(Ia0))", "J");
+ assertLinkage("C", "C2", "J1", "C2");
+ }
+
+ /*
+ * Cc2(Jd1(I)) -> Cc2(Jd1(Id0))
+ *
+ * 0*: Inherited default from I
+ * 1: Declared in C (through bridge)
+ * 2: Declared in C
+ */
+ public void test24() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Jd1(I))");
+ assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+ recompileSpec("Cc2(Jd1(Id0))", "I");
+ assertLinkage("C", "I0", "C2", "C2");
+ }
+
+ /*
+ * Cc2(Ja1(I)) -> Cc2(Ja1(Id0))
+ *
+ * 0*: Inherited default from I
+ * 1: Declared in C (through bridge)
+ * 2: Declared in C
+ */
+ public void test25() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Ja1(I))");
+ assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+ recompileSpec("Cc2(Ja1(Id0))", "I");
+ assertLinkage("C", "I0", "C2", "C2");
+ }
+
+ /*
+ * Cc2(J(I)) -> Cc2(Jd1(Id0))
+ *
+ * 0*: Inherited default from J (through bridge)
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test26() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(J(I))");
+ assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Jd1(Id0))", "J", "I");
+ assertLinkage("C", "J1", "J1", "C2");
+ }
+
+ /*
+ * C(Ac1, I) -> C(Ac1, Id0)
+ *
+ * 0*: Inherited default from I
+ * 1: Inherited from A
+ */
+ public void test27() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Ac1,I)");
+ assertLinkage("C", LINKAGE_ERROR, "A1");
+ recompileSpec("C(Ac1,Id0)", "I");
+ assertLinkage("C", "I0", "A1");
+ }
+
+ /*
+ * C(A, Id0) -> C(Ac1, Id0)
+ *
+ * 0*: Inherited default from I
+ * 1: Inherited from A
+ */
+ public void test28() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A,Id0)");
+ assertLinkage("C", "I0", LINKAGE_ERROR);
+ recompileSpec("C(Ac1,Id0)", "A");
+ assertLinkage("C", "I0", "A1");
+ }
+
+ /*
+ * C(A, I) -> C(Ac1, Id0)
+ *
+ * 0*: Inherited default from I
+ * 1: Inherited from A
+ */
+ public void test29() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A,I)");
+ assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR);
+ recompileSpec("C(Ac1,Id0)", "A", "I");
+ assertLinkage("C", "I0", "A1");
+ }
+
+ /*
+ * Cc2(Ac1, I) -> Cc2(Ac1, Id0)
+ *
+ * 0*: Inherited default from I
+ * 1: Declared in C (through bridge)
+ * 2: Declared in C
+ */
+ public void test30() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Ac1,I)");
+ assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+ recompileSpec("Cc2(Ac1,Id0)", "I");
+ assertLinkage("C", "I0", "C2", "C2");
+ }
+
+ /*
+ * Cc2(Aa1, I) -> Cc2(Aa1, Id0)
+ *
+ * 0*: Inherited default from I
+ * 1: Declared in C (through bridge)
+ * 2: Declared in C
+ */
+ public void test31() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Aa1,I)");
+ assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+ recompileSpec("Cc2(Aa1,Id0)", "I");
+ assertLinkage("C", "I0", "C2", "C2");
+ }
+
+ /*
+ * Cc2(A, Id0) -> Cc2(Ac1, Id0)
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C
+ */
+ public void test32() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A,Id0)");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Ac1,Id0)", "A");
+ assertLinkage("C", "C2", "A1", "C2");
+ }
+
+ /*
+ * Cc2(A, Ia0) -> Cc2(Ac1, Ia0)
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C
+ */
+ public void test33() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A,Ia0)");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Ac1,Ia0)", "A");
+ assertLinkage("C", "C2", "A1", "C2");
+ }
+
+ /*
+ * Cc2(A, I) -> Cc2(Ac1, Id0)
+ *
+ * 0*: Inherited from A
+ * 1*: Inherited default from I
+ * 2: Declared in C
+ */
+ public void test34() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A,I)");
+ assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Ac1,Id0)", "A", "I");
+ assertLinkage("C", "I0", "A1", "C2");
+ }
+
+ /*
+ * Cc2(Id0, J) -> Cc2(Id0, Jd1)
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test35() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Id0,J)");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Id0,Jd1)", "J");
+ assertLinkage("C", "C2", "J1", "C2");
+ }
+
+ /*
+ * Cc2(Ia0, J) -> Cc2(Ia0, Jd1)
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test36() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Ia0,J)");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Ia0,Jd1)", "J");
+ assertLinkage("C", "C2", "J1", "C2");
+ }
+
+ /*
+ * Cc2(I, J) -> Cc2(Id0, Jd1)
+ *
+ * 0*: Inherited default from I
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test37() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(I,J)");
+ assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Id0,Jd1)", "I", "J");
+ assertLinkage("C", "I0", "J1", "C2");
+ }
+
+ /*
+ * C(A(Id0), J(Id0)) -> C(Ac1(Id0), J(Id0))
+ *
+ * 0: Inherited default from I
+ * 0*: Inherited from A (through bridge)
+ * 1*: Inherited from A
+ */
+ public void test38() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Id0),J(Id0))");
+ assertLinkage("C", "I0", LINKAGE_ERROR);
+ recompileSpec("C(Ac1(Id0),J(Id0))", "A");
+ assertLinkage("C", "A1", "A1");
+ }
+
+ /*
+ * C(A(Id0), J(Id0)) -> C(A(Id0), Jd1(Id0))
+ *
+ * 0: Inherited default from I
+ * 0: Inherited default from J (through bridge)
+ * 1*: Inherited default from J
+ */
+ public void test39() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Id0),J(Id0))");
+ assertLinkage("C", "I0", LINKAGE_ERROR);
+ recompileSpec("C(A(Id0),Jd1(Id0))", "J");
+ assertLinkage("C", "J1", "J1");
+ }
+
+ /*
+ * C(A(Id0), J(Id0)) -> C(Ac2(Id0), Jd1(Id0))
+ *
+ * 0: Inherited default from I
+ * 0*: Inherited from A (new bridge in A beats new bridge in J)
+ * 1*: Inherited default from J
+ * 2: Inherited from A
+ */
+ public void test40() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Id0),J(Id0))");
+ assertLinkage("C", "I0", LINKAGE_ERROR);
+ recompileSpec("C(Ac2(Id0),Jd1(Id0))", "A", "J");
+ assertLinkage("C", "A2", "J1", "A2");
+ }
+
+ /*
+ * C(J(Id0), K(Id0)) -> C(Jd1(Id0), K(Id0))
+ *
+ * 0: Inherited from I
+ * 0*: Inherited default from J (through bridge)
+ * 1: Inherited default from J
+ */
+ public void test41() throws IOException, ReflectiveOperationException {
+ compileSpec("C(J(Id0),K(Id0))");
+ assertLinkage("C", "I0", LINKAGE_ERROR);
+ recompileSpec("C(Jd1(Id0),K(Id0))", "J");
+ assertLinkage("C", "J1", "J1");
+ }
+
+ /*
+ * C(Ac2(Id0), J(Id0)) -> C(Ac2(Id0), Jd1(Id0))
+ *
+ * 0: Inherited from A (bridge in A beats new bridge in J)
+ * 1*: Inherited default from J
+ * 2: Inherited from A
+ */
+ public void test42() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Ac2(Id0),J(Id0))");
+ assertLinkage("C", "A2", LINKAGE_ERROR, "A2");
+ recompileSpec("C(Ac2(Id0),Jd1(Id0))", "J");
+ assertLinkage("C", "A2", "J1", "A2");
+ }
+
+ /*
+ * C(Ac2(Ia0), J(Ia0)) -> C(Ac2(Ia0), Jd1(Ia0))
+ *
+ * 0: Inherited from A (bridge in A beats new bridge in J)
+ * 1*: Inherited default from J
+ * 2: Inherited from A
+ */
+ public void test43() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Ac2(Ia0),J(Ia0))");
+ assertLinkage("C", "A2", LINKAGE_ERROR, "A2");
+ recompileSpec("C(Ac2(Ia0),Jd1(Ia0))", "J");
+ assertLinkage("C", "A2", "J1", "A2");
+ }
+
+ /*
+ * C(A(Id0), Jd1(Id0)) -> C(Ac2(Id0), Jd1(Id0))
+ *
+ * 0: Inherited from J
+ * 0*: Inherited from A (new bridge in A beats bridge in J)
+ * 1: Inherited default from J
+ * 2*: Inherited from A
+ */
+ public void test44() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Id0),Jd1(Id0))");
+ assertLinkage("C", "J1", "J1", LINKAGE_ERROR);
+ recompileSpec("C(Ac2(Id0),Jd1(Id0))", "A");
+ assertLinkage("C", "A2", "J1", "A2");
+ }
+
+ /*
+ * C(A(Ia0), Jd1(Ia0)) -> C(Ac2(Ia0), Jd1(Ia0))
+ *
+ * 0: Inherited from J
+ * 0*: Inherited from A (new bridge in A beats bridge in J)
+ * 1: Inherited default from J
+ * 2*: Inherited from A
+ */
+ public void test45() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Ia0),Jd1(Ia0))");
+ assertLinkage("C", "J1", "J1", LINKAGE_ERROR);
+ recompileSpec("C(Ac2(Ia0),Jd1(Ia0))", "A");
+ assertLinkage("C", "A2", "J1", "A2");
+ }
+
+ /*
+ * Cc2(A(Id0), J(Id0)) -> Cc2(Ac1(Id0), J(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C
+ */
+ public void test46() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A(Id0),J(Id0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Ac1(Id0),J(Id0))", "A");
+ assertLinkage("C", "C2", "A1", "C2");
+ }
+
+ /*
+ * Cc2(A(Ia0), J(Ia0)) -> Cc2(Ac1(Ia0), J(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C
+ */
+ public void test47() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A(Ia0),J(Ia0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Ac1(Ia0),J(Ia0))", "A");
+ assertLinkage("C", "C2", "A1", "C2");
+ }
+
+ /*
+ * Cc2(A(Id0), J(Id0)) -> Cc2(A(Id0), Jd1(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test48() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A(Id0),J(Id0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(A(Id0),Jd1(Id0))", "J");
+ assertLinkage("C", "C2", "J1", "C2");
+ }
+
+ /*
+ * Cc2(A(Ia0), J(Ia0)) -> Cc2(A(Ia0), Jd1(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test49() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A(Ia0),J(Ia0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(A(Ia0),Jd1(Ia0))", "J");
+ assertLinkage("C", "C2", "J1", "C2");
+ }
+
+
+ /*
+ * Cc3(A(Id0), J(Id0)) -> Cc3(Ac1(Id0), Jd2(Id0))
+ *
+ * 0: Bridge in C
+ * 1*: Inherited from A
+ * 2*: Inherited default from J
+ * 3: Declared in C
+ */
+ public void test50() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(A(Id0),J(Id0))");
+ assertLinkage("C", "C3", LINKAGE_ERROR, LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Ac1(Id0),Jd2(Id0))", "A", "J");
+ assertLinkage("C", "C3", "A1", "J2", "C3");
+ }
+
+ /*
+ * Cc3(A(Ia0), J(Ia0)) -> Cc3(Ac1(Ia0), Jd2(Ia0))
+ *
+ * 0: Bridge in C
+ * 1*: Inherited from A
+ * 2*: Inherited default from J
+ * 3: Declared in C
+ */
+ public void test51() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(A(Ia0),J(Ia0))");
+ assertLinkage("C", "C3", LINKAGE_ERROR, LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Ac1(Ia0),Jd2(Ia0))", "A", "J");
+ assertLinkage("C", "C3", "A1", "J2", "C3");
+ }
+
+ /*
+ * Cc2(J(Id0), K(Id0)) -> Cc2(Jd1(Id0), K(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test52() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(J(Id0),K(Id0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Jd1(Id0),K(Id0))", "J");
+ assertLinkage("C", "C2", "J1", "C2");
+ }
+
+ /*
+ * Cc2(J(Ia0), K(Ia0)) -> Cc2(Jd1(Ia0), K(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test53() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(J(Ia0),K(Ia0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Jd1(Ia0),K(Ia0))", "J");
+ assertLinkage("C", "C2", "J1", "C2");
+ }
+
+ /*
+ * Cc3(J(Id0), K(Id0)) -> Cc3(Jd1(Id0), Kd2(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2*: Inherited default from K
+ * 3: Declared in C
+ */
+ public void test54() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(J(Id0),K(Id0))");
+ assertLinkage("C", "C3", LINKAGE_ERROR, LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Jd1(Id0),Kd2(Id0))", "J", "K");
+ assertLinkage("C", "C3", "J1", "K2", "C3");
+ }
+
+ /*
+ * Cc3(J(Ia0), K(Ia0)) -> Cc3(Jd1(Ia0), Kd2(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2*: Inherited default from K
+ * 3: Declared in C
+ */
+ public void test55() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(J(Ia0),K(Ia0))");
+ assertLinkage("C", "C3", LINKAGE_ERROR, LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Jd1(Ia0),Kd2(Ia0))", "J", "K");
+ assertLinkage("C", "C3", "J1", "K2", "C3");
+ }
+
+ /*
+ * Cc3(Ac1(Id0), J(Id0)) -> Cc3(Ac1(Id0), Jd2(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1: Declared in C (through bridge)
+ * 2*: Inherited default from J
+ * 3: Declared in C
+ */
+ public void test56() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(Ac1(Id0),J(Id0))");
+ assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Ac1(Id0),Jd2(Id0))", "J");
+ assertLinkage("C", "C3", "C3", "J2", "C3");
+ }
+
+ /*
+ * Cc3(Ac1(Ia0), J(Ia0)) -> Cc3(Ac1(Ia0), Jd2(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1: Declared in C (through bridge)
+ * 2*: Inherited default from J
+ * 3: Declared in C
+ */
+ public void test57() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(Ac1(Ia0),J(Ia0))");
+ assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Ac1(Ia0),Jd2(Ia0))", "J");
+ assertLinkage("C", "C3", "C3", "J2", "C3");
+ }
+
+ /*
+ * Cc3(Aa1(Id0), J(Id0)) -> Cc3(Aa1(Id0), Jd2(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1: Declared in C (through bridge)
+ * 2*: Inherited default from J
+ * 3: Declared in C
+ */
+ public void test58() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(Aa1(Id0),J(Id0))");
+ assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Aa1(Id0),Jd2(Id0))", "J");
+ assertLinkage("C", "C3", "C3", "J2", "C3");
+ }
+
+ /*
+ * Cc3(Aa1(Ia0), J(Ia0)) -> Cc3(Aa1(Ia0), Jd2(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1: Declared in C (through bridge)
+ * 2*: Inherited default from J
+ * 3: Declared in C
+ */
+ public void test59() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(Aa1(Ia0),J(Ia0))");
+ assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Aa1(Ia0),Jd2(Ia0))", "J");
+ assertLinkage("C", "C3", "C3", "J2", "C3");
+ }
+
+ /*
+ * Cc3(A(Id0), Jd2(Id0)) -> Cc3(Ac1(Id0), Jd2(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C (through bridge)
+ * 3: Declared in C
+ */
+ public void test60() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(A(Id0),Jd2(Id0))");
+ assertLinkage("C", "C3", LINKAGE_ERROR, "C3", "C3");
+ recompileSpec("Cc3(Ac1(Id0),Jd2(Id0))", "A");
+ assertLinkage("C", "C3", "A1", "C3", "C3");
+ }
+
+ /*
+ * Cc3(A(Im0), Jd2(Ia0)) -> Cc3(Ac1(Im0), Jd2(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C (through bridge)
+ * 3: Declared in C
+ */
+ public void test61() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(A(Ia0),Jd2(Ia0))");
+ assertLinkage("C", "C3", LINKAGE_ERROR, "C3", "C3");
+ recompileSpec("Cc3(Ac1(Ia0),Jd2(Ia0))", "A");
+ assertLinkage("C", "C3", "A1", "C3", "C3");
+ }
+
+ /*
+ * Cc3(A(Im0), Ja2(Id0)) -> Cc3(Ac1(Id0), Ja2(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C (through bridge)
+ * 3: Declared in C
+ */
+ public void test62() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(A(Id0),Ja2(Id0))");
+ assertLinkage("C", "C3", LINKAGE_ERROR, "C3", "C3");
+ recompileSpec("Cc3(Ac1(Id0),Ja2(Id0))", "A");
+ assertLinkage("C", "C3", "A1", "C3", "C3");
+ }
+
+ /*
+ * Cc3(A(Im0), Ja2(Ia0)) -> Cc3(Ac1(Ia0), Ja2(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C (through bridge)
+ * 3: Declared in C
+ */
+ public void test63() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(A(Ia0),Ja2(Ia0))");
+ assertLinkage("C", "C3", LINKAGE_ERROR, "C3", "C3");
+ recompileSpec("Cc3(Ac1(Ia0),Ja2(Ia0))", "A");
+ assertLinkage("C", "C3", "A1", "C3", "C3");
+ }
+
+ /*
+ * Cc3(Jd1(Id0), K(Id0)) -> Cc3(Jd1(Id0), Kd2(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1: Declared in C (through bridge)
+ * 2*: Inherited default from K
+ * 3: Declared in C
+ */
+ public void test64() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(Jd1(Id0),K(Id0))");
+ assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Jd1(Id0),Kd2(Id0))", "K");
+ assertLinkage("C", "C3", "C3", "K2", "C3");
+ }
+
+ /*
+ * Cc3(Jd1(Ia0), K(Ia0)) -> Cc3(Jd1(Ia0), Kd2(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1: Declared in C (through bridge)
+ * 2*: Inherited default from K
+ * 3: Declared in C
+ */
+ public void test65() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(Jd1(Ia0),K(Ia0))");
+ assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Jd1(Ia0),Kd2(Ia0))", "K");
+ assertLinkage("C", "C3", "C3", "K2", "C3");
+ }
+
+ /*
+ * Cc3(Ja1(Id0), K(Id0)) -> Cc3(Ja1(Id0), Kd2(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1: Declared in C (through bridge)
+ * 2*: Inherited default from K
+ * 3: Declared in C
+ */
+ public void test66() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(Jd1(Id0),K(Id0))");
+ assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Jd1(Id0),Kd2(Id0))", "K");
+ assertLinkage("C", "C3", "C3", "K2", "C3");
+ }
+
+ /*
+ * Cc3(Ja1(Ia0), K(Ia0)) -> Cc3(Ja1(Ia0), Kd2(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1: Declared in C (through bridge)
+ * 2*: Inherited default from K
+ * 3: Declared in C
+ */
+ public void test67() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(Jd1(Ia0),K(Ia0))");
+ assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Jd1(Ia0),Kd2(Ia0))", "K");
+ assertLinkage("C", "C3", "C3", "K2", "C3");
+ }
+
+ // Dan's set A
+ public void testA1() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Id0)");
+ assertLinkage("C", "I0");
+ }
+
+ public void testA2() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Id0))");
+ assertLinkage("C", "I0");
+ }
+
+ public void testA3() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Id0),J)");
+ assertLinkage("C", "I0");
+ }
+
+ public void testA4() throws IOException, ReflectiveOperationException {
+ compileSpec("D(C(Id0),Jd0(Id0))");
+ assertLinkage("D", "J0");
+ assertLinkage("C", "I0");
+ }
+
+ public void testA5() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Id0),Jd0)",
+ "compiler.err.types.incompatible.unrelated.defaults");
+ }
+
+ public void testA6() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Ia0,Jd0))",
+ "compiler.err.does.not.override.abstract",
+ "compiler.err.types.incompatible.abstract.default");
+ }
+
+ public void testA7() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Id0,Jd0))",
+ "compiler.err.types.incompatible.unrelated.defaults");
+ }
+
+ public void testA8() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Ia0),J)", "compiler.err.does.not.override.abstract");
+ }
+
+ public void testA9() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Ac0(Id0))");
+ assertLinkage("C", "A0");
+ }
+
+ public void testA10() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Aa0,I)", "compiler.err.does.not.override.abstract");
+ }
+
+ public void testA11() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Ac0,Id0)");
+ assertLinkage("C", "A0");
+ }
+
+ // Dan's set B
+
+ /* B1 can't be done, needs a second concrete class D
+ public void testB1() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc1(Dc0)");
+ assertLinkage("C", "C1", "C1");
+ assertLinkage("D", "A0", LINKAGE_ERROR);
+ }
+ */
+
+ public void testB2() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc1(Ac0)");
+ assertLinkage("C", "C1", "C1");
+ }
+
+ //??? B3 seems to suggest that we should create an abstract class
+ //public void testB3() throws IOException, ReflectiveOperationException {
+ // compileSpec("Ba1(Cc0)");
+ // assertLinkage("B", "C0", "A1");
+ //}
+
+ // B4 needs too many classes
+
+ public void testB5() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc1(Aa1(Id0))");
+ assertLinkage("C", "C1", "C1");
+ }
+
+ public void testB6() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Ac1(Id0))");
+ assertLinkage("C", "A1", "A1");
+ }
+
+ public void testB7() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc1(Id0)");
+ assertLinkage("C", "C1", "C1");
+ }
+
+ public void testB8() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Jd1(Id0))");
+ assertLinkage("C", "J1", "J1");
+ }
+
+ // B9 needs too many classes
+
+ // The rest of Dan's tests need generics
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/bridge/template_tests/TEST.properties Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,7 @@
+# This file identifies root(s) of the test-ng hierarchy.
+
+
+
+TestNG.dirs = .
+
+lib.dirs = /lib/combo
--- a/langtools/test/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -197,7 +197,7 @@
"class Test {\n" +
" void m(SAM1 s) { }\n" +
" void m(SAM2 s) { }\n" +
- " { m(x->{ #LR }); }\n" +
+ " { m((#A1 x)->{ #LR }); }\n" +
"}\n";
String source;
@@ -236,14 +236,17 @@
void check() {
checkCount.incrementAndGet();
+ if (ak1 != ak2)
+ return;
+
if (!lrk.compatibleWith(rt1) || !lrk.compatibleWith(rt2))
return;
if (lrk.needsConversion(rt1) != lrk.needsConversion(rt2))
return;
- boolean m1MoreSpecific = moreSpecific(rt1, rt2, ek1, ek2, ak1, ak2);
- boolean m2MoreSpecific = moreSpecific(rt2, rt1, ek2, ek1, ak2, ak1);
+ boolean m1MoreSpecific = rt1.moreSpecificThan(rt2);
+ boolean m2MoreSpecific = rt2.moreSpecificThan(rt1);
boolean ambiguous = (m1MoreSpecific == m2MoreSpecific);
@@ -268,17 +271,6 @@
}
}
- boolean moreSpecific(RetTypeKind rk1, RetTypeKind rk2, ExceptionKind ek1,
- ExceptionKind ek2, ArgTypeKind ak1, ArgTypeKind ak2) {
- if (!rk1.moreSpecificThan(rk2))
- return false;
-
- if (ak1 != ak2)
- return false;
-
- return true;
- }
-
static class DiagnosticChecker
implements javax.tools.DiagnosticListener<JavaFileObject> {
--- a/langtools/test/tools/javac/lambda/typeInference/InferenceTest5.java Fri Sep 20 17:11:32 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @bug 8003280
- * @summary Add lambda tests
- * This test is for overloaded methods, verify that the specific method is
- selected when type inference occurs
- * @compile InferenceTest5.java
- * @run main InferenceTest5
- */
-
-import java.util.List;
-import java.io.File;
-
-public class InferenceTest5 {
-
- private static void assertTrue(boolean b) {
- if(!b)
- throw new AssertionError();
- }
-
- public static void main(String[] args) {
- InferenceTest5 test = new InferenceTest5();
- int n = test.method1((a, b) -> {} );
- assertTrue(n == 1);
-
- n = test.method1(() -> null);
- assertTrue(n == 2);
-
- n = test.method1(a -> null);
- assertTrue(n == 3);
-
- n = test.method1(a -> {});
- assertTrue(n == 4);
-
- n = test.method1(() -> {});
- assertTrue(n == 5);
-
- n = test.method1((a, b) -> 0);
- assertTrue(n == 6);
-
- n = test.method1((a, b) -> null);
- assertTrue(n == 6);
-
- n = test.method1((a, b) -> null, (a, b) -> null);
- assertTrue(n == 7);
- }
-
- int method1(SAM1<String> s) {
- return 1;
- }
-
- int method1(SAM2 s) {
- return 2;
- }
-
- int method1(SAM3 s) {
- return 3;
- }
-
- int method1(SAM4 s) {
- return 4;
- }
-
- int method1(SAM5 s) {
- return 5;
- }
-
- int method1(SAM6<?, ? super Integer> s) {
- return 6;
- }
-
- int method1(SAM6<?, ?>... s) {
- return 7;
- }
-
- static interface SAM1<T> {
- void foo(List<T> a, List<T> b);
- }
-
- static interface SAM2 {
- List<String> foo();
- }
-
- static interface SAM3 {
- String foo(int a);
- }
-
- static interface SAM4 {
- void foo(List<File> a);
- }
-
- static interface SAM5 {
- void foo();
- }
-
- static interface SAM6<T, V> {
- V get(T t, T t2);
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest6.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,26 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280 8016177
+ * @summary Add lambda tests
+ * Missing cast to SAM type that causes type inference to not work.
+ * @compile -XDrawDiagnostics InferenceTest6.java
+ */
+
+import java.util.*;
+
+public class InferenceTest6 {
+ public static void main(String[] args) {
+ InferenceTest6 test = new InferenceTest6();
+ test.method1(n -> {});
+ test.method1((SAM1<String>)n -> {});
+ test.method1((SAM1<Integer>)n -> {n++;});
+ test.method1((SAM1<Comparator<String>>)n -> {List<String> list = Arrays.asList("string1", "string2"); Collections.sort(list,n);});
+ test.method1((SAM1<Thread>)n -> {n.start();});
+ }
+
+ interface SAM1<X> {
+ void m1(X arg);
+ }
+
+ <X> void method1(SAM1<X> s) {}
+}
--- a/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg1_2.out Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg1_2.out Fri Sep 20 19:15:59 2013 -0700
@@ -1,4 +1,5 @@
InferenceTest_neg1_2.java:14:13: compiler.err.ref.ambiguous: method, kindname.method, method(InferenceTest_neg1_2.SAM4<java.lang.Double,java.lang.String>), InferenceTest_neg1_2, kindname.method, method(InferenceTest_neg1_2.SAM5<java.lang.Integer>), InferenceTest_neg1_2
-InferenceTest_neg1_2.java:15:13: compiler.err.ref.ambiguous: method, kindname.method, method(InferenceTest_neg1_2.SAM2), InferenceTest_neg1_2, kindname.method, method(InferenceTest_neg1_2.SAM4<java.lang.Double,java.lang.String>), InferenceTest_neg1_2
-InferenceTest_neg1_2.java:16:13: compiler.err.ref.ambiguous: method, kindname.method, method(InferenceTest_neg1_2.SAM3<java.lang.Integer>), InferenceTest_neg1_2, kindname.method, method(InferenceTest_neg1_2.SAM5<java.lang.Integer>), InferenceTest_neg1_2
-3 errors
+InferenceTest_neg1_2.java:15:13: compiler.err.ref.ambiguous: method, kindname.method, method(InferenceTest_neg1_2.SAM4<java.lang.Double,java.lang.String>), InferenceTest_neg1_2, kindname.method, method(InferenceTest_neg1_2.SAM5<java.lang.Integer>), InferenceTest_neg1_2
+InferenceTest_neg1_2.java:16:13: compiler.err.ref.ambiguous: method, kindname.method, method(InferenceTest_neg1_2.SAM4<java.lang.Double,java.lang.String>), InferenceTest_neg1_2, kindname.method, method(InferenceTest_neg1_2.SAM5<java.lang.Integer>), InferenceTest_neg1_2
+InferenceTest_neg1_2.java:16:20: compiler.err.cant.apply.symbol: kindname.method, method, InferenceTest_neg1_2.SAM4<java.lang.Double,java.lang.String>, @597, kindname.class, InferenceTest_neg1_2, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: int, java.lang.String)))
+4 errors
--- a/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg5.java Fri Sep 20 17:11:32 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * @test /nodynamiccopyright/
- * @bug 8003280
- * @summary Add lambda tests
- * Missing cast to SAM type that causes type inference to not work.
- * @compile/fail/ref=InferenceTest_neg5.out -XDrawDiagnostics InferenceTest_neg5.java
- */
-
-import java.util.*;
-
-public class InferenceTest_neg5 {
- public static void main(String[] args) {
- InferenceTest_neg5 test = new InferenceTest_neg5();
- test.method1(n -> {});
- test.method1((SAM1<String>)n -> {});
- test.method1((SAM1<Integer>)n -> {n++;});
- test.method1((SAM1<Comparator<String>>)n -> {List<String> list = Arrays.asList("string1", "string2"); Collections.sort(list,n);});
- test.method1((SAM1<Thread>)n -> {n.start();});
- }
-
- interface SAM1<X> {
- void m1(X arg);
- }
-
- <X> void method1(SAM1<X> s) {}
-}
--- a/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg5.out Fri Sep 20 17:11:32 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-InferenceTest_neg5.java:14:21: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: X)
-1 error
--- a/langtools/test/tools/javac/lambda/typeInference/combo/TypeInferenceComboTest.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lambda/typeInference/combo/TypeInferenceComboTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -227,12 +227,7 @@
}
else if (lambdaBodyType != LambdaBody.RETURN_ARG)
return false;
- if ( genericDeclKind == GenericDeclKind.GENERIC_NOBOUND ||
- genericDeclKind == GenericDeclKind.GENERIC_BOUND ) {
- if ( parameterType == TypeKind.GENERIC &&
- parameterKind == ParameterKind.IMPLICIT) //cyclic inference
- return false;
- }
+
return true;
}
--- a/langtools/test/tools/javac/lib/DPrinter.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/lib/DPrinter.java Fri Sep 20 19:15:59 2013 -0700
@@ -49,7 +49,7 @@
import com.sun.source.util.TaskListener;
import com.sun.source.util.Trees;
import com.sun.tools.javac.api.JavacTrees;
-import com.sun.tools.javac.code.Annotations;
+import com.sun.tools.javac.code.SymbolMetadata;
import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Kinds;
@@ -186,21 +186,21 @@
FULL
};
- public void printAnnotations(String label, Annotations annotations) {
+ public void printAnnotations(String label, SymbolMetadata annotations) {
printAnnotations(label, annotations, Details.FULL);
}
- protected void printAnnotations(String label, Annotations annotations, Details details) {
+ protected void printAnnotations(String label, SymbolMetadata annotations, Details details) {
if (annotations == null) {
printNull(label);
} else {
// no SUMMARY format currently available to use
// use reflection to get at private fields
- Object DECL_NOT_STARTED = getField(null, Annotations.class, "DECL_NOT_STARTED");
- Object DECL_IN_PROGRESS = getField(null, Annotations.class, "DECL_IN_PROGRESS");
- Object attributes = getField(annotations, Annotations.class, "attributes");
- Object type_attributes = getField(annotations, Annotations.class, "type_attributes");
+ Object DECL_NOT_STARTED = getField(null, SymbolMetadata.class, "DECL_NOT_STARTED");
+ Object DECL_IN_PROGRESS = getField(null, SymbolMetadata.class, "DECL_IN_PROGRESS");
+ Object attributes = getField(annotations, SymbolMetadata.class, "attributes");
+ Object type_attributes = getField(annotations, SymbolMetadata.class, "type_attributes");
if (!showEmptyItems) {
if (attributes instanceof List && ((List) attributes).isEmpty()
--- a/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java Fri Sep 20 19:15:59 2013 -0700
@@ -31,6 +31,7 @@
* @compile/fail/ref=TestMissingElement.ref -proc:only -XprintRounds -XDrawDiagnostics -processor TestMissingElement InvalidSource.java
*/
+import java.io.PrintWriter;
import java.util.*;
import javax.annotation.processing.*;
import javax.lang.model.element.*;
@@ -38,7 +39,18 @@
import javax.lang.model.util.*;
import static javax.tools.Diagnostic.Kind.*;
+import com.sun.tools.javac.processing.JavacProcessingEnvironment;
+import com.sun.tools.javac.util.Log;
+
public class TestMissingElement extends JavacTestingAbstractProcessor {
+ private PrintWriter out;
+
+ @Override
+ public void init(ProcessingEnvironment env) {
+ super.init(env);
+ out = ((JavacProcessingEnvironment) env).getContext().get(Log.outKey);
+ }
+
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (TypeElement te: ElementFilter.typesIn(roundEnv.getRootElements())) {
@@ -70,13 +82,13 @@
}
private void checkInterfaces(TypeElement te, String expect) {
- System.err.println("check interfaces: " + te + " -- " + expect);
+ out.println("check interfaces: " + te + " -- " + expect);
String found = asString(te.getInterfaces(), ", ");
checkEqual("interfaces", te, found, expect);
}
private void checkSupertype(TypeElement te, String expect) {
- System.err.println("check supertype: " + te + " -- " + expect);
+ out.println("check supertype: " + te + " -- " + expect);
String found = asString(te.getSuperclass());
checkEqual("supertype", te, found, expect);
}
@@ -85,7 +97,7 @@
if (found.equals(expect)) {
// messager.printMessage(NOTE, "expected " + label + " found: " + expect, te);
} else {
- System.err.println("unexpected " + label + ": " + te + "\n"
+ out.println("unexpected " + label + ": " + te + "\n"
+ " found: " + found + "\n"
+ "expect: " + expect);
messager.printMessage(ERROR, "unexpected " + label + " found: " + found + "; expected: " + expect, te);
--- a/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.ref Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.ref Fri Sep 20 19:15:59 2013 -0700
@@ -2,6 +2,24 @@
input files: {ExpectInterfaces, ExpectSupertype, OK, InvalidSource}
annotations: [ExpectSupertype, ExpectInterfaces]
last round: false
+check supertype: InvalidSource.TestClassMissingClassA -- !:empty clss A!
+check supertype: InvalidSource.TestClassMissingClassAB -- !:empty clss (pkg A).B!
+check supertype: InvalidSource.TestClassMissingClass_juA -- !:empty clss (pkg java.util).A!
+check supertype: InvalidSource.TestClassTMissingClassAT -- !:empty clss A!<tvar T>
+check interfaces: InvalidSource.TestClassMissingIntfA -- !:empty intf A!
+check interfaces: InvalidSource.TestClassMissingIntfAB -- !:empty intf (pkg A).B!
+check interfaces: InvalidSource.TestClassMissingIntfAOK -- !:empty intf A!, intf OK
+check interfaces: InvalidSource.TestClassOKMissingIntfA -- intf OK, !:empty intf A!
+check interfaces: InvalidSource.TestClassMissingIntfA_B -- !:empty intf A!, !:empty intf B!
+check interfaces: InvalidSource.TestIntfMissingIntfA -- !:empty intf A!
+check interfaces: InvalidSource.TestIntfMissingIntfAOK -- !:empty intf A!, intf OK
+check interfaces: InvalidSource.TestIntfOKMissingIntfA -- intf OK, !:empty intf A!
+check interfaces: InvalidSource.TestIntfMissingIntfAB -- !:empty intf A!, !:empty intf B!
+check interfaces: InvalidSource.TestClassTMissingIntfAT -- !:empty intf A!<tvar T>
+check interfaces: InvalidSource.TestClassTMissingIntfAT_B -- !:empty intf A!<tvar T>, !:empty intf B!
+check interfaces: InvalidSource.TestIntfTMissingIntfAT -- !:empty intf A!<tvar T>
+check interfaces: InvalidSource.TestIntfTMissingIntfAT_B -- !:empty intf A!<tvar T>, !:empty intf B!
+check interfaces: InvalidSource.TestClassListMissingX -- intf (pkg java.util).List<!:empty clss X!>
Round 2:
input files: {}
annotations: []
@@ -28,22 +46,4 @@
InvalidSource.java:103:51: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null)
InvalidSource.java:103:57: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.class, InvalidSource, null)
InvalidSource.java:106:58: compiler.err.cant.resolve.location: kindname.class, X, , , (compiler.misc.location: kindname.class, InvalidSource, null)
-22 errors
-check supertype: InvalidSource.TestClassMissingClassA -- !:empty clss A!
-check supertype: InvalidSource.TestClassMissingClassAB -- !:empty clss (pkg A).B!
-check supertype: InvalidSource.TestClassMissingClass_juA -- !:empty clss (pkg java.util).A!
-check supertype: InvalidSource.TestClassTMissingClassAT -- !:empty clss A!<tvar T>
-check interfaces: InvalidSource.TestClassMissingIntfA -- !:empty intf A!
-check interfaces: InvalidSource.TestClassMissingIntfAB -- !:empty intf (pkg A).B!
-check interfaces: InvalidSource.TestClassMissingIntfAOK -- !:empty intf A!, intf OK
-check interfaces: InvalidSource.TestClassOKMissingIntfA -- intf OK, !:empty intf A!
-check interfaces: InvalidSource.TestClassMissingIntfA_B -- !:empty intf A!, !:empty intf B!
-check interfaces: InvalidSource.TestIntfMissingIntfA -- !:empty intf A!
-check interfaces: InvalidSource.TestIntfMissingIntfAOK -- !:empty intf A!, intf OK
-check interfaces: InvalidSource.TestIntfOKMissingIntfA -- intf OK, !:empty intf A!
-check interfaces: InvalidSource.TestIntfMissingIntfAB -- !:empty intf A!, !:empty intf B!
-check interfaces: InvalidSource.TestClassTMissingIntfAT -- !:empty intf A!<tvar T>
-check interfaces: InvalidSource.TestClassTMissingIntfAT_B -- !:empty intf A!<tvar T>, !:empty intf B!
-check interfaces: InvalidSource.TestIntfTMissingIntfAT -- !:empty intf A!<tvar T>
-check interfaces: InvalidSource.TestIntfTMissingIntfAT_B -- !:empty intf A!<tvar T>, !:empty intf B!
-check interfaces: InvalidSource.TestClassListMissingX -- intf (pkg java.util).List<!:empty clss X!>
\ No newline at end of file
+22 errors
\ No newline at end of file
--- a/langtools/test/tools/javac/warnings/6594914/T6594914a.out Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/warnings/6594914/T6594914a.out Fri Sep 20 19:15:59 2013 -0700
@@ -1,7 +1,7 @@
T6594914a.java:11:5: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
T6594914a.java:16:16: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
-T6594914a.java:16:52: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
T6594914a.java:16:33: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
T6594914a.java:17:20: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6594914a.java:16:52: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
T6594914a.java:24:9: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
6 warnings
--- a/langtools/test/tools/javac/warnings/6594914/T6594914b.out Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javac/warnings/6594914/T6594914b.out Fri Sep 20 19:15:59 2013 -0700
@@ -1,7 +1,7 @@
T6594914b.java:11:13: compiler.warn.sun.proprietary: sun.misc.Lock
T6594914b.java:16:24: compiler.warn.sun.proprietary: sun.misc.Lock
-T6594914b.java:16:56: compiler.warn.sun.proprietary: sun.misc.Lock
T6594914b.java:16:39: compiler.warn.sun.proprietary: sun.misc.Lock
T6594914b.java:17:28: compiler.warn.sun.proprietary: sun.misc.CEFormatException
+T6594914b.java:16:56: compiler.warn.sun.proprietary: sun.misc.Lock
T6594914b.java:24:17: compiler.warn.sun.proprietary: sun.misc.Lock
6 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/ImplicitTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,31 @@
+/*
+ * 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 8021112
+ * @summary Verify that deprecated warning is printed correctly for import
+ * statement when processing a file on demand while attributing another file.
+ * @clean pack.ImplicitUse pack.ImplicitMain pack.Dep
+ * @compile/ref=ImplicitTest.out -XDrawDiagnostics -Xlint:deprecation pack/ImplicitMain.java
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/ImplicitTest.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,2 @@
+ImplicitUse.java:4:12: compiler.warn.has.been.deprecated: pack.Dep, pack
+1 warning
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/PackageInfo.java Fri Sep 20 19:15:59 2013 -0700
@@ -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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 8021112
+ * @summary Verify that deprecated warnings are printed correctly for package-info.java
+ * @clean pack.package-info pack.DeprecatedClass
+ * @compile/ref=PackageInfo.out -XDrawDiagnostics -Xlint:deprecation pack/package-info.java pack/DeprecatedClass.java
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/PackageInfo.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,3 @@
+package-info.java:5:12: compiler.warn.has.been.deprecated: pack.DeprecatedClass, pack
+package-info.java:2:2: compiler.warn.has.been.deprecated: pack.DeprecatedClass, pack
+2 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/T6480588.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,36 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 6470588
+ * @summary Verify that \\@SuppressWarnings("deprecation") works OK for all parts
+ * of class/method/field "header", including (declaration) annotations
+ * @build VerifySuppressWarnings
+ * @compile/ref=T6480588.out -XDrawDiagnostics -Xlint:unchecked,deprecation,cast T6480588.java
+ * @run main VerifySuppressWarnings T6480588.java
+ */
+
+@DeprecatedAnnotation
+class T6480588 extends DeprecatedClass implements DeprecatedInterface {
+ @DeprecatedAnnotation
+ public DeprecatedClass method(DeprecatedClass param) throws DeprecatedClass {
+ DeprecatedClass lv = new DeprecatedClass();
+ @Deprecated
+ DeprecatedClass lvd = new DeprecatedClass();
+ return null;
+ }
+
+ @Deprecated
+ public void methodD() {
+ }
+
+ @DeprecatedAnnotation
+ DeprecatedClass field = new DeprecatedClass();
+
+ @DeprecatedAnnotation
+ class Inner extends DeprecatedClass implements DeprecatedInterface {
+ }
+
+}
+
+@Deprecated class DeprecatedClass extends Throwable { }
+@Deprecated interface DeprecatedInterface { }
+@Deprecated @interface DeprecatedAnnotation { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/T6480588.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,18 @@
+T6480588.java:12:24: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:12:51: compiler.warn.has.been.deprecated: DeprecatedInterface, compiler.misc.unnamed.package
+T6480588.java:11:2: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
+T6480588.java:14:12: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:14:65: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:13:6: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
+T6480588.java:14:35: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:15:9: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:15:34: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:17:9: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:17:35: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:26:5: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:25:6: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
+T6480588.java:26:33: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:29:25: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:29:52: compiler.warn.has.been.deprecated: DeprecatedInterface, compiler.misc.unnamed.package
+T6480588.java:28:6: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
+17 warnings
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/T8021112a.java Fri Sep 20 19:15:59 2013 -0700
@@ -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.
+ */
+package test;
+
+/**
+ * @test
+ * @bug 8021112
+ * @summary Verify that \\@SuppressWarnings work even if the value is defined
+ * inside the suppressed class itself, and verify that "unnecessary cast"
+ * lint can be properly suppressed.
+ * @compile -Xlint:cast -Werror T8021112a.java
+ */
+
+import static test.T8021112a.D;
+
+@SuppressWarnings(D)
+public class T8021112a {
+ public static final String D = (String) "cast";
+}
+
+class Other {
+ public static final String D = "cast";
+ @SuppressWarnings(D)
+ public static final String D2 = (String) "cast";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/T8021112b.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,22 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 8021112
+ * @summary Verify that \\@SuppressWarnings("unchecked") works correctly for lazy attrib values
+ * @build VerifySuppressWarnings
+ * @compile/ref=T8021112b.out -XDrawDiagnostics -Xlint:unchecked,deprecation,cast T8021112b.java
+ * @run main VerifySuppressWarnings T8021112b.java
+ */
+
+public class T8021112b {
+ public static final String D1 = Dep.D;
+ public static final String D2 = "";
+ public static final Object[] o = {
+ new Object() {
+ Dep d;
+ }
+ };
+}
+
+@Deprecated class Dep {
+ public static final String D = T8021112b.D2;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/T8021112b.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,3 @@
+T8021112b.java:11:37: compiler.warn.has.been.deprecated: Dep, compiler.misc.unnamed.package
+T8021112b.java:15:13: compiler.warn.has.been.deprecated: Dep, compiler.misc.unnamed.package
+2 warnings
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/TypeAnnotations.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,51 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 8021112
+ * @summary Verify that \\@SuppressWarnings("unchecked") works for type annotations
+ * @build VerifySuppressWarnings
+ * @compile/ref=TypeAnnotations.out -XDrawDiagnostics -Xlint:unchecked,deprecation,cast TypeAnnotations.java
+ * @run main VerifySuppressWarnings TypeAnnotations.java
+ */
+
+import java.lang.annotation.*;
+
+public class TypeAnnotations extends @TA Object implements @TA Runnable {
+
+ public @TA String @TA [] m(@TA String @TA [] p) throws @TA Throwable {
+ Runnable r = () -> {
+ @TA Object tested = null;
+ @TA boolean isAnnotated = tested instanceof @TA String;
+ };
+
+ @TA Object tested = null;
+ @TA boolean isAnnotated = tested instanceof @TA String;
+
+ return (@TA String @TA []) null;
+ }
+
+ {
+ Runnable r = () -> {
+ @TA Object tested = null;
+ @TA boolean isAnnotated = tested instanceof @TA String;
+ };
+
+ @TA Object tested = null;
+ @TA boolean isAnnotated = tested instanceof @TA String;
+
+ @TA String @TA [] ret = (@TA String @TA []) null;
+ }
+
+ @TA String @TA [] f = new @TA String @TA[0];
+
+ @Override public void run() { }
+
+ public static class Inner extends @TA Object implements @TA Runnable {
+ @Override public void run() { }
+ }
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE})
+@Deprecated
+@interface TA {
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/TypeAnnotations.out Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,41 @@
+TypeAnnotations.java:12:39: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:12:61: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:14:24: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:14:61: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:14:13: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:14:44: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:14:33: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:23:29: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:23:18: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:16:14: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:17:58: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:17:14: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:17:58: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:20:10: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:21:54: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:21:10: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:21:54: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:23:18: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:23:29: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:28:14: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:29:58: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:29:14: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:29:58: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:32:10: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:33:54: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:33:10: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:33:54: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:35:46: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:35:35: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:35:21: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:35:10: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:35:35: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:35:46: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:38:17: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:38:6: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:38:43: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:38:32: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:38:32: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:42:40: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:42:62: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+40 warnings
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/VerifySuppressWarnings.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,212 @@
+/*
+ * 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.sun.source.tree.ClassTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.NewClassTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.TreeScanner;
+import com.sun.source.util.Trees;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticListener;
+import javax.tools.FileObject;
+import javax.tools.ForwardingJavaFileManager;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+
+/**Takes a source file, parses it once to get the warnings inside the file and
+ * then for each and every declaration in the file, it tries to place
+ * the @SuppressWarnings annotation on the declaration and verifies than no
+ * warnings are produced inside the declaration, but all are produced outside it.
+ *
+ * Currently only works with <code>unchecked,deprecation,cast</code> warnings.
+ */
+public class VerifySuppressWarnings {
+
+ private static final List<String> STANDARD_PARAMS = Arrays.asList("-Xlint:unchecked,deprecation,cast", "-Xjcov");
+
+ public static void main(String... args) throws IOException, URISyntaxException {
+ if (args.length != 1) throw new IllegalStateException("Must provide class name!");
+ String testContent = null;
+ List<File> sourcePath = new ArrayList<>();
+ for (String sourcePaths : System.getProperty("test.src.path").split(":")) {
+ sourcePath.add(new File(sourcePaths));
+ }
+ JavacFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
+ for (File sp : sourcePath) {
+ File inp = new File(sp, args[0]);
+
+ if (inp.canRead()) {
+ testContent = fm.getRegularFile(inp).getCharContent(true).toString();
+ }
+ }
+ if (testContent == null) throw new IllegalStateException();
+ final List<Diagnostic<?>> diagnostics = new ArrayList<>();
+ DiagnosticListener<JavaFileObject> collectDiagnostics = new DiagnosticListener<JavaFileObject>() {
+ @Override public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ diagnostics.add(diagnostic);
+ }
+ };
+ JavaFileObject testFile = new TestFO(new URI("mem://" + args[0]), testContent);
+ JavacTask task = JavacTool.create().getTask(null,
+ new TestFM(fm),
+ collectDiagnostics,
+ STANDARD_PARAMS,
+ null,
+ Arrays.asList(testFile));
+ final Trees trees = Trees.instance(task);
+ final CompilationUnitTree cut = task.parse().iterator().next();
+ task.analyze();
+
+ final List<int[]> declarationSpans = new ArrayList<>();
+
+ new TreeScanner<Void, Void>() {
+ @Override public Void visitClass(ClassTree node, Void p) {
+ handleDeclaration(node);
+ return super.visitClass(node, p);
+ }
+ @Override public Void visitMethod(MethodTree node, Void p) {
+ handleDeclaration(node);
+ return super.visitMethod(node, p);
+ }
+ @Override public Void visitVariable(VariableTree node, Void p) {
+ handleDeclaration(node);
+ return super.visitVariable(node, p);
+ }
+
+ @Override
+ public Void visitNewClass(NewClassTree node, Void p) {
+ if (node.getClassBody() != null) {
+ scan(node.getClassBody().getMembers(), null);
+ }
+ return null;
+ }
+
+ private void handleDeclaration(Tree node) {
+ int endPos = (int) trees.getSourcePositions().getEndPosition(cut, node);
+
+ if (endPos == (-1)) {
+ if (node.getKind() == Tree.Kind.METHOD && (((JCMethodDecl) node).getModifiers().flags & Flags.GENERATEDCONSTR) != 0) {
+ return ;
+ }
+ throw new IllegalStateException();
+ }
+
+ declarationSpans.add(new int[] {(int) trees.getSourcePositions().getStartPosition(cut, node), endPos});
+ }
+ }.scan(cut, null);
+
+ for (final int[] declarationSpan : declarationSpans) {
+ final String suppressWarnings = "@SuppressWarnings({\"deprecation\", \"unchecked\", \"serial\"})";
+ final String updatedContent = testContent.substring(0, declarationSpan[0]) + suppressWarnings + testContent.substring(declarationSpan[0]);
+ final List<Diagnostic<?>> foundErrors = new ArrayList<>(diagnostics);
+ DiagnosticListener<JavaFileObject> verifyDiagnostics = new DiagnosticListener<JavaFileObject>() {
+ @Override public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ long adjustedPos = diagnostic.getPosition();
+
+ if (adjustedPos >= declarationSpan[0]) adjustedPos -= suppressWarnings.length();
+
+ if (declarationSpan[0] <= adjustedPos && adjustedPos <= declarationSpan[1]) {
+ throw new IllegalStateException("unsuppressed: " + diagnostic.getMessage(null));
+ }
+
+ boolean found = false;
+
+ for (Iterator<Diagnostic<?>> it = foundErrors.iterator(); it.hasNext();) {
+ Diagnostic<?> d = it.next();
+ if (d.getPosition() == adjustedPos && d.getCode().equals(diagnostic.getCode())) {
+ it.remove();
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ throw new IllegalStateException("diagnostic not originally reported: " + diagnostic.getMessage(null));
+ }
+ }
+ };
+
+ JavaFileObject updatedFile = new TestFO(new URI("mem://" + args[0]), updatedContent);
+ JavacTask testTask = JavacTool.create().getTask(null,
+ new TestFM(fm),
+ verifyDiagnostics,
+ STANDARD_PARAMS,
+ null,
+ Arrays.asList(updatedFile));
+
+ testTask.analyze();
+
+ for (Diagnostic<?> d : foundErrors) {
+ if (d.getPosition() < declarationSpan[0] || declarationSpan[1] < d.getPosition()) {
+ throw new IllegalStateException("missing: " + d.getMessage(null));
+ }
+ }
+ }
+ }
+
+ private static final class TestFO extends SimpleJavaFileObject {
+ private final String content;
+ public TestFO(URI uri, String content) {
+ super(uri, Kind.SOURCE);
+ this.content = content;
+ }
+
+ @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+ return content;
+ }
+
+ @Override public boolean isNameCompatible(String simpleName, Kind kind) {
+ return true;
+ }
+ }
+
+ private static final class TestFM extends ForwardingJavaFileManager<JavaFileManager> {
+
+ public TestFM(JavaFileManager fileManager) {
+ super(fileManager);
+ }
+
+ @Override
+ public boolean isSameFile(FileObject a, FileObject b) {
+ return a.equals(b);
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/pack/DeprecatedClass.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,5 @@
+/* /nodynamiccopyright/ */
+package pack;
+@Deprecated
+@interface DeprecatedClass {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/pack/ImplicitMain.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,14 @@
+/* /nodynamiccopyright/ */
+package pack;
+
+@SuppressWarnings("deprecation")
+public class ImplicitMain {
+ private Object test() {
+ return new ImplicitUse();
+ }
+}
+
+@Deprecated
+class Dep {
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/pack/ImplicitUse.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,7 @@
+/* /nodynamiccopyright/ */
+package pack;
+
+import pack.Dep;
+
+public class ImplicitUse {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/pack/package-info.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,5 @@
+/* /nodynamiccopyright/ */
+@DeprecatedClass
+package pack;
+
+import pack.DeprecatedClass;
--- a/langtools/test/tools/javadoc/api/basic/APITest.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javadoc/api/basic/APITest.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -29,6 +29,7 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI;
+import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
@@ -164,11 +165,13 @@
}
private void listFiles(Path dir, Set<Path> files) throws IOException {
- for (Path f: Files.newDirectoryStream(dir)) {
- if (Files.isDirectory(f))
- listFiles(f, files);
- else if (Files.isRegularFile(f))
- files.add(f);
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(dir)) {
+ for (Path f: ds) {
+ if (Files.isDirectory(f))
+ listFiles(f, files);
+ else if (Files.isRegularFile(f))
+ files.add(f);
+ }
}
}
--- a/langtools/test/tools/javadoc/api/basic/GetTask_FileManagerTest.java Fri Sep 20 17:11:32 2013 -0700
+++ b/langtools/test/tools/javadoc/api/basic/GetTask_FileManagerTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6493690
+ * @bug 6493690 8024434
* @summary javadoc should have a javax.tools.Tool service provider
* @build APITest
* @run main GetTask_FileManagerTest
--- a/make/scripts/webrev.ksh Fri Sep 20 17:11:32 2013 -0700
+++ b/make/scripts/webrev.ksh Fri Sep 20 19:15:59 2013 -0700
@@ -27,7 +27,7 @@
# Documentation is available via 'webrev -h'.
#
-WEBREV_UPDATED=24.0-hg+jbs
+WEBREV_UPDATED=24.1-hg+openjdk.java.net
HTML='<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
@@ -230,7 +230,7 @@
# $ sdiff_to_html old/usr/src/tools/scripts/webrev.sh \
# new/usr/src/tools/scripts/webrev.sh \
# webrev.sh usr/src/tools/scripts \
-# '<a href="https://jbs.oracle.com/bugs/browse/JDK-1234567">
+# '<a href="https://bugs.openjdk.java.net/browse/JDK-1234567">
# JDK-1234567</a> my bugid' > <file>.html
#
# framed_sdiff() is then called which creates $2.frames.html
@@ -1476,7 +1476,7 @@
# The first and last are simple addition while the middle one
# is a move/rename or a copy. We can't distinguish from a rename vs a copy
# without also getting the status of removed files. The middle case above
- # is a rename if File4 is also shown a being removed. If File4 is not a
+ # is a rename if File4 is also shown a being removed. If File4 is not a
# removed file, then the middle case is a copy from File4 to subdir/File4
# FIXME - we're not distinguishing copy from rename
$HGCMD -aC | $FILTER | while read LINE; do
@@ -1644,7 +1644,7 @@
# The first and last are simple addition while the middle one
# is a move/rename or a copy. We can't distinguish from a rename vs a copy
# without also getting the status of removed files. The middle case above
- # is a rename if File4 is also shown a being removed. If File4 is not a
+ # is a rename if File4 is also shown a being removed. If File4 is not a
# removed file, then the middle case is a copy from File4 to subdir/File4
# FIXME - we're not distinguishing copy from rename
@@ -2529,7 +2529,7 @@
# Bug IDs will be replaced by a URL. Order of precedence
# is: default location, $WEBREV_BUGURL, the -O flag.
#
-BUGURL='https://jbs.oracle.com/bugs/browse/'
+BUGURL='https://bugs.openjdk.java.net/browse/'
[[ -n $WEBREV_BUGURL ]] && BUGURL="$WEBREV_BUGURL"
if [[ -n "$Oflag" ]]; then
CRID=`echo $CRID | sed -e 's/JDK-//'`
@@ -3056,7 +3056,7 @@
for id in $CRID
do
if [[ -z "$Oflag" ]]; then
- #add "JDK-" to raw bug id for jbs links.
+ #add "JDK-" to raw bug id for openjdk.java.net links.
id=`echo ${id} | sed 's/^\([0-9]\{5,\}\)$/JDK-\1/'`
fi
print "<tr><th>Bug id:</th><td>"
--- a/nashorn/.hgtags Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/.hgtags Fri Sep 20 19:15:59 2013 -0700
@@ -215,3 +215,5 @@
414203de4374e1964a9918c38a95fb245010a9f1 jdk8-b103
afc100513451d22f0b8135999d6eb52f36df3d36 jdk8-b104
f484bfb624dd06683cb33b524700a5dd4927a82b jdk8-b105
+bf70cbd2c8369fd97ffdfcbe1a80dbc2797408ee jdk8-b106
+f35e1255024b66f7cf82517798f45f6e194e5567 jdk8-b107
--- a/nashorn/make/build.xml Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/make/build.xml Fri Sep 20 19:15:59 2013 -0700
@@ -230,6 +230,10 @@
<compilerarg value="-Xlint:deprecation"/>
</javac>
+ <copy todir="${build.test.classes.dir}/META-INF/services">
+ <fileset dir="${test.src.dir}/META-INF/services/"/>
+ </copy>
+
<!-- tests that check nashorn internals and internal API -->
<jar jarfile="${nashorn.internal.tests.jar}">
<fileset dir="${build.test.classes.dir}" excludes="**/api/**"/>
@@ -238,6 +242,7 @@
<!-- tests that check nashorn script engine (jsr-223) API -->
<jar jarfile="${nashorn.api.tests.jar}">
<fileset dir="${build.test.classes.dir}" includes="**/api/**"/>
+ <fileset dir="${build.test.classes.dir}" includes="**/META-INF/**"/>
</jar>
</target>
@@ -264,6 +269,13 @@
permission java.util.PropertyPermission "nashorn.test.*", "read";
};
+grant codeBase "file:/${basedir}/test/script/basic/parser/*" {
+ permission java.io.FilePermission "${basedir}/test/script/-", "read";
+ permission java.io.FilePermission "$${user.dir}", "read";
+ permission java.util.PropertyPermission "user.dir", "read";
+ permission java.util.PropertyPermission "nashorn.test.*", "read";
+};
+
grant codeBase "file:/${basedir}/test/script/basic/JDK-8010946-privileged.js" {
permission java.util.PropertyPermission "java.security.policy", "read";
};
--- a/nashorn/src/jdk/nashorn/api/scripting/JSObject.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/api/scripting/JSObject.java Fri Sep 20 19:15:59 2013 -0700
@@ -25,73 +25,210 @@
package jdk.nashorn.api.scripting;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
/**
- * netscape.javascript.JSObject-like interface for nashorn script objects.
+ * This is the base class for nashorn ScriptObjectMirror class.
+ *
+ * This class can also be subclassed by an arbitrary Java class. Nashorn will
+ * treat objects of such classes just like nashorn script objects. Usual nashorn
+ * operations like obj[i], obj.foo, obj.func(), delete obj.foo will be glued
+ * to appropriate method call of this class.
*/
public abstract class JSObject {
/**
- * Call a JavaScript function
+ * Call this object as a JavaScript function. This is equivalent to
+ * 'func.apply(thiz, args)' in JavaScript.
*
- * @param functionName name of function
+ * @param thiz 'this' object to be passed to the function
* @param args arguments to method
* @return result of call
*/
- public abstract Object call(String functionName, Object... args);
+ public Object call(Object thiz, Object... args) {
+ throw new UnsupportedOperationException("call");
+ }
/**
- * Call a JavaScript method as a constructor. This is equivalent to
- * calling new obj.Method(arg1, arg2...) in JavaScript.
+ * Call this 'constructor' JavaScript function to create a new object.
+ * This is equivalent to 'new func(arg1, arg2...)' in JavaScript.
*
- * @param functionName name of function
* @param args arguments to method
* @return result of constructor call
*/
- public abstract Object newObject(String functionName, Object... args);
+ public Object newObject(Object... args) {
+ throw new UnsupportedOperationException("newObject");
+ }
/**
- * Evaluate a JavaScript expression
+ * Evaluate a JavaScript expression.
*
* @param s JavaScript expression to evaluate
* @return evaluation result
*/
- public abstract Object eval(String s);
+ public Object eval(String s) {
+ throw new UnsupportedOperationException("eval");
+ }
/**
- * Retrieves a named member of a JavaScript object.
+ * Call a JavaScript function member of this object.
+ *
+ * @param name name of the member function to call
+ * @param args arguments to be passed to the member function
+ * @return result of call
+ */
+ public Object callMember(String name, Object... args) {
+ throw new UnsupportedOperationException("call");
+ }
+
+ /**
+ * Retrieves a named member of this JavaScript object.
*
* @param name of member
* @return member
*/
- public abstract Object getMember(String name);
+ public Object getMember(String name) {
+ return null;
+ }
/**
- * Retrieves an indexed member of a JavaScript object.
+ * Retrieves an indexed member of this JavaScript object.
*
- * @param index index of member slot
+ * @param index index slot to retrieve
* @return member
*/
- public abstract Object getSlot(int index);
+ public Object getSlot(int index) {
+ return null;
+ }
/**
- * Remove a named member from a JavaScript object
+ * Does this object have a named member?
*
* @param name name of member
+ * @return true if this object has a member of the given name
*/
- public abstract void removeMember(String name);
+ public boolean hasMember(String name) {
+ return false;
+ }
+
+ /**
+ * Does this object have a indexed property?
+ *
+ * @param slot index to check
+ * @return true if this object has a slot
+ */
+ public boolean hasSlot(int slot) {
+ return false;
+ }
+
+ /**
+ * Remove a named member from this JavaScript object
+ *
+ * @param name name of the member
+ */
+ public void removeMember(String name) {
+ }
+
+ /**
+ * Set a named member in this JavaScript object
+ *
+ * @param name name of the member
+ * @param value value of the member
+ */
+ public void setMember(String name, Object value) {
+ }
+
+ /**
+ * Set an indexed member in this JavaScript object
+ *
+ * @param index index of the member slot
+ * @param value value of the member
+ */
+ public void setSlot(int index, Object value) {
+ }
+
+ // property and value iteration
+
+ /**
+ * Returns the set of all property names of this object.
+ *
+ * @return set of property names
+ */
+ @SuppressWarnings("unchecked")
+ public Set<String> keySet() {
+ return Collections.EMPTY_SET;
+ }
/**
- * Set a named member in a JavaScript object
+ * Returns the set of all property values of this object.
+ *
+ * @return set of property values.
+ */
+ @SuppressWarnings("unchecked")
+ public Collection<Object> values() {
+ return Collections.EMPTY_SET;
+ }
+
+ // JavaScript instanceof check
+
+ /**
+ * Checking whether the given object is an instance of 'this' object.
*
- * @param name name of member
- * @param value value of member
+ * @param instance instace to check
+ * @return true if the given 'instance' is an instance of this 'function' object
*/
- public abstract void setMember(String name, Object value);
+ public boolean isInstance(final Object instance) {
+ return false;
+ }
+
+ /**
+ * Checking whether this object is an instance of the given 'clazz' object.
+ *
+ * @param clazz clazz to check
+ * @return true if this object is an instance of the given 'clazz'
+ */
+ public boolean isInstanceOf(final Object clazz) {
+ if (clazz instanceof JSObject) {
+ return ((JSObject)clazz).isInstance(this);
+ }
+
+ return false;
+ }
/**
- * Set an indexed member in a JavaScript object
+ * ECMA [[Class]] property
+ *
+ * @return ECMA [[Class]] property value of this object
+ */
+ public String getClassName() {
+ return getClass().getName();
+ }
+
+ /**
+ * Is this a function object?
*
- * @param index index of member slot
- * @param value value of member
+ * @return if this mirror wraps a ECMAScript function instance
+ */
+ public boolean isFunction() {
+ return false;
+ }
+
+ /**
+ * Is this a 'use strict' function object?
+ *
+ * @return true if this mirror represents a ECMAScript 'use strict' function
*/
- public abstract void setSlot(int index, Object value);
+ public boolean isStrictFunction() {
+ return false;
+ }
+
+ /**
+ * Is this an array object?
+ *
+ * @return if this mirror wraps a ECMAScript array object
+ */
+ public boolean isArray() {
+ return false;
+ }
}
--- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Fri Sep 20 19:15:59 2013 -0700
@@ -315,7 +315,7 @@
final ScriptObjectMirror mirror = (ScriptObjectMirror)thiz;
realSelf = mirror.getScriptObject();
realGlobal = mirror.getHomeGlobal();
- if (! realGlobal.isOfContext(nashornContext)) {
+ if (! isOfContext(realGlobal, nashornContext)) {
throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
}
} else if (thiz instanceof ScriptObject) {
@@ -326,7 +326,7 @@
throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
}
- if (! realGlobal.isOfContext(nashornContext)) {
+ if (! isOfContext(realGlobal, nashornContext)) {
throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
}
}
@@ -394,7 +394,7 @@
// Retrieve nashorn Global object from a given ScriptObjectMirror
private ScriptObject globalFromMirror(final ScriptObjectMirror mirror) {
ScriptObject sobj = mirror.getScriptObject();
- if (sobj instanceof GlobalObject && sobj.isOfContext(nashornContext)) {
+ if (sobj instanceof GlobalObject && isOfContext(sobj, nashornContext)) {
return sobj;
}
@@ -470,7 +470,7 @@
ScriptObjectMirror selfMirror = null;
if (selfObject instanceof ScriptObjectMirror) {
selfMirror = (ScriptObjectMirror)selfObject;
- if (! selfMirror.getHomeGlobal().isOfContext(nashornContext)) {
+ if (! isOfContext(selfMirror.getHomeGlobal(), nashornContext)) {
throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
}
} else if (selfObject instanceof ScriptObject) {
@@ -481,7 +481,7 @@
throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
}
- if (! oldGlobal.isOfContext(nashornContext)) {
+ if (! isOfContext(oldGlobal, nashornContext)) {
throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
}
@@ -494,7 +494,7 @@
if (selfMirror != null) {
try {
- return ScriptObjectMirror.translateUndefined(selfMirror.call(name, args));
+ return ScriptObjectMirror.translateUndefined(selfMirror.callMember(name, args));
} catch (final Exception e) {
final Throwable cause = e.getCause();
if (cause instanceof NoSuchMethodException) {
@@ -617,4 +617,9 @@
}
return true;
}
+
+ private static boolean isOfContext(final ScriptObject global, final Context context) {
+ assert global instanceof GlobalObject: "Not a Global object";
+ return ((GlobalObject)global).isOfContext(context);
+ }
}
--- a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Fri Sep 20 19:15:59 2013 -0700
@@ -42,14 +42,13 @@
import java.util.concurrent.Callable;
import javax.script.Bindings;
import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.GlobalObject;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
/**
- * Mirror object that wraps a given ScriptObject instance. User can
- * access ScriptObject via the javax.script.Bindings interface or
- * netscape.javascript.JSObject interface.
+ * Mirror object that wraps a given Nashorn Script object.
*/
public final class ScriptObjectMirror extends JSObject implements Bindings {
private static AccessControlContext getContextAccCtxt() {
@@ -62,6 +61,7 @@
private final ScriptObject sobj;
private final ScriptObject global;
+ private final boolean strict;
@Override
public boolean equals(final Object other) {
@@ -88,8 +88,9 @@
}
// JSObject methods
+
@Override
- public Object call(final String functionName, final Object... args) {
+ public Object call(final Object thiz, final Object... args) {
final ScriptObject oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global);
@@ -98,15 +99,13 @@
Context.setGlobal(global);
}
- final Object val = functionName == null? sobj : sobj.get(functionName);
- if (val instanceof ScriptFunction) {
+ if (sobj instanceof ScriptFunction) {
final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
- return wrap(ScriptRuntime.checkAndApply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global);
- } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) {
- return ((ScriptObjectMirror)val).call(null, args);
+ final Object self = globalChanged? wrap(thiz, oldGlobal) : thiz;
+ return wrap(ScriptRuntime.apply((ScriptFunction)sobj, unwrap(self, global), unwrapArray(modArgs, global)), global);
}
- throw new NoSuchMethodException("No such function " + ((functionName != null)? functionName : ""));
+ throw new RuntimeException("not a function: " + toString());
} catch (final RuntimeException | Error e) {
throw e;
} catch (final Throwable t) {
@@ -119,7 +118,7 @@
}
@Override
- public Object newObject(final String functionName, final Object... args) {
+ public Object newObject(final Object... args) {
final ScriptObject oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global);
@@ -128,15 +127,12 @@
Context.setGlobal(global);
}
- final Object val = functionName == null? sobj : sobj.get(functionName);
- if (val instanceof ScriptFunction) {
+ if (sobj instanceof ScriptFunction) {
final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
- return wrap(ScriptRuntime.checkAndConstruct((ScriptFunction)val, unwrapArray(modArgs, global)), global);
- } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) {
- return ((ScriptObjectMirror)val).newObject(null, args);
+ return wrap(ScriptRuntime.construct((ScriptFunction)sobj, unwrapArray(modArgs, global)), global);
}
- throw new RuntimeException("not a constructor " + ((functionName != null)? functionName : ""));
+ throw new RuntimeException("not a constructor: " + toString());
} catch (final RuntimeException | Error e) {
throw e;
} catch (final Throwable t) {
@@ -166,7 +162,39 @@
}
@Override
+ public Object callMember(final String functionName, final Object... args) {
+ functionName.getClass(); // null check
+ final ScriptObject oldGlobal = Context.getGlobal();
+ final boolean globalChanged = (oldGlobal != global);
+
+ try {
+ if (globalChanged) {
+ Context.setGlobal(global);
+ }
+
+ final Object val = sobj.get(functionName);
+ if (val instanceof ScriptFunction) {
+ final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
+ return wrap(ScriptRuntime.apply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global);
+ } else if (val instanceof JSObject && ((JSObject)val).isFunction()) {
+ return ((JSObject)val).call(sobj, args);
+ }
+
+ throw new NoSuchMethodException("No such function " + functionName);
+ } catch (final RuntimeException | Error e) {
+ throw e;
+ } catch (final Throwable t) {
+ throw new RuntimeException(t);
+ } finally {
+ if (globalChanged) {
+ Context.setGlobal(oldGlobal);
+ }
+ }
+ }
+
+ @Override
public Object getMember(final String name) {
+ name.getClass();
return inGlobal(new Callable<Object>() {
@Override public Object call() {
return wrap(sobj.get(name), global);
@@ -184,12 +212,33 @@
}
@Override
+ public boolean hasMember(final String name) {
+ name.getClass();
+ return inGlobal(new Callable<Boolean>() {
+ @Override public Boolean call() {
+ return sobj.has(name);
+ }
+ });
+ }
+
+ @Override
+ public boolean hasSlot(final int slot) {
+ return inGlobal(new Callable<Boolean>() {
+ @Override public Boolean call() {
+ return sobj.has(slot);
+ }
+ });
+ }
+
+ @Override
public void removeMember(final String name) {
+ name.getClass();
remove(name);
}
@Override
public void setMember(final String name, final Object value) {
+ name.getClass();
put(name, value);
}
@@ -197,19 +246,58 @@
public void setSlot(final int index, final Object value) {
inGlobal(new Callable<Void>() {
@Override public Void call() {
- sobj.set(index, unwrap(value, global), global.isStrictContext());
+ sobj.set(index, unwrap(value, global), strict);
return null;
}
});
}
+ @Override
+ public boolean isInstance(final Object obj) {
+ if (! (obj instanceof ScriptObjectMirror)) {
+ return false;
+ }
+
+ final ScriptObjectMirror instance = (ScriptObjectMirror)obj;
+ // if not belongs to my global scope, return false
+ if (global != instance.global) {
+ return false;
+ }
+
+ return inGlobal(new Callable<Boolean>() {
+ @Override public Boolean call() {
+ return sobj.isInstance(instance.sobj);
+ }
+ });
+ }
+
+ @Override
+ public String getClassName() {
+ return sobj.getClassName();
+ }
+
+ @Override
+ public boolean isFunction() {
+ return sobj instanceof ScriptFunction;
+ }
+
+ @Override
+ public boolean isStrictFunction() {
+ return isFunction() && ((ScriptFunction)sobj).isStrict();
+ }
+
+ @Override
+ public boolean isArray() {
+ return sobj.isArray();
+ }
+
// javax.script.Bindings methods
@Override
public void clear() {
inGlobal(new Callable<Object>() {
@Override public Object call() {
- sobj.clear();
+ sobj.clear(strict);
return null;
}
});
@@ -292,7 +380,7 @@
return inGlobal(new Callable<Object>() {
@Override public Object call() {
final Object modValue = globalChanged? wrap(value, oldGlobal) : value;
- return translateUndefined(wrap(sobj.put(key, unwrap(modValue, global)), global));
+ return translateUndefined(wrap(sobj.put(key, unwrap(modValue, global), strict), global));
}
});
}
@@ -303,7 +391,6 @@
final boolean globalChanged = (oldGlobal != global);
inGlobal(new Callable<Object>() {
@Override public Object call() {
- final boolean strict = global.isStrictContext();
for (final Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) {
final Object value = entry.getValue();
final Object modValue = globalChanged? wrap(value, oldGlobal) : value;
@@ -318,7 +405,7 @@
public Object remove(final Object key) {
return inGlobal(new Callable<Object>() {
@Override public Object call() {
- return wrap(sobj.remove(unwrap(key, global)), global);
+ return wrap(sobj.remove(unwrap(key, global), strict), global);
}
});
}
@@ -333,7 +420,7 @@
public boolean delete(final Object key) {
return inGlobal(new Callable<Boolean>() {
@Override public Boolean call() {
- return sobj.delete(unwrap(key, global));
+ return sobj.delete(unwrap(key, global), strict);
}
});
}
@@ -391,15 +478,6 @@
}
/**
- * ECMA [[Class]] property
- *
- * @return ECMA [[Class]] property value of this object
- */
- public String getClassName() {
- return sobj.getClassName();
- }
-
- /**
* ECMA 8.12.1 [[GetOwnProperty]] (P)
*
* @param key property key
@@ -505,55 +583,6 @@
});
}
- // ECMAScript instanceof check
-
- /**
- * Checking whether a script object is an instance of another by
- * walking the proto chain
- *
- * @param instance instace to check
- * @return true if 'instance' is an instance of this object
- */
- public boolean isInstance(final ScriptObjectMirror instance) {
- // if not belongs to my global scope, return false
- if (instance == null || global != instance.global) {
- return false;
- }
-
- return inGlobal(new Callable<Boolean>() {
- @Override public Boolean call() {
- return sobj.isInstance(instance.sobj);
- }
- });
- }
-
- /**
- * is this a function object?
- *
- * @return if this mirror wraps a ECMAScript function instance
- */
- public boolean isFunction() {
- return sobj instanceof ScriptFunction;
- }
-
- /**
- * is this a 'use strict' function object?
- *
- * @return true if this mirror represents a ECMAScript 'use strict' function
- */
- public boolean isStrictFunction() {
- return isFunction() && ((ScriptFunction)sobj).isStrict();
- }
-
- /**
- * is this an array object?
- *
- * @return if this mirror wraps a ECMAScript array object
- */
- public boolean isArray() {
- return sobj.isArray();
- }
-
/**
* Utility to check if given object is ECMAScript undefined value
*
@@ -637,10 +666,11 @@
ScriptObjectMirror(final ScriptObject sobj, final ScriptObject global) {
assert sobj != null : "ScriptObjectMirror on null!";
- assert global != null : "null global for ScriptObjectMirror!";
+ assert global instanceof GlobalObject : "global is not a GlobalObject";
this.sobj = sobj;
this.global = global;
+ this.strict = ((GlobalObject)global).isStrictContext();
}
// accessors for script engine
--- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java Fri Sep 20 19:15:59 2013 -0700
@@ -26,6 +26,7 @@
package jdk.nashorn.internal.codegen;
import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS;
+import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS_VAR;
import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE;
import static jdk.nashorn.internal.codegen.CompilerConstants.EXCEPTION_PREFIX;
import static jdk.nashorn.internal.codegen.CompilerConstants.ITERATOR_PREFIX;
@@ -172,7 +173,9 @@
initCompileConstant(VARARGS, body, IS_PARAM | IS_INTERNAL);
if (functionNode.needsArguments()) {
initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL | IS_ALWAYS_DEFINED);
- addLocalDef(ARGUMENTS.symbolName());
+ final String argumentsName = ARGUMENTS_VAR.symbolName();
+ newType(defineSymbol(body, argumentsName, IS_VAR | IS_ALWAYS_DEFINED), Type.typeFor(ARGUMENTS_VAR.type()));
+ addLocalDef(argumentsName);
}
}
@@ -491,30 +494,29 @@
objectifySymbols(body);
}
+ List<VarNode> syntheticInitializers = null;
+
if (body.getFlag(Block.NEEDS_SELF_SYMBOL)) {
- final IdentNode callee = compilerConstant(CALLEE);
- VarNode selfInit =
- new VarNode(
- newFunctionNode.getLineNumber(),
- newFunctionNode.getToken(),
- newFunctionNode.getFinish(),
- newFunctionNode.getIdent(),
- callee);
-
- LOG.info("Accepting self symbol init ", selfInit, " for ", newFunctionNode.getName());
+ syntheticInitializers = new ArrayList<>(2);
+ LOG.info("Accepting self symbol init for ", newFunctionNode.getName());
+ // "var fn = :callee"
+ syntheticInitializers.add(createSyntheticInitializer(newFunctionNode.getIdent(), CALLEE, newFunctionNode));
+ }
- final List<Statement> newStatements = new ArrayList<>();
- assert callee.getSymbol() != null && callee.getSymbol().hasSlot();
-
- final IdentNode name = selfInit.getName();
- final Symbol nameSymbol = body.getExistingSymbol(name.getName());
+ if(newFunctionNode.needsArguments()) {
+ if(syntheticInitializers == null) {
+ syntheticInitializers = new ArrayList<>(1);
+ }
+ // "var arguments = :arguments"
+ syntheticInitializers.add(createSyntheticInitializer(createImplicitIdentifier(ARGUMENTS_VAR.symbolName()),
+ ARGUMENTS, newFunctionNode));
+ }
- assert nameSymbol != null;
-
- selfInit = selfInit.setName((IdentNode)name.setSymbol(lc, nameSymbol));
-
- newStatements.add(selfInit);
- newStatements.addAll(body.getStatements());
+ if(syntheticInitializers != null) {
+ final List<Statement> stmts = body.getStatements();
+ final List<Statement> newStatements = new ArrayList<>(stmts.size() + syntheticInitializers.size());
+ newStatements.addAll(syntheticInitializers);
+ newStatements.addAll(stmts);
newFunctionNode = newFunctionNode.setBody(lc, body.setStatements(lc, newStatements));
}
@@ -533,6 +535,28 @@
return newFunctionNode;
}
+ /**
+ * Creates a synthetic initializer for a variable (a var statement that doesn't occur in the source code). Typically
+ * used to create assignmnent of {@code :callee} to the function name symbol in self-referential function
+ * expressions as well as for assignment of {@code :arguments} to {@code arguments}.
+ *
+ * @param name the ident node identifying the variable to initialize
+ * @param initConstant the compiler constant it is initialized to
+ * @param fn the function node the assignment is for
+ * @return a var node with the appropriate assignment
+ */
+ private VarNode createSyntheticInitializer(final IdentNode name, final CompilerConstants initConstant, final FunctionNode fn) {
+ final IdentNode init = compilerConstant(initConstant);
+ assert init.getSymbol() != null && init.getSymbol().hasSlot();
+
+ VarNode synthVar = new VarNode(fn.getLineNumber(), fn.getToken(), fn.getFinish(), name, init);
+
+ final Symbol nameSymbol = fn.getBody().getExistingSymbol(name.getName());
+ assert nameSymbol != null;
+
+ return synthVar.setName((IdentNode)name.setSymbol(lc, nameSymbol));
+ }
+
@Override
public Node leaveCONVERT(final UnaryNode unaryNode) {
assert false : "There should be no convert operators in IR during Attribution";
@@ -886,10 +910,9 @@
@Override
public Node leaveDECINC(final UnaryNode unaryNode) {
// @see assignOffset
- final UnaryNode newUnaryNode = unaryNode.setRHS(ensureAssignmentSlots(unaryNode.rhs()));
final Type type = arithType();
- newType(newUnaryNode.rhs().getSymbol(), type);
- return end(ensureSymbol(type, newUnaryNode));
+ newType(unaryNode.rhs().getSymbol(), type);
+ return end(ensureSymbol(type, unaryNode));
}
@Override
@@ -975,15 +998,18 @@
}
private IdentNode compilerConstant(CompilerConstants cc) {
- final FunctionNode functionNode = lc.getCurrentFunction();
- return (IdentNode)
- new IdentNode(
- functionNode.getToken(),
- functionNode.getFinish(),
- cc.symbolName()).
- setSymbol(
- lc,
- functionNode.compilerConstant(cc));
+ return (IdentNode)createImplicitIdentifier(cc.symbolName()).setSymbol(lc, lc.getCurrentFunction().compilerConstant(cc));
+ }
+
+ /**
+ * Creates an ident node for an implicit identifier within the function (one not declared in the script source
+ * code). These identifiers are defined with function's token and finish.
+ * @param name the name of the identifier
+ * @return an ident node representing the implicit identifier.
+ */
+ private IdentNode createImplicitIdentifier(final String name) {
+ final FunctionNode fn = lc.getCurrentFunction();
+ return new IdentNode(fn.getToken(), fn.getFinish(), name);
}
@Override
@@ -1575,39 +1601,6 @@
}
/**
- * In an assignment, recursively make sure that there are slots for
- * everything that has to be laid out as temporary storage, which is the
- * case if we are assign-op:ing a BaseNode subclass. This has to be
- * recursive to handle things like multi dimensional arrays as lhs
- *
- * see NASHORN-258
- *
- * @param assignmentDest the destination node of the assignment, e.g. lhs for binary nodes
- */
- private Expression ensureAssignmentSlots(final Expression assignmentDest) {
- final LexicalContext attrLexicalContext = lc;
- return (Expression)assignmentDest.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
- @Override
- public Node leaveIndexNode(final IndexNode indexNode) {
- assert indexNode.getSymbol().isTemp();
- final Expression index = indexNode.getIndex();
- //only temps can be set as needing slots. the others will self resolve
- //it is illegal to take a scope var and force it to be a slot, that breaks
- Symbol indexSymbol = index.getSymbol();
- if (indexSymbol.isTemp() && !indexSymbol.isConstant() && !indexSymbol.hasSlot()) {
- if(indexSymbol.isShared()) {
- indexSymbol = temporarySymbols.createUnshared(indexSymbol);
- }
- indexSymbol.setNeedsSlot(true);
- attrLexicalContext.getCurrentBlock().putSymbol(attrLexicalContext, indexSymbol);
- return indexNode.setIndex(index.setSymbol(attrLexicalContext, indexSymbol));
- }
- return indexNode;
- }
- });
- }
-
- /**
* Return the type that arithmetic ops should use. Until we have implemented better type
* analysis (range based) or overflow checks that are fast enough for int arithmetic,
* this is the number type
@@ -1704,7 +1697,7 @@
newType(lhs.getSymbol(), destType); //may not narrow if dest is already wider than destType
// ensureSymbol(destType, binaryNode); //for OP= nodes, the node can carry a narrower types than its lhs rhs. This is perfectly fine
- return end(ensureSymbol(destType, ensureAssignmentSlots(binaryNode)));
+ return end(ensureSymbol(destType, binaryNode));
}
private Expression ensureSymbol(final Type type, final Expression expr) {
--- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java Fri Sep 20 19:15:59 2013 -0700
@@ -1361,6 +1361,7 @@
final List<Expression> values = new ArrayList<>();
boolean hasGettersSetters = false;
+ Expression protoNode = null;
for (PropertyNode propertyNode: elements) {
final Expression value = propertyNode.getValue();
@@ -1369,6 +1370,9 @@
if (value == null) {
hasGettersSetters = true;
+ } else if (key.equals(ScriptObject.PROTO_PROPERTY_NAME)) {
+ protoNode = value;
+ continue;
}
keys.add(key);
@@ -1410,8 +1414,13 @@
}
method.dup();
- globalObjectPrototype();
- method.invoke(ScriptObject.SET_PROTO);
+ if (protoNode != null) {
+ load(protoNode);
+ method.invoke(ScriptObject.SET_PROTO_CHECK);
+ } else {
+ globalObjectPrototype();
+ method.invoke(ScriptObject.SET_PROTO);
+ }
if (hasGettersSetters) {
for (final PropertyNode propertyNode : elements) {
--- a/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java Fri Sep 20 19:15:59 2013 -0700
@@ -102,8 +102,12 @@
/** the varargs variable when necessary */
VARARGS(":varargs", Object[].class),
- /** the arguments vector when necessary and the slot */
- ARGUMENTS("arguments", ScriptObject.class, 2),
+ /** the arguments variable (visible to function body). Initially set to ARGUMENTS, but can be reassigned by code in
+ * the function body.*/
+ ARGUMENTS_VAR("arguments", Object.class),
+
+ /** the internal arguments object, when necessary (not visible to scripts, can't be reassigned). */
+ ARGUMENTS(":arguments", ScriptObject.class),
/** prefix for iterators for for (x in ...) */
ITERATOR_PREFIX(":i", Iterator.class),
--- a/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java Fri Sep 20 19:15:59 2013 -0700
@@ -168,6 +168,7 @@
* return 3;
* }
* }
+ * </pre>
*
* @return true if can have callsite type
*/
--- a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java Fri Sep 20 19:15:59 2013 -0700
@@ -27,6 +27,7 @@
import java.util.Arrays;
import java.util.List;
+import java.util.ArrayList;
import jdk.nashorn.internal.codegen.CompilerConstants;
import jdk.nashorn.internal.ir.AccessNode;
import jdk.nashorn.internal.ir.BinaryNode;
@@ -197,10 +198,10 @@
comma();
final IdentNode label = breakNode.getLabel();
+ property("label");
if (label != null) {
- property("label", label.getName());
+ label.accept(this);
} else {
- property("label");
nullValue();
}
@@ -256,13 +257,11 @@
comma();
final Node guard = catchNode.getExceptionCondition();
- property("guard");
if (guard != null) {
+ property("guard");
guard.accept(this);
- } else {
- nullValue();
+ comma();
}
- comma();
property("body");
catchNode.getBody().accept(this);
@@ -278,10 +277,10 @@
comma();
final IdentNode label = continueNode.getLabel();
+ property("label");
if (label != null) {
- property("label", label.getName());
+ label.accept(this);
} else {
- property("label");
nullValue();
}
@@ -299,13 +298,20 @@
@Override
public boolean enterExpressionStatement(final ExpressionStatement expressionStatement) {
+ // handle debugger statement
+ final Node expression = expressionStatement.getExpression();
+ if (expression instanceof RuntimeNode) {
+ expression.accept(this);
+ return false;
+ }
+
enterDefault(expressionStatement);
type("ExpressionStatement");
comma();
property("expression");
- expressionStatement.getExpression().accept(this);
+ expression.accept(this);
return leave();
}
@@ -388,13 +394,14 @@
@Override
public boolean enterFunctionNode(final FunctionNode functionNode) {
- enterDefault(functionNode);
+ final boolean program = functionNode.isProgram();
+ if (program) {
+ return emitProgram(functionNode);
+ }
- final boolean program = functionNode.isProgram();
+ enterDefault(functionNode);
final String name;
- if (program) {
- name = "Program";
- } else if (functionNode.isDeclared()) {
+ if (functionNode.isDeclared()) {
name = "FunctionDeclaration";
} else {
name = "FunctionExpression";
@@ -402,24 +409,41 @@
type(name);
comma();
- if (! program) {
- property("id");
- if (functionNode.isAnonymous()) {
- nullValue();
- } else {
- functionNode.getIdent().accept(this);
- }
- comma();
+ property("id");
+ if (functionNode.isAnonymous()) {
+ nullValue();
+ } else {
+ functionNode.getIdent().accept(this);
}
+ comma();
+
+ array("params", functionNode.getParameters());
+ comma();
+
+ arrayStart("defaults");
+ arrayEnd();
+ comma();
property("rest");
nullValue();
comma();
- if (!program) {
- array("params", functionNode.getParameters());
- comma();
- }
+ property("body");
+ functionNode.getBody().accept(this);
+ comma();
+
+ property("generator", false);
+ comma();
+
+ property("expression", false);
+
+ return leave();
+ }
+
+ private boolean emitProgram(final FunctionNode functionNode) {
+ enterDefault(functionNode);
+ type("Program");
+ comma();
// body consists of nested functions and statements
final List<Statement> stats = functionNode.getBody().getStatements();
@@ -730,7 +754,31 @@
tryNode.getBody().accept(this);
comma();
- array("handlers", tryNode.getCatches());
+
+ final List<? extends Node> catches = tryNode.getCatches();
+ final List<CatchNode> guarded = new ArrayList<>();
+ CatchNode unguarded = null;
+ if (catches != null) {
+ for (Node n : catches) {
+ CatchNode cn = (CatchNode)n;
+ if (cn.getExceptionCondition() != null) {
+ guarded.add(cn);
+ } else {
+ assert unguarded == null: "too many unguarded?";
+ unguarded = cn;
+ }
+ }
+ }
+
+ array("guardedHandlers", guarded);
+ comma();
+
+ property("handler");
+ if (unguarded != null) {
+ unguarded.accept(this);
+ } else {
+ nullValue();
+ }
comma();
property("finalizer");
@@ -760,8 +808,8 @@
array("arguments", callNode.getArgs());
} else {
+ final String operator;
final boolean prefix;
- final String operator;
switch (tokenType) {
case INCPOSTFIX:
prefix = false;
@@ -780,8 +828,9 @@
prefix = true;
break;
default:
- prefix = false;
+ prefix = true;
operator = tokenType.getName();
+ break;
}
type(unaryNode.isAssignment()? "UpdateExpression" : "UnaryExpression");
@@ -802,6 +851,14 @@
@Override
public boolean enterVarNode(final VarNode varNode) {
+ final Node init = varNode.getInit();
+ if (init instanceof FunctionNode && ((FunctionNode)init).isDeclared()) {
+ // function declaration - don't emit VariableDeclaration instead
+ // just emit FunctionDeclaration using 'init' Node.
+ init.accept(this);
+ return false;
+ }
+
enterDefault(varNode);
type("VariableDeclaration");
@@ -816,11 +873,11 @@
type("VariableDeclarator");
comma();
- property("id", varNode.getName().toString());
+ property("id");
+ varNode.getName().accept(this);
comma();
property("init");
- final Node init = varNode.getInit();
if (init != null) {
init.accept(this);
} else {
@@ -855,7 +912,7 @@
whileNode.getTest().accept(this);
comma();
- property("block");
+ property("body");
whileNode.getBody().accept(this);
}
@@ -894,23 +951,27 @@
return buf.toString();
}
- private void property(final String key, final String value) {
+ private void property(final String key, final String value, final boolean escape) {
buf.append('"');
buf.append(key);
buf.append("\":");
if (value != null) {
- buf.append('"');
+ if (escape) buf.append('"');
buf.append(value);
- buf.append('"');
+ if (escape) buf.append('"');
}
}
+ private void property(final String key, final String value) {
+ property(key, value, true);
+ }
+
private void property(final String key, final boolean value) {
- property(key, Boolean.toString(value));
+ property(key, Boolean.toString(value), false);
}
private void property(final String key, final int value) {
- property(key, Integer.toString(value));
+ property(key, Integer.toString(value), false);
}
private void property(final String key) {
--- a/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java Fri Sep 20 19:15:59 2013 -0700
@@ -565,7 +565,7 @@
@Override
public MethodHandle asSpreader(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
- final MethodHandle mh = super.asCollector(handle, arrayType, arrayLength);
+ final MethodHandle mh = super.asSpreader(handle, arrayType, arrayLength);
return debug(mh, "asSpreader", handle, arrayType, arrayLength);
}
--- a/nashorn/src/jdk/nashorn/internal/objects/Global.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java Fri Sep 20 19:15:59 2013 -0700
@@ -412,6 +412,14 @@
// initialized by nasgen
private static PropertyMap $nasgenmap$;
+ // context to which this global belongs to
+ private final Context context;
+
+ @Override
+ protected Context getContext() {
+ return context;
+ }
+
// performs initialization checks for Global constructor and returns the
// PropertyMap, if everything is fine.
private static PropertyMap checkAndGetMap(final Context context) {
@@ -439,7 +447,7 @@
*/
public Global(final Context context) {
super(checkAndGetMap(context));
- this.setContext(context);
+ this.context = context;
this.setIsScope();
final int cacheSize = context.getEnv()._class_cache_size;
@@ -482,6 +490,16 @@
// GlobalObject interface implementation
@Override
+ public boolean isOfContext(final Context context) {
+ return this.context == context;
+ }
+
+ @Override
+ public boolean isStrictContext() {
+ return context.getEnv()._strict;
+ }
+
+ @Override
public void initBuiltinObjects() {
if (this.builtinObject != null) {
// already initialized, just return
@@ -1765,7 +1783,7 @@
// do not fill $ENV if we have a security manager around
// Retrieve current state of ENV variables.
final ScriptObject env = newObject();
- env.putAll(System.getenv());
+ env.putAll(System.getenv(), scriptEnv._strict);
addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, env);
} else {
addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java Fri Sep 20 19:15:59 2013 -0700
@@ -41,7 +41,7 @@
import java.util.List;
import java.util.concurrent.Callable;
-import jdk.nashorn.api.scripting.ScriptObjectMirror;
+import jdk.nashorn.api.scripting.JSObject;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
@@ -374,7 +374,7 @@
public static Object isArray(final Object self, final Object arg) {
return isArray(arg) || (arg == Global.instance().getArrayPrototype())
|| (arg instanceof NativeRegExpExecResult)
- || (arg instanceof ScriptObjectMirror && ((ScriptObjectMirror)arg).isArray());
+ || (arg instanceof JSObject && ((JSObject)arg).isArray());
}
/**
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java Fri Sep 20 19:15:59 2013 -0700
@@ -30,7 +30,7 @@
import java.util.List;
-import jdk.nashorn.api.scripting.ScriptObjectMirror;
+import jdk.nashorn.api.scripting.JSObject;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
@@ -88,7 +88,7 @@
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object apply(final Object self, final Object thiz, final Object array) {
- if (!(self instanceof ScriptFunction)) {
+ if (!(self instanceof ScriptFunction) && !(self instanceof JSObject)) {
throw typeError("not.a.function", ScriptRuntime.safeToString(self));
}
@@ -111,21 +111,27 @@
list.toArray(args = new Object[list.size()]);
} else if (array == null || array == UNDEFINED) {
args = ScriptRuntime.EMPTY_ARRAY;
- } else if (array instanceof ScriptObjectMirror) {
- // look for array-like ScriptObjectMirror object
- final ScriptObjectMirror mirror = (ScriptObjectMirror)array;
- final Object len = mirror.containsKey("length")? mirror.getMember("length") : Integer.valueOf(0);
+ } else if (array instanceof JSObject) {
+ // look for array-like JSObject object
+ final JSObject jsObj = (JSObject)array;
+ final Object len = jsObj.hasMember("length")? jsObj.getMember("length") : Integer.valueOf(0);
final int n = (int)JSType.toUint32(len);
args = new Object[n];
for (int i = 0; i < args.length; i++) {
- args[i] = mirror.containsKey(i)? mirror.getSlot(i) : UNDEFINED;
+ args[i] = jsObj.hasSlot(i)? jsObj.getSlot(i) : UNDEFINED;
}
} else {
throw typeError("function.apply.expects.array");
}
- return ScriptRuntime.apply((ScriptFunction)self, thiz, args);
+ if (self instanceof ScriptFunction) {
+ return ScriptRuntime.apply((ScriptFunction)self, thiz, args);
+ } else if (self instanceof JSObject) {
+ return ((JSObject)self).call(thiz, args);
+ }
+
+ throw new AssertionError("should not reach here");
}
/**
@@ -137,7 +143,7 @@
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object call(final Object self, final Object... args) {
- if (!(self instanceof ScriptFunction)) {
+ if (!(self instanceof ScriptFunction) && !(self instanceof JSObject)) {
throw typeError("not.a.function", ScriptRuntime.safeToString(self));
}
@@ -151,7 +157,13 @@
arguments = ScriptRuntime.EMPTY_ARRAY;
}
- return ScriptRuntime.apply((ScriptFunction)self, thiz, arguments);
+ if (self instanceof ScriptFunction) {
+ return ScriptRuntime.apply((ScriptFunction)self, thiz, arguments);
+ } else if (self instanceof JSObject) {
+ return ((JSObject)self).call(thiz, arguments);
+ }
+
+ throw new AssertionError("should not reach here");
}
/**
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java Fri Sep 20 19:15:59 2013 -0700
@@ -34,6 +34,7 @@
import java.util.List;
import jdk.internal.dynalink.beans.StaticClass;
import jdk.internal.dynalink.support.TypeUtilities;
+import jdk.nashorn.api.scripting.JSObject;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Function;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
@@ -43,6 +44,7 @@
import jdk.nashorn.internal.runtime.ListAdapter;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.linker.Bootstrap;
import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
@@ -288,7 +290,9 @@
return null;
}
- Global.checkObject(obj);
+ if (!(obj instanceof ScriptObject) && !(obj instanceof JSObject)) {
+ throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
+ }
final Class<?> targetClass;
if(objType == UNDEFINED) {
@@ -304,11 +308,11 @@
}
if(targetClass.isArray()) {
- return ((ScriptObject)obj).getArray().asArrayOfType(targetClass.getComponentType());
+ return JSType.toJavaArray(obj, targetClass.getComponentType());
}
if(targetClass == List.class || targetClass == Deque.class) {
- return new ListAdapter((ScriptObject)obj);
+ return ListAdapter.create(obj);
}
throw typeError("unsupported.java.to.type", targetClass.getName());
--- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java Fri Sep 20 19:15:59 2013 -0700
@@ -25,7 +25,6 @@
package jdk.nashorn.internal.parser;
-import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS;
import static jdk.nashorn.internal.codegen.CompilerConstants.EVAL;
import static jdk.nashorn.internal.codegen.CompilerConstants.FUNCTION_PREFIX;
import static jdk.nashorn.internal.codegen.CompilerConstants.RUN_SCRIPT;
@@ -115,6 +114,8 @@
* Builds the IR.
*/
public class Parser extends AbstractParser {
+ private static final String ARGUMENTS_NAME = CompilerConstants.ARGUMENTS_VAR.symbolName();
+
/** Current script environment. */
private final ScriptEnvironment env;
@@ -511,13 +512,19 @@
* @param ident Referenced property.
*/
private void detectSpecialProperty(final IdentNode ident) {
- final String name = ident.getName();
-
- if (ARGUMENTS.symbolName().equals(name)) {
+ if (isArguments(ident)) {
lc.setFlag(lc.getCurrentFunction(), FunctionNode.USES_ARGUMENTS);
}
}
+ private static boolean isArguments(final String name) {
+ return ARGUMENTS_NAME.equals(name);
+ }
+
+ private static boolean isArguments(final IdentNode ident) {
+ return isArguments(ident.getName());
+ }
+
/**
* Tells whether a IdentNode can be used as L-value of an assignment
*
@@ -2060,7 +2067,7 @@
case FLOATING:
return getLiteral();
default:
- return getIdentifierName();
+ return getIdentifierName().setIsPropertyName();
}
}
@@ -2449,7 +2456,7 @@
} else if (env._function_statement == ScriptEnvironment.FunctionStatementBehavior.WARNING) {
warning(JSErrorType.SYNTAX_ERROR, AbstractParser.message("no.func.decl.here.warn"), functionToken);
}
- if (ARGUMENTS.symbolName().equals(name.getName())) {
+ if (isArguments(name)) {
lc.setFlag(lc.getCurrentFunction(), FunctionNode.DEFINES_ARGUMENTS);
}
}
@@ -2468,7 +2475,7 @@
final IdentNode parameter = parameters.get(i);
String parameterName = parameter.getName();
- if (ARGUMENTS.symbolName().equals(parameterName)) {
+ if (isArguments(parameterName)) {
functionNode = functionNode.setFlag(lc, FunctionNode.DEFINES_ARGUMENTS);
}
@@ -2486,7 +2493,7 @@
parametersSet.add(parameterName);
}
} else if (arity == 1) {
- if (ARGUMENTS.symbolName().equals(parameters.get(0).getName())) {
+ if (isArguments(parameters.get(0))) {
functionNode = functionNode.setFlag(lc, FunctionNode.DEFINES_ARGUMENTS);
}
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java Fri Sep 20 19:15:59 2013 -0700
@@ -236,6 +236,10 @@
private static final ClassLoader myLoader = Context.class.getClassLoader();
private static final StructureLoader sharedLoader;
+ /*package-private*/ ClassLoader getSharedLoader() {
+ return sharedLoader;
+ }
+
private static AccessControlContext createNoPermAccCtxt() {
return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) });
}
@@ -254,7 +258,7 @@
sharedLoader = AccessController.doPrivileged(new PrivilegedAction<StructureLoader>() {
@Override
public StructureLoader run() {
- return new StructureLoader(myLoader, null);
+ return new StructureLoader(myLoader);
}
}, CREATE_LOADER_ACC_CTXT);
}
@@ -573,7 +577,7 @@
setGlobalTrusted(newGlobal);
final Object[] wrapped = args == null? ScriptRuntime.EMPTY_ARRAY : ScriptObjectMirror.wrapArray(args, oldGlobal);
- newGlobal.put("arguments", ((GlobalObject)newGlobal).wrapAsObject(wrapped));
+ newGlobal.put("arguments", ((GlobalObject)newGlobal).wrapAsObject(wrapped), env._strict);
try {
// wrap objects from newGlobal's world as mirrors - but if result
@@ -599,7 +603,7 @@
* @throws ClassNotFoundException if structure class cannot be resolved
*/
public static Class<?> forStructureClass(final String fullName) throws ClassNotFoundException {
- if (System.getSecurityManager() != null && !NashornLoader.isStructureClass(fullName)) {
+ if (System.getSecurityManager() != null && !StructureLoader.isStructureClass(fullName)) {
throw new ClassNotFoundException(fullName);
}
return Class.forName(fullName, true, sharedLoader);
@@ -792,12 +796,11 @@
static Context fromClass(final Class<?> clazz) {
final ClassLoader loader = clazz.getClassLoader();
- Context context = null;
- if (loader instanceof NashornLoader) {
- context = ((NashornLoader)loader).getContext();
+ if (loader instanceof ScriptLoader) {
+ return ((ScriptLoader)loader).getContext();
}
- return (context != null) ? context : Context.getContextTrusted();
+ return Context.getContextTrusted();
}
private Object evaluateSource(final Source source, final ScriptObject scope, final ScriptObject thiz) {
@@ -899,7 +902,7 @@
new PrivilegedAction<ScriptLoader>() {
@Override
public ScriptLoader run() {
- return new ScriptLoader(sharedLoader, Context.this);
+ return new ScriptLoader(appLoader, Context.this);
}
}, CREATE_LOADER_ACC_CTXT);
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java Fri Sep 20 19:15:59 2013 -0700
@@ -28,7 +28,6 @@
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
-
import jdk.nashorn.api.scripting.NashornException;
import jdk.nashorn.internal.scripts.JS;
--- a/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java Fri Sep 20 19:15:59 2013 -0700
@@ -37,6 +37,18 @@
public interface GlobalObject {
/**
+ * Is this global of the given Context?
+ * @return true if this global belongs to the given Context
+ */
+ public boolean isOfContext(Context context);
+
+ /**
+ * Does this global belong to a strict Context?
+ * @return true if this global belongs to a strict Context
+ */
+ public boolean isStrictContext();
+
+ /**
* Initialize standard builtin objects like "Object", "Array", "Function" etc.
* as well as our extension builtin objects like "Java", "JSAdapter" as properties
* of the global scope object.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSObjectListAdapter.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2010, 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 jdk.nashorn.internal.runtime;
+
+import jdk.nashorn.api.scripting.JSObject;
+
+/**
+ * A ListAdapter that can wraps a JSObject.
+ */
+public final class JSObjectListAdapter extends ListAdapter {
+ /**
+ * Creates a new list wrapper for the specified JSObject.
+ * @param obj JSOcript the object to wrap
+ */
+ public JSObjectListAdapter(final JSObject obj) {
+ super(obj);
+ }
+
+ @Override
+ public int size() {
+ return JSType.toInt32(((JSObject)obj).getMember("length"));
+ }
+
+ @Override
+ protected Object getAt(int index) {
+ return ((JSObject)obj).getSlot(index);
+ }
+
+ @Override
+ protected void setAt(int index, Object element) {
+ ((JSObject)obj).setSlot(index, element);
+ }
+}
--- a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java Fri Sep 20 19:15:59 2013 -0700
@@ -28,11 +28,14 @@
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
-import java.util.Locale;
+import java.lang.reflect.Array;
import jdk.internal.dynalink.beans.StaticClass;
+import jdk.nashorn.api.scripting.JSObject;
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
import jdk.nashorn.internal.parser.Lexer;
+import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
import jdk.nashorn.internal.runtime.linker.Bootstrap;
/**
@@ -40,25 +43,28 @@
*/
public enum JSType {
/** The undefined type */
- UNDEFINED,
+ UNDEFINED("undefined"),
/** The null type */
- NULL,
+ NULL("object"),
/** The boolean type */
- BOOLEAN,
+ BOOLEAN("boolean"),
/** The number type */
- NUMBER,
+ NUMBER("number"),
/** The string type */
- STRING,
+ STRING("string"),
/** The object type */
- OBJECT,
+ OBJECT("object"),
/** The function type */
- FUNCTION;
+ FUNCTION("function");
+
+ /** The type name as returned by ECMAScript "typeof" operator*/
+ private final String typeName;
/** Max value for an uint32 in JavaScript */
public static final long MAX_UINT = 0xFFFF_FFFFL;
@@ -110,13 +116,21 @@
private static final double INT32_LIMIT = 4294967296.0;
/**
+ * Constructor
+ *
+ * @param typeName the type name
+ */
+ private JSType(final String typeName) {
+ this.typeName = typeName;
+ }
+
+ /**
* The external type name as returned by ECMAScript "typeof" operator
*
* @return type name for this type
*/
public final String typeName() {
- // For NULL, "object" has to be returned!
- return ((this == NULL) ? OBJECT : this).name().toLowerCase(Locale.ENGLISH);
+ return this.typeName;
}
/**
@@ -127,31 +141,32 @@
* @return the JSType for the object
*/
public static JSType of(final Object obj) {
- if (obj == ScriptRuntime.UNDEFINED) {
- return JSType.UNDEFINED;
+ // Order of these statements is tuned for performance (see JDK-8024476)
+ if (obj == null) {
+ return JSType.NULL;
}
- if (obj == null) {
- return JSType.NULL;
+ if (obj instanceof ScriptObject) {
+ return (obj instanceof ScriptFunction) ? JSType.FUNCTION : JSType.OBJECT;
}
if (obj instanceof Boolean) {
return JSType.BOOLEAN;
}
+ if (obj instanceof String || obj instanceof ConsString) {
+ return JSType.STRING;
+ }
+
if (obj instanceof Number) {
return JSType.NUMBER;
}
- if (obj instanceof String || obj instanceof ConsString) {
- return JSType.STRING;
+ if (obj == ScriptRuntime.UNDEFINED) {
+ return JSType.UNDEFINED;
}
- if (Bootstrap.isCallable(obj)) {
- return JSType.FUNCTION;
- }
-
- return JSType.OBJECT;
+ return Bootstrap.isCallable(obj) ? JSType.FUNCTION : JSType.OBJECT;
}
/**
@@ -849,6 +864,53 @@
}
/**
+ * Script object to Java array conversion.
+ *
+ * @param obj script object to be converted to Java array
+ * @param componentType component type of the destination array required
+ * @return converted Java array
+ */
+ public static Object toJavaArray(final Object obj, final Class<?> componentType) {
+ if (obj instanceof ScriptObject) {
+ return convertArray(((ScriptObject)obj).getArray().asObjectArray(), componentType);
+ } else if (obj instanceof JSObject) {
+ final ArrayLikeIterator itr = ArrayLikeIterator.arrayLikeIterator(obj);
+ final int len = (int) itr.getLength();
+ final Object[] res = new Object[len];
+ int idx = 0;
+ while (itr.hasNext()) {
+ res[idx++] = itr.next();
+ }
+ return convertArray(res, componentType);
+ } else {
+ throw new IllegalArgumentException("not a script object");
+ }
+ }
+
+ /**
+ * Java array to java array conversion - but using type conversions implemented by linker.
+ *
+ * @param src source array
+ * @param componentType component type of the destination array required
+ * @return converted Java array
+ */
+ public static Object convertArray(final Object[] src, final Class<?> componentType) {
+ final int l = src.length;
+ final Object dst = Array.newInstance(componentType, l);
+ final MethodHandle converter = Bootstrap.getLinkerServices().getTypeConverter(Object.class, componentType);
+ try {
+ for (int i = 0; i < src.length; i++) {
+ Array.set(dst, i, invoke(converter, src[i]));
+ }
+ } catch (final RuntimeException | Error e) {
+ throw e;
+ } catch (final Throwable t) {
+ throw new RuntimeException(t);
+ }
+ return dst;
+ }
+
+ /**
* Check if an object is null or undefined
*
* @param obj object to check
@@ -953,4 +1015,13 @@
return Double.NaN;
}
+ private static Object invoke(final MethodHandle mh, final Object arg) {
+ try {
+ return mh.invoke(arg);
+ } catch (final RuntimeException | Error e) {
+ throw e;
+ } catch (final Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java Fri Sep 20 19:15:59 2013 -0700
@@ -32,6 +32,7 @@
import java.util.NoSuchElementException;
import java.util.RandomAccess;
import java.util.concurrent.Callable;
+import jdk.nashorn.api.scripting.JSObject;
import jdk.nashorn.internal.runtime.linker.Bootstrap;
import jdk.nashorn.internal.runtime.linker.InvokeByName;
@@ -48,7 +49,7 @@
* operations respectively, while {@link #addLast(Object)} and {@link #removeLast()} will translate to {@code push} and
* {@code pop}.
*/
-public final class ListAdapter extends AbstractList<Object> implements RandomAccess, Deque<Object> {
+public abstract class ListAdapter extends AbstractList<Object> implements RandomAccess, Deque<Object> {
// These add to the back and front of the list
private static final Object PUSH = new Object();
private static InvokeByName getPUSH() {
@@ -56,7 +57,7 @@
new Callable<InvokeByName>() {
@Override
public InvokeByName call() {
- return new InvokeByName("push", ScriptObject.class, void.class, Object.class);
+ return new InvokeByName("push", Object.class, void.class, Object.class);
}
});
}
@@ -67,7 +68,7 @@
new Callable<InvokeByName>() {
@Override
public InvokeByName call() {
- return new InvokeByName("unshift", ScriptObject.class, void.class, Object.class);
+ return new InvokeByName("unshift", Object.class, void.class, Object.class);
}
});
}
@@ -79,7 +80,7 @@
new Callable<InvokeByName>() {
@Override
public InvokeByName call() {
- return new InvokeByName("pop", ScriptObject.class, Object.class);
+ return new InvokeByName("pop", Object.class, Object.class);
}
});
}
@@ -90,7 +91,7 @@
new Callable<InvokeByName>() {
@Override
public InvokeByName call() {
- return new InvokeByName("shift", ScriptObject.class, Object.class);
+ return new InvokeByName("shift", Object.class, Object.class);
}
});
}
@@ -102,7 +103,7 @@
new Callable<InvokeByName>() {
@Override
public InvokeByName call() {
- return new InvokeByName("splice", ScriptObject.class, void.class, int.class, int.class, Object.class);
+ return new InvokeByName("splice", Object.class, void.class, int.class, int.class, Object.class);
}
});
}
@@ -113,40 +114,52 @@
new Callable<InvokeByName>() {
@Override
public InvokeByName call() {
- return new InvokeByName("splice", ScriptObject.class, void.class, int.class, int.class);
+ return new InvokeByName("splice", Object.class, void.class, int.class, int.class);
}
});
}
- private final ScriptObject obj;
+ protected final Object obj;
- /**
- * Creates a new list wrapper for the specified script object.
- * @param obj script the object to wrap
- */
- public ListAdapter(ScriptObject obj) {
+ // allow subclasses only in this package
+ ListAdapter(Object obj) {
this.obj = obj;
}
- @Override
- public int size() {
- return JSType.toInt32(obj.getLength());
+ /**
+ * Factory to create a ListAdapter for a given script object.
+ *
+ * @param obj script object to wrap as a ListAdapter
+ * @return A ListAdapter wrapper object
+ */
+ public static ListAdapter create(final Object obj) {
+ if (obj instanceof ScriptObject) {
+ return new ScriptObjectListAdapter((ScriptObject)obj);
+ } else if (obj instanceof JSObject) {
+ return new JSObjectListAdapter((JSObject)obj);
+ } else {
+ throw new IllegalArgumentException("ScriptObject or JSObject expected");
+ }
}
@Override
- public Object get(int index) {
+ public final Object get(int index) {
checkRange(index);
- return obj.get(index);
+ return getAt(index);
}
+ protected abstract Object getAt(final int index);
+
@Override
public Object set(int index, Object element) {
checkRange(index);
- final Object prevValue = get(index);
- obj.set(index, element, false);
+ final Object prevValue = getAt(index);
+ setAt(index, element);
return prevValue;
}
+ protected abstract void setAt(int index, Object element);
+
private void checkRange(int index) {
if(index < 0 || index >= size()) {
throw invalidIndex(index);
@@ -154,18 +167,18 @@
}
@Override
- public void push(Object e) {
+ public final void push(Object e) {
addFirst(e);
}
@Override
- public boolean add(Object e) {
+ public final boolean add(Object e) {
addLast(e);
return true;
}
@Override
- public void addFirst(Object e) {
+ public final void addFirst(Object e) {
try {
final InvokeByName unshiftInvoker = getUNSHIFT();
final Object fn = unshiftInvoker.getGetter().invokeExact(obj);
@@ -179,7 +192,7 @@
}
@Override
- public void addLast(Object e) {
+ public final void addLast(Object e) {
try {
final InvokeByName pushInvoker = getPUSH();
final Object fn = pushInvoker.getGetter().invokeExact(obj);
@@ -193,7 +206,7 @@
}
@Override
- public void add(int index, Object e) {
+ public final void add(int index, Object e) {
try {
if(index < 0) {
throw invalidIndex(index);
@@ -229,40 +242,40 @@
}
@Override
- public boolean offer(Object e) {
+ public final boolean offer(Object e) {
return offerLast(e);
}
@Override
- public boolean offerFirst(Object e) {
+ public final boolean offerFirst(Object e) {
addFirst(e);
return true;
}
@Override
- public boolean offerLast(Object e) {
+ public final boolean offerLast(Object e) {
addLast(e);
return true;
}
@Override
- public Object pop() {
+ public final Object pop() {
return removeFirst();
}
@Override
- public Object remove() {
+ public final Object remove() {
return removeFirst();
}
@Override
- public Object removeFirst() {
+ public final Object removeFirst() {
checkNonEmpty();
return invokeShift();
}
@Override
- public Object removeLast() {
+ public final Object removeLast() {
checkNonEmpty();
return invokePop();
}
@@ -274,7 +287,7 @@
}
@Override
- public Object remove(int index) {
+ public final Object remove(int index) {
if(index < 0) {
throw invalidIndex(index);
} else if (index == 0) {
@@ -320,7 +333,7 @@
}
@Override
- protected void removeRange(int fromIndex, int toIndex) {
+ protected final void removeRange(int fromIndex, int toIndex) {
invokeSpliceRemove(fromIndex, toIndex - fromIndex);
}
@@ -338,54 +351,54 @@
}
@Override
- public Object poll() {
+ public final Object poll() {
return pollFirst();
}
@Override
- public Object pollFirst() {
+ public final Object pollFirst() {
return isEmpty() ? null : invokeShift();
}
@Override
- public Object pollLast() {
+ public final Object pollLast() {
return isEmpty() ? null : invokePop();
}
@Override
- public Object peek() {
+ public final Object peek() {
return peekFirst();
}
@Override
- public Object peekFirst() {
+ public final Object peekFirst() {
return isEmpty() ? null : get(0);
}
@Override
- public Object peekLast() {
+ public final Object peekLast() {
return isEmpty() ? null : get(size() - 1);
}
@Override
- public Object element() {
+ public final Object element() {
return getFirst();
}
@Override
- public Object getFirst() {
+ public final Object getFirst() {
checkNonEmpty();
return get(0);
}
@Override
- public Object getLast() {
+ public final Object getLast() {
checkNonEmpty();
return get(size() - 1);
}
@Override
- public Iterator<Object> descendingIterator() {
+ public final Iterator<Object> descendingIterator() {
final ListIterator<Object> it = listIterator(size());
return new Iterator<Object>() {
@Override
@@ -406,12 +419,12 @@
}
@Override
- public boolean removeFirstOccurrence(Object o) {
+ public final boolean removeFirstOccurrence(Object o) {
return removeOccurrence(o, iterator());
}
@Override
- public boolean removeLastOccurrence(Object o) {
+ public final boolean removeLastOccurrence(Object o) {
return removeOccurrence(o, descendingIterator());
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java Fri Sep 20 19:15:59 2013 -0700
@@ -38,10 +38,7 @@
import jdk.nashorn.tools.Shell;
/**
- * Superclass for Nashorn class loader classes. This stores Context
- * instance as an instance field. The current context can be
- * efficiently accessed from a given Class via it's ClassLoader.
- *
+ * Superclass for Nashorn class loader classes.
*/
abstract class NashornLoader extends SecureClassLoader {
private static final String OBJECTS_PKG = "jdk.nashorn.internal.objects";
@@ -69,27 +66,8 @@
};
}
- private final Context context;
-
- final Context getContext() {
- return context;
- }
-
- NashornLoader(final ClassLoader parent, final Context context) {
+ NashornLoader(final ClassLoader parent) {
super(parent);
- this.context = context;
- }
-
-
- /**
- * Called by subclass after package access check is done
- * @param name name of the class to be loaded
- * @param resolve whether the class should be resolved or not
- * @return Class object
- * @throws ClassNotFoundException if class cannot be loaded
- */
- protected final Class<?> loadClassTrusted(final String name, final boolean resolve) throws ClassNotFoundException {
- return super.loadClass(name, resolve);
}
protected static void checkPackageAccess(final String name) {
@@ -122,10 +100,6 @@
return permCollection;
}
- static boolean isStructureClass(final String fullName) {
- return fullName.startsWith(SCRIPTS_PKG);
- }
-
/**
* Create a secure URL class loader for the given classpath
* @param classPath classpath for the loader to search from
--- a/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java Fri Sep 20 19:15:59 2013 -0700
@@ -198,7 +198,7 @@
final String propertyName = desc.getNameToken(2);
final String fullName = name.isEmpty() ? propertyName : name + "." + propertyName;
- final Context context = getContext();
+ final Context context = Context.getContextTrusted();
Class<?> javaClass = null;
try {
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java Fri Sep 20 19:15:59 2013 -0700
@@ -33,17 +33,42 @@
*
*/
final class ScriptLoader extends NashornLoader {
+ private static final String NASHORN_PKG_PREFIX = "jdk.nashorn.internal.";
+
+ private final Context context;
+
+ /*package-private*/ Context getContext() {
+ return context;
+ }
+
/**
* Constructor.
*/
- ScriptLoader(final StructureLoader parent, final Context context) {
- super(parent, context);
+ ScriptLoader(final ClassLoader parent, final Context context) {
+ super(parent);
+ this.context = context;
}
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
checkPackageAccess(name);
- return super.loadClassTrusted(name, resolve);
+ try {
+ return super.loadClass(name, resolve);
+ } catch (final ClassNotFoundException | SecurityException e) {
+ // We'll get ClassNotFoundException for Nashorn 'struct' classes.
+ // Also, we'll get SecurityException for jdk.nashorn.internal.*
+ // classes. So, load these using to context's 'shared' loader.
+ // All these classes start with "jdk.nashorn.internal." prefix.
+ try {
+ if (name.startsWith(NASHORN_PKG_PREFIX)) {
+ return context.getSharedLoader().loadClass(name);
+ }
+ } catch (final ClassNotFoundException ignored) {
+ }
+
+ // throw the original exception from here
+ throw e;
+ }
}
// package-private and private stuff below this point
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Sep 20 19:15:59 2013 -0700
@@ -87,6 +87,8 @@
*/
public abstract class ScriptObject extends PropertyListenerManager implements PropertyAccess {
+ /** __proto__ special property name */
+ public static final String PROTO_PROPERTY_NAME = "__proto__";
/** Search fall back routine name for "no such method" */
static final String NO_SUCH_METHOD_NAME = "__noSuchMethod__";
@@ -118,9 +120,6 @@
/** objects proto. */
private ScriptObject proto;
- /** Context of the object, lazily cached. */
- private Context context;
-
/** Object flags. */
private int flags;
@@ -130,6 +129,9 @@
/** Indexed array data. */
private ArrayData arrayData;
+ static final MethodHandle GETPROTO = findOwnMH("getProto", ScriptObject.class);
+ static final MethodHandle SETPROTOCHECK = findOwnMH("setProtoCheck", void.class, Object.class);
+
static final MethodHandle SETFIELD = findOwnMH("setField", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class);
static final MethodHandle SETSPILL = findOwnMH("setSpill", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
static final MethodHandle SETSPILLWITHNEW = findOwnMH("setSpillWithNew", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
@@ -150,6 +152,9 @@
/** Method handle for setting the proto of a ScriptObject */
public static final Call SET_PROTO = virtualCallNoLookup(ScriptObject.class, "setProto", void.class, ScriptObject.class);
+ /** Method handle for setting the proto of a ScriptObject after checking argument */
+ public static final Call SET_PROTO_CHECK = virtualCallNoLookup(ScriptObject.class, "setProtoCheck", void.class, Object.class);
+
/** Method handle for setting the user accessors of a ScriptObject */
public static final Call SET_USER_ACCESSORS = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setUserAccessors", void.class, String.class, ScriptFunction.class, ScriptFunction.class);
@@ -1035,40 +1040,11 @@
}
/**
- * Return true if the script object context is strict
- * @return true if strict context
- */
- public final boolean isStrictContext() {
- return getContext()._strict;
- }
-
- /**
- * Checks if this object belongs to the given context
- * @param ctx context to check against
- * @return true if this object belongs to the given context
- */
- public final boolean isOfContext(final Context ctx) {
- return context == ctx;
- }
-
- /**
* Return the current context from the object's map.
* @return Current context.
*/
- protected final Context getContext() {
- if (context == null) {
- context = Context.fromClass(getClass());
- }
- return context;
- }
-
- /**
- * Set the current context.
- * @param ctx context instance to set
- */
- protected final void setContext(final Context ctx) {
- ctx.getClass();
- this.context = ctx;
+ protected Context getContext() {
+ return Context.fromClass(getClass());
}
/**
@@ -1474,9 +1450,10 @@
/**
* Clears the properties from a ScriptObject
* (java.util.Map-like method to help ScriptObjectMirror implementation)
+ *
+ * @param strict strict mode or not
*/
- public void clear() {
- final boolean strict = isStrictContext();
+ public void clear(final boolean strict) {
final Iterator<String> iter = propertyIterator();
while (iter.hasNext()) {
delete(iter.next(), strict);
@@ -1560,11 +1537,12 @@
*
* @param key property key
* @param value property value
+ * @param strict strict mode or not
* @return oldValue if property with same key existed already
*/
- public Object put(final Object key, final Object value) {
+ public Object put(final Object key, final Object value, final boolean strict) {
final Object oldValue = get(key);
- set(key, value, isStrictContext());
+ set(key, value, strict);
return oldValue;
}
@@ -1574,9 +1552,9 @@
* (java.util.Map-like method to help ScriptObjectMirror implementation)
*
* @param otherMap a {@literal <key,value>} map of properties to add
+ * @param strict strict mode or not
*/
- public void putAll(final Map<?, ?> otherMap) {
- final boolean strict = isStrictContext();
+ public void putAll(final Map<?, ?> otherMap, final boolean strict) {
for (final Map.Entry<?, ?> entry : otherMap.entrySet()) {
set(entry.getKey(), entry.getValue(), strict);
}
@@ -1587,26 +1565,16 @@
* (java.util.Map-like method to help ScriptObjectMirror implementation)
*
* @param key the key of the property
+ * @param strict strict mode or not
* @return the oldValue of the removed property
*/
- public Object remove(final Object key) {
+ public Object remove(final Object key, final boolean strict) {
final Object oldValue = get(key);
- delete(key, isStrictContext());
+ delete(key, strict);
return oldValue;
}
/**
- * Delete a property from the ScriptObject.
- * (to help ScriptObjectMirror implementation)
- *
- * @param key the key of the property
- * @return if the delete was successful or not
- */
- public boolean delete(final Object key) {
- return delete(key, isStrictContext());
- }
-
- /**
* Return the size of the ScriptObject - i.e. the number of properties
* it contains
* (java.util.Map-like method to help ScriptObjectMirror implementation)
@@ -1745,6 +1713,10 @@
MethodHandle methodHandle;
if (find == null) {
+ if (PROTO_PROPERTY_NAME.equals(name)) {
+ return new GuardedInvocation(GETPROTO, NashornGuards.getScriptObjectGuard());
+ }
+
if ("getProp".equals(operator)) {
return noSuchProperty(desc, request);
} else if ("getMethod".equals(operator)) {
@@ -1851,6 +1823,7 @@
* toString = function() { print("global toString"); } // don't affect Object.prototype.toString
*/
FindProperty find = findProperty(name, true, scope, this);
+
// If it's not a scope search, then we don't want any inherited properties except those with user defined accessors.
if (!scope && find != null && find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) {
// We should still check if inherited data property is not writable
@@ -1866,9 +1839,12 @@
// Existing, non-writable property
return createEmptySetMethod(desc, "property.not.writable", true);
}
- } else if (!isExtensible()) {
- // Non-existing property on a non-extensible object
- return createEmptySetMethod(desc, "object.non.extensible", false);
+ } else {
+ if (PROTO_PROPERTY_NAME.equals(name)) {
+ return new GuardedInvocation(SETPROTOCHECK, NashornGuards.getScriptObjectGuard());
+ } else if (! isExtensible()) {
+ return createEmptySetMethod(desc, "object.non.extensible", false);
+ }
}
return new SetMethodCreator(this, find, desc).createGuardedInvocation();
@@ -2317,11 +2293,9 @@
return;
}
- final boolean isStrict = isStrictContext();
-
if (newLength > arrayLength) {
setArray(getArray().ensure(newLength - 1));
- if (getArray().canDelete(arrayLength, (newLength - 1), isStrict)) {
+ if (getArray().canDelete(arrayLength, (newLength - 1), false)) {
setArray(getArray().delete(arrayLength, (newLength - 1)));
}
return;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObjectListAdapter.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 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 jdk.nashorn.internal.runtime;
+
+/**
+ * A ListAdapter that can wrap a ScriptObject.
+ */
+public final class ScriptObjectListAdapter extends ListAdapter {
+ /**
+ * Creates a new list wrapper for the specified ScriptObject.
+ * @param obj script the object to wrap
+ */
+ public ScriptObjectListAdapter(final ScriptObject obj) {
+ super(obj);
+ }
+
+ @Override
+ public int size() {
+ return JSType.toInt32(((ScriptObject)obj).getLength());
+ }
+
+ @Override
+ protected Object getAt(int index) {
+ return ((ScriptObject)obj).get(index);
+ }
+
+ @Override
+ protected void setAt(int index, Object element) {
+ ((ScriptObject)obj).set(index, element, false);
+ }
+}
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Fri Sep 20 19:15:59 2013 -0700
@@ -43,6 +43,7 @@
import java.util.NoSuchElementException;
import java.util.Objects;
import jdk.internal.dynalink.beans.StaticClass;
+import jdk.nashorn.api.scripting.JSObject;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
import jdk.nashorn.internal.ir.debug.JSONWriter;
@@ -190,8 +191,8 @@
case FUNCTION:
if (self instanceof ScriptObject) {
className = ((ScriptObject)self).getClassName();
- } else if (self instanceof ScriptObjectMirror) {
- className = ((ScriptObjectMirror)self).getClassName();
+ } else if (self instanceof JSObject) {
+ className = ((JSObject)self).getClassName();
} else {
className = self.getClass().getName();
}
@@ -245,8 +246,8 @@
return new RangeIterator(Array.getLength(obj));
}
- if (obj instanceof ScriptObjectMirror) {
- return ((ScriptObjectMirror)obj).keySet().iterator();
+ if (obj instanceof JSObject) {
+ return ((JSObject)obj).keySet().iterator();
}
if (obj instanceof List) {
@@ -323,8 +324,8 @@
};
}
- if (obj instanceof ScriptObjectMirror) {
- return ((ScriptObjectMirror)obj).values().iterator();
+ if (obj instanceof JSObject) {
+ return ((JSObject)obj).values().iterator();
}
if (obj instanceof Map) {
@@ -352,35 +353,6 @@
}
/**
- * Check that the target function is associated with current Context. And also make sure that 'self', if
- * ScriptObject, is from current context.
- *
- * Call a function given self and args. If the number of the arguments is known in advance, you can likely achieve
- * better performance by {@link Bootstrap#createDynamicInvoker(String, Class, Class...) creating a dynamic invoker}
- * for operation {@code "dyn:call"}, then using its {@link MethodHandle#invokeExact(Object...)} method instead.
- *
- * @param target ScriptFunction object.
- * @param self Receiver in call.
- * @param args Call arguments.
- * @return Call result.
- */
- public static Object checkAndApply(final ScriptFunction target, final Object self, final Object... args) {
- final ScriptObject global = Context.getGlobalTrusted();
- assert (global instanceof GlobalObject): "No current global set";
-
- if (target.getContext() != global.getContext()) {
- throw new IllegalArgumentException("'target' function is not from current Context");
- }
-
- if (self instanceof ScriptObject && ((ScriptObject)self).getContext() != global.getContext()) {
- throw new IllegalArgumentException("'self' object is not from current Context");
- }
-
- // all in order - call real 'apply'
- return apply(target, self, args);
- }
-
- /**
* Call a function given self and args. If the number of the arguments is known in advance, you can likely achieve
* better performance by {@link Bootstrap#createDynamicInvoker(String, Class, Class...) creating a dynamic invoker}
* for operation {@code "dyn:call"}, then using its {@link MethodHandle#invokeExact(Object...)} method instead.
@@ -401,28 +373,6 @@
}
/**
- * Check that the target function is associated with current Context.
- * And also make sure that 'self', if ScriptObject, is from current context.
- *
- * Call a function as a constructor given args.
- *
- * @param target ScriptFunction object.
- * @param args Call arguments.
- * @return Constructor call result.
- */
- public static Object checkAndConstruct(final ScriptFunction target, final Object... args) {
- final ScriptObject global = Context.getGlobalTrusted();
- assert (global instanceof GlobalObject): "No current global set";
-
- if (target.getContext() != global.getContext()) {
- throw new IllegalArgumentException("'target' function is not from current Context");
- }
-
- // all in order - call real 'construct'
- return construct(target, args);
- }
-
- /**
* Call a script function as a constructor with given args.
*
* @param target ScriptFunction object.
@@ -520,9 +470,12 @@
throw typeError(global, "cant.apply.with.to.null");
}
- final ScriptObject withObject = new WithObject(scope, JSType.toScriptObject(global, expression));
+ final Object wrappedExpr = JSType.toScriptObject(global, expression);
+ if (wrappedExpr instanceof ScriptObject) {
+ return new WithObject(scope, (ScriptObject)wrappedExpr);
+ }
- return withObject;
+ throw typeError(global, "cant.apply.with.to.non.scriptobject");
}
/**
@@ -534,7 +487,7 @@
*/
public static ScriptObject closeWith(final ScriptObject scope) {
if (scope instanceof WithObject) {
- return scope.getProto();
+ return ((WithObject)scope).getParentScope();
}
return scope;
}
@@ -619,8 +572,8 @@
throw typeError("cant.get.property", safeToString(property), "null");
} else if (JSType.isPrimitive(obj)) {
obj = ((ScriptObject)JSType.toScriptObject(obj)).get(property);
- } else if (obj instanceof ScriptObjectMirror) {
- obj = ((ScriptObjectMirror)obj).getMember(property.toString());
+ } else if (obj instanceof JSObject) {
+ obj = ((JSObject)obj).getMember(property.toString());
} else {
obj = UNDEFINED;
}
@@ -672,6 +625,11 @@
return ((ScriptObject) JSType.toScriptObject(obj)).delete(property, Boolean.TRUE.equals(strict));
}
+ if (obj instanceof JSObject) {
+ ((JSObject)obj).removeMember(Objects.toString(property));
+ return true;
+ }
+
// if object is not reference type, vacuously delete is successful.
return true;
}
@@ -863,6 +821,10 @@
return ((ScriptObject)obj).has(property);
}
+ if (obj instanceof JSObject) {
+ return ((JSObject)obj).hasMember(Objects.toString(property));
+ }
+
return false;
}
@@ -889,11 +851,13 @@
return ((StaticClass)clazz).getRepresentedClass().isInstance(obj);
}
- if (clazz instanceof ScriptObjectMirror) {
- if (obj instanceof ScriptObjectMirror) {
- return ((ScriptObjectMirror)clazz).isInstance((ScriptObjectMirror)obj);
- }
- return false;
+ if (clazz instanceof JSObject) {
+ return ((JSObject)clazz).isInstance(obj);
+ }
+
+ // provide for reverse hook
+ if (obj instanceof JSObject) {
+ return ((JSObject)obj).isInstanceOf(clazz);
}
throw typeError("instanceof.on.non.object");
--- a/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java Fri Sep 20 19:15:59 2013 -0700
@@ -34,7 +34,6 @@
/**
* Responsible for on the fly construction of structure classes.
- *
*/
final class StructureLoader extends NashornLoader {
private static final String JS_OBJECT_PREFIX_EXTERNAL = binaryName(SCRIPTS_PACKAGE) + '.' + JS_OBJECT_PREFIX.symbolName();
@@ -42,27 +41,17 @@
/**
* Constructor.
*/
- StructureLoader(final ClassLoader parent, final Context context) {
- super(parent, context);
+ StructureLoader(final ClassLoader parent) {
+ super(parent);
}
- @Override
- protected synchronized Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
- // check the cache first
- final Class<?> loadedClass = findLoadedClass(name);
- if (loadedClass != null) {
- if (resolve) {
- resolveClass(loadedClass);
- }
- return loadedClass;
- }
-
- return super.loadClassTrusted(name, resolve);
+ static boolean isStructureClass(final String name) {
+ return name.startsWith(JS_OBJECT_PREFIX_EXTERNAL);
}
@Override
protected Class<?> findClass(final String name) throws ClassNotFoundException {
- if (name.startsWith(JS_OBJECT_PREFIX_EXTERNAL)) {
+ if (isStructureClass(name)) {
return generateClass(name, name.substring(JS_OBJECT_PREFIX_EXTERNAL.length()));
}
return super.findClass(name);
@@ -75,11 +64,7 @@
* @return Generated class.
*/
private Class<?> generateClass(final String name, final String descriptor) {
- Context context = getContext();
-
- if (context == null) {
- context = Context.getContextTrusted();
- }
+ final Context context = Context.getContextTrusted();
final byte[] code = new ObjectClassGenerator(context).generate(descriptor);
return defineClass(name, code, 0, code.length, new ProtectionDomain(null, getPermissions(null)));
--- a/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java Fri Sep 20 19:15:59 2013 -0700
@@ -30,26 +30,26 @@
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
+import java.lang.invoke.SwitchPoint;
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
-
/**
* This class supports the handling of scope in a with body.
*
*/
public final class WithObject extends ScriptObject implements Scope {
-
+ private static final MethodHandle WITHEXPRESSIONGUARD = findOwnMH("withExpressionGuard", boolean.class, Object.class, PropertyMap.class, SwitchPoint.class);
private static final MethodHandle WITHEXPRESSIONFILTER = findOwnMH("withFilterExpression", Object.class, Object.class);
private static final MethodHandle WITHSCOPEFILTER = findOwnMH("withFilterScope", Object.class, Object.class);
private static final MethodHandle BIND_TO_EXPRESSION_OBJ = findOwnMH("bindToExpression", Object.class, Object.class, Object.class);
private static final MethodHandle BIND_TO_EXPRESSION_FN = findOwnMH("bindToExpression", Object.class, ScriptFunction.class, Object.class);
/** With expression object. */
- private final Object expression;
+ private final ScriptObject expression;
/**
* Constructor
@@ -57,12 +57,13 @@
* @param scope scope object
* @param expression with expression
*/
- WithObject(final ScriptObject scope, final Object expression) {
+ WithObject(final ScriptObject scope, final ScriptObject expression) {
super(scope, null);
setIsScope();
this.expression = expression;
}
+
/**
* Delete a property based on a key.
* @param key Any valid JavaScript value.
@@ -71,15 +72,13 @@
*/
@Override
public boolean delete(final Object key, final boolean strict) {
- if (expression instanceof ScriptObject) {
- final ScriptObject self = (ScriptObject)expression;
- final String propName = JSType.toString(key);
+ final ScriptObject self = expression;
+ final String propName = JSType.toString(key);
- final FindProperty find = self.findProperty(propName, true);
+ final FindProperty find = self.findProperty(propName, true);
- if (find != null) {
- return self.delete(propName, strict);
- }
+ if (find != null) {
+ return self.delete(propName, strict);
}
return false;
@@ -105,18 +104,16 @@
name = null;
}
- if (expression instanceof ScriptObject) {
- self = (ScriptObject)expression;
- if (isNamedOperation) {
- find = self.findProperty(name, true);
- }
+ self = expression;
+ if (isNamedOperation) {
+ find = self.findProperty(name, true);
+ }
- if (find != null) {
- link = self.lookup(desc, request);
+ if (find != null) {
+ link = self.lookup(desc, request);
- if (link != null) {
- return fixExpressionCallSite(ndesc, link);
- }
+ if (link != null) {
+ return fixExpressionCallSite(ndesc, link);
}
}
@@ -126,7 +123,7 @@
}
if (find != null) {
- return fixScopeCallSite(scope.lookup(desc, request));
+ return fixScopeCallSite(scope.lookup(desc, request), name);
}
// the property is not found - now check for
@@ -178,7 +175,7 @@
link = scope.lookup(desc, request);
if (link != null) {
- return fixScopeCallSite(link);
+ return fixScopeCallSite(link, name);
}
return null;
@@ -197,11 +194,9 @@
*/
@Override
FindProperty findProperty(final String key, final boolean deep, final boolean stopOnNonScope, final ScriptObject start) {
- if (expression instanceof ScriptObject) {
- final FindProperty exprProperty = ((ScriptObject)expression).findProperty(key, deep, stopOnNonScope, start);
- if(exprProperty != null) {
- return exprProperty;
- }
+ final FindProperty exprProperty = expression.findProperty(key, deep, stopOnNonScope, start);
+ if (exprProperty != null) {
+ return exprProperty;
}
return super.findProperty(key, deep, stopOnNonScope, start);
}
@@ -220,16 +215,17 @@
* Get first parent scope that is not an instance of WithObject.
*/
private Scope getNonWithParent() {
- ScriptObject proto = getProto();
+ ScriptObject proto = getParentScope();
while (proto != null && proto instanceof WithObject) {
- proto = proto.getProto();
+ proto = ((WithObject)proto).getParentScope();
}
assert proto instanceof Scope : "with scope without parent scope";
return (Scope) proto;
}
+
private static GuardedInvocation fixReceiverType(final GuardedInvocation link, final MethodHandle filter) {
// The receiver may be an Object or a ScriptObject.
final MethodType invType = link.getInvocation().type();
@@ -256,9 +252,13 @@
filterGuard(link, WITHEXPRESSIONFILTER));
}
- private static GuardedInvocation fixScopeCallSite(final GuardedInvocation link) {
+ private GuardedInvocation fixScopeCallSite(final GuardedInvocation link, final String name) {
final GuardedInvocation newLink = fixReceiverType(link, WITHSCOPEFILTER);
- return link.replaceMethods(filter(newLink.getInvocation(), WITHSCOPEFILTER), filterGuard(newLink, WITHSCOPEFILTER));
+ return link.replaceMethods(filter(newLink.getInvocation(), WITHSCOPEFILTER),
+ MH.guardWithTest(
+ expressionGuard(name),
+ filterGuard(newLink, WITHSCOPEFILTER),
+ MH.dropArguments(MH.constant(boolean.class, false), 0, Object.class)));
}
private static MethodHandle filterGuard(final GuardedInvocation link, final MethodHandle filter) {
@@ -279,7 +279,6 @@
return ((WithObject)receiver).expression;
}
-
@SuppressWarnings("unused")
private static Object bindToExpression(final Object fn, final Object receiver) {
return fn instanceof ScriptFunction ? bindToExpression((ScriptFunction) fn, receiver) : fn;
@@ -289,6 +288,17 @@
return fn.makeBoundFunction(withFilterExpression(receiver), new Object[0]);
}
+ private MethodHandle expressionGuard(final String name) {
+ final PropertyMap map = expression.getMap();
+ final SwitchPoint sp = map.getProtoGetSwitchPoint(expression.getProto(), name);
+ return MH.insertArguments(WITHEXPRESSIONGUARD, 1, map, sp);
+ }
+
+ @SuppressWarnings("unused")
+ private static boolean withExpressionGuard(final Object receiver, final PropertyMap map, final SwitchPoint sp) {
+ return ((WithObject)receiver).expression.getMap() == map && (sp == null || !sp.hasBeenInvalidated());
+ }
+
/**
* Drops the WithObject wrapper from the scope.
* @param receiver WithObject wrapper.
@@ -302,10 +312,14 @@
* Get the with expression for this {@code WithObject}
* @return the with expression
*/
- public Object getExpression() {
+ public ScriptObject getExpression() {
return expression;
}
+ public ScriptObject getParentScope() {
+ return getProto();
+ }
+
private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
return MH.findStatic(MethodHandles.lookup(), WithObject.class, name, MH.type(rtype, types));
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java Fri Sep 20 19:15:59 2013 -0700
@@ -26,10 +26,9 @@
package jdk.nashorn.internal.runtime.arrays;
import java.lang.invoke.MethodHandle;
-import java.lang.reflect.Array;
import jdk.nashorn.internal.runtime.GlobalObject;
+import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.PropertyDescriptor;
-import jdk.nashorn.internal.runtime.linker.Bootstrap;
/**
* ArrayData - abstraction for wrapping array elements
@@ -204,20 +203,7 @@
* @return and array of the given type
*/
public Object asArrayOfType(final Class<?> componentType) {
- final Object[] src = asObjectArray();
- final int l = src.length;
- final Object dst = Array.newInstance(componentType, l);
- final MethodHandle converter = Bootstrap.getLinkerServices().getTypeConverter(Object.class, componentType);
- try {
- for (int i = 0; i < src.length; i++) {
- Array.set(dst, i, invoke(converter, src[i]));
- }
- } catch (final RuntimeException | Error e) {
- throw e;
- } catch (final Throwable t) {
- throw new RuntimeException(t);
- }
- return dst;
+ return JSType.convertArray(asObjectArray(), componentType);
}
/**
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java Fri Sep 20 19:15:59 2013 -0700
@@ -27,7 +27,7 @@
import java.util.Iterator;
import java.util.List;
-import jdk.nashorn.api.scripting.ScriptObjectMirror;
+import jdk.nashorn.api.scripting.JSObject;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptObject;
@@ -127,8 +127,8 @@
return new ScriptObjectIterator((ScriptObject)obj, includeUndefined);
}
- if (obj instanceof ScriptObjectMirror) {
- return new ScriptObjectMirrorIterator((ScriptObjectMirror)obj, includeUndefined);
+ if (obj instanceof JSObject) {
+ return new JSObjectIterator((JSObject)obj, includeUndefined);
}
if (obj instanceof List) {
@@ -160,8 +160,8 @@
return new ReverseScriptObjectIterator((ScriptObject)obj, includeUndefined);
}
- if (obj instanceof ScriptObjectMirror) {
- return new ReverseScriptObjectMirrorIterator((ScriptObjectMirror)obj, includeUndefined);
+ if (obj instanceof JSObject) {
+ return new ReverseJSObjectIterator((JSObject)obj, includeUndefined);
}
if (obj instanceof List) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java Fri Sep 20 19:15:59 2013 -0700
@@ -27,7 +27,7 @@
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
-import jdk.nashorn.api.scripting.ScriptObjectMirror;
+import jdk.nashorn.api.scripting.JSObject;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptRuntime;
@@ -101,9 +101,9 @@
final boolean strict;
if (callbackfn instanceof ScriptFunction) {
strict = ((ScriptFunction)callbackfn).isStrict();
- } else if (callbackfn instanceof ScriptObjectMirror &&
- ((ScriptObjectMirror)callbackfn).isFunction()) {
- strict = ((ScriptObjectMirror)callbackfn).isStrictFunction();
+ } else if (callbackfn instanceof JSObject &&
+ ((JSObject)callbackfn).isFunction()) {
+ strict = ((JSObject)callbackfn).isStrictFunction();
} else if (Bootstrap.isDynamicMethod(callbackfn) || Bootstrap.isFunctionalInterfaceObject(callbackfn)) {
strict = false;
} else {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/JSObjectIterator.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2010, 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 jdk.nashorn.internal.runtime.arrays;
+
+import java.util.NoSuchElementException;
+import jdk.nashorn.api.scripting.JSObject;
+import jdk.nashorn.internal.runtime.JSType;
+
+/**
+ * Iterator over a ScriptObjectMirror
+ */
+class JSObjectIterator extends ArrayLikeIterator<Object> {
+
+ protected final JSObject obj;
+ private final long length;
+
+ JSObjectIterator(final JSObject obj, final boolean includeUndefined) {
+ super(includeUndefined);
+ this.obj = obj;
+ this.length = JSType.toUint32(obj.hasMember("length")? obj.getMember("length") : 0);
+ this.index = 0;
+ }
+
+ protected boolean indexInArray() {
+ return index < length;
+ }
+
+ @Override
+ public long getLength() {
+ return length;
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (length == 0L) {
+ return false; //return empty string if toUint32(length) == 0
+ }
+
+ while (indexInArray()) {
+ if (obj.hasSlot((int)index) || includeUndefined) {
+ break;
+ }
+ bumpIndex();
+ }
+
+ return indexInArray();
+ }
+
+ @Override
+ public Object next() {
+ if (indexInArray()) {
+ return obj.getSlot((int)bumpIndex());
+ }
+
+ throw new NoSuchElementException();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseJSObjectIterator.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2010, 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 jdk.nashorn.internal.runtime.arrays;
+
+import jdk.nashorn.api.scripting.JSObject;
+import jdk.nashorn.internal.runtime.JSType;
+
+/**
+ * Reverse iterator over a ScriptObjectMirror
+ */
+final class ReverseJSObjectIterator extends JSObjectIterator {
+
+ ReverseJSObjectIterator(final JSObject obj, final boolean includeUndefined) {
+ super(obj, includeUndefined);
+ this.index = JSType.toUint32(obj.hasMember("length")? obj.getMember("length") : 0) - 1;
+ }
+
+ @Override
+ public boolean isReverse() {
+ return true;
+ }
+
+ @Override
+ protected boolean indexInArray() {
+ return index >= 0;
+ }
+
+ @Override
+ protected long bumpIndex() {
+ return index--;
+ }
+}
+
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseScriptObjectMirrorIterator.java Fri Sep 20 17:11:32 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2010, 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 jdk.nashorn.internal.runtime.arrays;
-
-import jdk.nashorn.api.scripting.ScriptObjectMirror;
-import jdk.nashorn.internal.runtime.JSType;
-
-/**
- * Reverse iterator over a ScriptObjectMirror
- */
-final class ReverseScriptObjectMirrorIterator extends ScriptObjectMirrorIterator {
-
- ReverseScriptObjectMirrorIterator(final ScriptObjectMirror obj, final boolean includeUndefined) {
- super(obj, includeUndefined);
- this.index = JSType.toUint32(obj.containsKey("length")? obj.getMember("length") : 0) - 1;
- }
-
- @Override
- public boolean isReverse() {
- return true;
- }
-
- @Override
- protected boolean indexInArray() {
- return index >= 0;
- }
-
- @Override
- protected long bumpIndex() {
- return index--;
- }
-}
-
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ScriptObjectMirrorIterator.java Fri Sep 20 17:11:32 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2010, 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 jdk.nashorn.internal.runtime.arrays;
-
-import java.util.NoSuchElementException;
-import jdk.nashorn.api.scripting.ScriptObjectMirror;
-import jdk.nashorn.internal.runtime.JSType;
-
-/**
- * Iterator over a ScriptObjectMirror
- */
-class ScriptObjectMirrorIterator extends ArrayLikeIterator<Object> {
-
- protected final ScriptObjectMirror obj;
- private final long length;
-
- ScriptObjectMirrorIterator(final ScriptObjectMirror obj, final boolean includeUndefined) {
- super(includeUndefined);
- this.obj = obj;
- this.length = JSType.toUint32(obj.containsKey("length")? obj.getMember("length") : 0);
- this.index = 0;
- }
-
- protected boolean indexInArray() {
- return index < length;
- }
-
- @Override
- public long getLength() {
- return length;
- }
-
- @Override
- public boolean hasNext() {
- if (length == 0L) {
- return false; //return empty string if toUint32(length) == 0
- }
-
- while (indexInArray()) {
- if (obj.containsKey(index) || includeUndefined) {
- break;
- }
- bumpIndex();
- }
-
- return indexInArray();
- }
-
- @Override
- public Object next() {
- if (indexInArray()) {
- return obj.get(bumpIndex());
- }
-
- throw new NoSuchElementException();
- }
-}
-
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java Fri Sep 20 19:15:59 2013 -0700
@@ -39,7 +39,7 @@
import jdk.internal.dynalink.beans.StaticClass;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkerServices;
-import jdk.nashorn.api.scripting.ScriptObjectMirror;
+import jdk.nashorn.api.scripting.JSObject;
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
import jdk.nashorn.internal.codegen.RuntimeCallSite;
import jdk.nashorn.internal.runtime.JSType;
@@ -87,7 +87,7 @@
}
return obj instanceof ScriptFunction ||
- ((obj instanceof ScriptObjectMirror) && ((ScriptObjectMirror)obj).isFunction()) ||
+ ((obj instanceof JSObject) && ((JSObject)obj).isFunction()) ||
isDynamicMethod(obj) ||
isFunctionalInterfaceObject(obj) ||
obj instanceof StaticClass;
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java Fri Sep 20 19:15:59 2013 -0700
@@ -30,7 +30,6 @@
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
-import java.util.Objects;
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
@@ -88,8 +87,9 @@
case "setElem":
return c > 2 ? findSetMethod(desc) : findSetIndexMethod();
case "call":
+ return findCallMethod(desc, operator);
case "callMethod":
- return findCallMethod(desc, operator);
+ return findCallMethodMethod(desc, operator);
case "new":
return findNewMethod(desc);
default:
@@ -98,33 +98,37 @@
}
private static GuardedInvocation findGetMethod(final CallSiteDescriptor desc) {
- final MethodHandle getter = MH.insertArguments(JSOBJECT_GET, 1, desc.getNameToken(2));
+ final MethodHandle getter = MH.insertArguments(JSOBJECT_GETMEMBER, 1, desc.getNameToken(2));
return new GuardedInvocation(getter, null, IS_JSOBJECT_GUARD);
}
private static GuardedInvocation findGetIndexMethod() {
- return new GuardedInvocation(JSOBJECT_GET, null, IS_JSOBJECT_GUARD);
+ return new GuardedInvocation(JSOBJECTLINKER_GET, null, IS_JSOBJECT_GUARD);
}
private static GuardedInvocation findSetMethod(final CallSiteDescriptor desc) {
- final MethodHandle getter = MH.insertArguments(JSOBJECT_PUT, 1, desc.getNameToken(2));
+ final MethodHandle getter = MH.insertArguments(JSOBJECT_SETMEMBER, 1, desc.getNameToken(2));
return new GuardedInvocation(getter, null, IS_JSOBJECT_GUARD);
}
private static GuardedInvocation findSetIndexMethod() {
- return new GuardedInvocation(JSOBJECT_PUT, null, IS_JSOBJECT_GUARD);
+ return new GuardedInvocation(JSOBJECTLINKER_PUT, null, IS_JSOBJECT_GUARD);
}
- private static GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final String operator) {
- // if operator is "call", then 'self' is a JSObject function object already. Use 'call' as the method name
- final String methodName = "callMethod".equals(operator)? desc.getNameToken(2) : "call";
- MethodHandle func = MH.insertArguments(JSOBJECT_CALL, 1, methodName);
+ private static GuardedInvocation findCallMethodMethod(final CallSiteDescriptor desc, final String operator) {
+ final String methodName = desc.getNameToken(2);
+ MethodHandle func = MH.insertArguments(JSOBJECT_CALLMEMBER, 1, methodName);
func = MH.asCollector(func, Object[].class, desc.getMethodType().parameterCount() - 1);
return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD);
}
+ private static GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final String operator) {
+ final MethodHandle func = MH.asCollector(JSOBJECT_CALL, Object[].class, desc.getMethodType().parameterCount() - 2);
+ return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD);
+ }
+
private static GuardedInvocation findNewMethod(final CallSiteDescriptor desc) {
- MethodHandle func = MH.asCollector(JSOBJECT_NEW, Object[].class, desc.getMethodType().parameterCount() - 1);
+ final MethodHandle func = MH.asCollector(JSOBJECT_NEW, Object[].class, desc.getMethodType().parameterCount() - 1);
return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD);
}
@@ -135,36 +139,30 @@
@SuppressWarnings("unused")
private static Object get(final Object jsobj, final Object key) {
- if (key instanceof String) {
- return ((JSObject)jsobj).getMember((String)key);
+ if (key instanceof Integer) {
+ return ((JSObject)jsobj).getSlot((int)(Integer)key);
} else if (key instanceof Number) {
final int index = getIndex((Number)key);
if (index > -1) {
return ((JSObject)jsobj).getSlot(index);
}
+ } else if (key instanceof String) {
+ return ((JSObject)jsobj).getMember((String)key);
}
return null;
}
@SuppressWarnings("unused")
private static void put(final Object jsobj, final Object key, final Object value) {
- if (key instanceof String) {
- ((JSObject)jsobj).setMember((String)key, value);
+ if (key instanceof Integer) {
+ ((JSObject)jsobj).setSlot((int)(Integer)key, value);
} else if (key instanceof Number) {
((JSObject)jsobj).setSlot(getIndex((Number)key), value);
+ } else if (key instanceof String) {
+ ((JSObject)jsobj).setMember((String)key, value);
}
}
- @SuppressWarnings("unused")
- private static Object call(final Object jsobj, final Object method, final Object... args) {
- return ((JSObject)jsobj).call(Objects.toString(method), args);
- }
-
- @SuppressWarnings("unused")
- private static Object newObject(final Object jsobj, final Object... args) {
- return ((JSObject)jsobj).newObject(null, args);
- }
-
private static int getIndex(final Number n) {
final double value = n.doubleValue();
return JSType.isRepresentableAsInt(value) ? (int)value : -1;
@@ -172,11 +170,17 @@
private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality();
- private static final MethodHandle IS_JSOBJECT_GUARD = findOwnMH("isJSObject", boolean.class, Object.class);
- private static final MethodHandle JSOBJECT_GET = findOwnMH("get", Object.class, Object.class, Object.class);
- private static final MethodHandle JSOBJECT_PUT = findOwnMH("put", Void.TYPE, Object.class, Object.class, Object.class);
- private static final MethodHandle JSOBJECT_CALL = findOwnMH("call", Object.class, Object.class, Object.class, Object[].class);
- private static final MethodHandle JSOBJECT_NEW = findOwnMH("newObject", Object.class, Object.class, Object[].class);
+ // method handles of the current class
+ private static final MethodHandle IS_JSOBJECT_GUARD = findOwnMH("isJSObject", boolean.class, Object.class);
+ private static final MethodHandle JSOBJECTLINKER_GET = findOwnMH("get", Object.class, Object.class, Object.class);
+ private static final MethodHandle JSOBJECTLINKER_PUT = findOwnMH("put", Void.TYPE, Object.class, Object.class, Object.class);
+
+ // method handles of JSObject class
+ private static final MethodHandle JSOBJECT_GETMEMBER = findJSObjectMH("getMember", Object.class, String.class);
+ private static final MethodHandle JSOBJECT_SETMEMBER = findJSObjectMH("setMember", Void.TYPE, String.class, Object.class);
+ private static final MethodHandle JSOBJECT_CALLMEMBER = findJSObjectMH("callMember", Object.class, String.class, Object[].class);
+ private static final MethodHandle JSOBJECT_CALL = findJSObjectMH("call", Object.class, Object.class, Object[].class);
+ private static final MethodHandle JSOBJECT_NEW = findJSObjectMH("newObject", Object.class, Object[].class);
private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
final Class<?> own = JSObjectLinker.class;
@@ -187,4 +191,14 @@
return MH.findVirtual(MethodHandles.lookup(), own, name, mt);
}
}
+
+ private static MethodHandle findJSObjectMH(final String name, final Class<?> rtype, final Class<?>... types) {
+ final Class<?> own = JSObject.class;
+ final MethodType mt = MH.type(rtype, types);
+ try {
+ return MH.findVirtual(MethodHandles.publicLookup(), own, name, mt);
+ } catch (final MethodHandleFactory.LookupException e) {
+ return MH.findVirtual(MethodHandles.lookup(), own, name, mt);
+ }
+ }
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java Fri Sep 20 19:15:59 2013 -0700
@@ -263,15 +263,6 @@
}
if (atom()) {
- // Check for character classes that never or always match
- if (sb.toString().endsWith("[]")) {
- sb.setLength(sb.length() - 1);
- sb.append("^\\s\\S]");
- } else if (sb.toString().endsWith("[^]")) {
- sb.setLength(sb.length() - 2);
- sb.append("\\s\\S]");
- }
-
quantifier();
return true;
}
@@ -767,7 +758,18 @@
if (classRanges() && ch0 == ']') {
pop(']');
- return commit(1);
+ commit(1);
+
+ // Substitute empty character classes [] and [^] that never or always match
+ if (position == startIn + 2) {
+ sb.setLength(sb.length() - 1);
+ sb.append("^\\s\\S]");
+ } else if (position == startIn + 3 && inNegativeClass) {
+ sb.setLength(sb.length() - 2);
+ sb.append("\\s\\S]");
+ }
+
+ return true;
}
} finally {
inCharClass = false; // no nested character classes in JavaScript
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties Fri Sep 20 19:15:59 2013 -0700
@@ -110,6 +110,7 @@
type.error.cannot.get.default.number=Cannot get default number value
type.error.cant.apply.with.to.null=Cannot apply "with" to null
type.error.cant.apply.with.to.undefined=Cannot apply "with" to undefined
+type.error.cant.apply.with.to.non.scriptobject=Cannot apply "with" to non script object
type.error.in.with.non.object=Right hand side of "in" cannot be non-Object, found {0}
type.error.prototype.not.an.object="prototype" of {0} is not an Object, it is {1}
type.error.cant.load.script=Cannot load script from {0}
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/base.js Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/base.js Fri Sep 20 19:15:59 2013 -0700
@@ -23,204 +23,126 @@
* questions.
*/
-Scene = Java.type("javafx.scene.Scene");
-Group = Java.type("javafx.scene.Group");
-Stage = Java.type("javafx.stage.Stage");
+var JFX_BASE_CLASSES = [];
+var JFX_GRAPHICS_CLASSES = [];
+var JFX_CONTROLS_CLASSES = [];
+var JFX_FXML_CLASSES = [];
+var JFX_WEB_CLASSES = [];
+var JFX_MEDIA_CLASSES = [];
+var JFX_SWING_CLASSES = [];
+var JFX_SWT_CLASSES = [];
+
+function LOAD_FX_CLASSES(clsList) {
+
+ for each (var cls in clsList) {
+ // Ex. Stage = Java.type("javafx.stage.Stage");
+ this[cls[cls.length - 1]] = Java.type(cls.join("."));
+ }
+}
+
+(function() {
+ var System = Java.type("java.lang.System");
+ var ZipFile = Java.type("java.util.zip.ZipFile");
+
+ var SUFFIX_LENGTH = ".class".length;
+
+ try {
+ var jfxrtJar = new ZipFile(System.getProperty("java.home") + "/lib/ext/jfxrt.jar");
+ } catch (ex) {
+ throw new Error("JavaFX runtime not found");
+ }
+
+ var entries = jfxrtJar.entries();
+
+ while (entries.hasMoreElements()) {
+ var entry = entries.nextElement();
+
+ if (entry.isDirectory()) {
+ continue;
+ }
+
+ var name = entry.name;
+
+ if (!name.endsWith(".class")) {
+ continue;
+ }
+
+ name = name.substring(0, name.length - SUFFIX_LENGTH);
+ cls = name.split("/");
+
+ if (cls[0] != "javafx") {
+ continue;
+ }
+
+ var last = cls[cls.length - 1];
+ var nested = last.lastIndexOf("$");
+
+ // If class name ends with $nnn
+ if (nested != -1 && !(last.substring(nested) - 0)) {
+ continue;
+ }
-Binding = Java.type("javafx.beans.binding.Binding");
-Bindings = Java.type("javafx.beans.binding.Bindings");
-BooleanBinding = Java.type("javafx.beans.binding.BooleanBinding");
-BooleanExpression = Java.type("javafx.beans.binding.BooleanExpression");
-DoubleBinding = Java.type("javafx.beans.binding.DoubleBinding");
-DoubleExpression = Java.type("javafx.beans.binding.DoubleExpression");
-FloatBinding = Java.type("javafx.beans.binding.FloatBinding");
-FloatExpression = Java.type("javafx.beans.binding.FloatExpression");
-IntegerBinding = Java.type("javafx.beans.binding.IntegerBinding");
-IntegerExpression = Java.type("javafx.beans.binding.IntegerExpression");
-ListBinding = Java.type("javafx.beans.binding.ListBinding");
-ListExpression = Java.type("javafx.beans.binding.ListExpression");
-LongBinding = Java.type("javafx.beans.binding.LongBinding");
-LongExpression = Java.type("javafx.beans.binding.LongExpression");
-MapBinding = Java.type("javafx.beans.binding.MapBinding");
-MapExpression = Java.type("javafx.beans.binding.MapExpression");
-NumberBinding = Java.type("javafx.beans.binding.NumberBinding");
-NumberExpression = Java.type("javafx.beans.binding.NumberExpression");
-NumberExpressionBase = Java.type("javafx.beans.binding.NumberExpressionBase");
-ObjectBinding = Java.type("javafx.beans.binding.ObjectBinding");
-ObjectExpression = Java.type("javafx.beans.binding.ObjectExpression");
-SetBinding = Java.type("javafx.beans.binding.SetBinding");
-SetExpression = Java.type("javafx.beans.binding.SetExpression");
-StringBinding = Java.type("javafx.beans.binding.StringBinding");
-StringExpression = Java.type("javafx.beans.binding.StringExpression");
-When = Java.type("javafx.beans.binding.When");
-DefaultProperty = Java.type("javafx.beans.DefaultProperty");
-InvalidationListener = Java.type("javafx.beans.InvalidationListener");
-Observable = Java.type("javafx.beans.Observable");
-JavaBeanBooleanProperty = Java.type("javafx.beans.property.adapter.JavaBeanBooleanProperty");
-JavaBeanBooleanPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanBooleanPropertyBuilder");
-JavaBeanDoubleProperty = Java.type("javafx.beans.property.adapter.JavaBeanDoubleProperty");
-JavaBeanDoublePropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanDoublePropertyBuilder");
-JavaBeanFloatProperty = Java.type("javafx.beans.property.adapter.JavaBeanFloatProperty");
-JavaBeanFloatPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanFloatPropertyBuilder");
-JavaBeanIntegerProperty = Java.type("javafx.beans.property.adapter.JavaBeanIntegerProperty");
-JavaBeanIntegerPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanIntegerPropertyBuilder");
-JavaBeanLongProperty = Java.type("javafx.beans.property.adapter.JavaBeanLongProperty");
-JavaBeanLongPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanLongPropertyBuilder");
-JavaBeanObjectProperty = Java.type("javafx.beans.property.adapter.JavaBeanObjectProperty");
-JavaBeanObjectPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanObjectPropertyBuilder");
-JavaBeanProperty = Java.type("javafx.beans.property.adapter.JavaBeanProperty");
-JavaBeanStringProperty = Java.type("javafx.beans.property.adapter.JavaBeanStringProperty");
-JavaBeanStringPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanStringPropertyBuilder");
-ReadOnlyJavaBeanBooleanProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanBooleanProperty");
-ReadOnlyJavaBeanBooleanPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanBooleanPropertyBuilder");
-ReadOnlyJavaBeanDoubleProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanDoubleProperty");
-ReadOnlyJavaBeanDoublePropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanDoublePropertyBuilder");
-ReadOnlyJavaBeanFloatProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanFloatProperty");
-ReadOnlyJavaBeanFloatPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanFloatPropertyBuilder");
-ReadOnlyJavaBeanIntegerProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanIntegerProperty");
-ReadOnlyJavaBeanIntegerPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanIntegerPropertyBuilder");
-ReadOnlyJavaBeanLongProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanLongProperty");
-ReadOnlyJavaBeanLongPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanLongPropertyBuilder");
-ReadOnlyJavaBeanObjectProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanObjectProperty");
-ReadOnlyJavaBeanObjectPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanObjectPropertyBuilder");
-ReadOnlyJavaBeanProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanProperty");
-ReadOnlyJavaBeanStringProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanStringProperty");
-ReadOnlyJavaBeanStringPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanStringPropertyBuilder");
-BooleanProperty = Java.type("javafx.beans.property.BooleanProperty");
-BooleanPropertyBase = Java.type("javafx.beans.property.BooleanPropertyBase");
-DoubleProperty = Java.type("javafx.beans.property.DoubleProperty");
-DoublePropertyBase = Java.type("javafx.beans.property.DoublePropertyBase");
-FloatProperty = Java.type("javafx.beans.property.FloatProperty");
-FloatPropertyBase = Java.type("javafx.beans.property.FloatPropertyBase");
-IntegerProperty = Java.type("javafx.beans.property.IntegerProperty");
-IntegerPropertyBase = Java.type("javafx.beans.property.IntegerPropertyBase");
-ListProperty = Java.type("javafx.beans.property.ListProperty");
-ListPropertyBase = Java.type("javafx.beans.property.ListPropertyBase");
-LongProperty = Java.type("javafx.beans.property.LongProperty");
-LongPropertyBase = Java.type("javafx.beans.property.LongPropertyBase");
-MapProperty = Java.type("javafx.beans.property.MapProperty");
-MapPropertyBase = Java.type("javafx.beans.property.MapPropertyBase");
-ObjectProperty = Java.type("javafx.beans.property.ObjectProperty");
-ObjectPropertyBase = Java.type("javafx.beans.property.ObjectPropertyBase");
-Property = Java.type("javafx.beans.property.Property");
-ReadOnlyBooleanProperty = Java.type("javafx.beans.property.ReadOnlyBooleanProperty");
-ReadOnlyBooleanPropertyBase = Java.type("javafx.beans.property.ReadOnlyBooleanPropertyBase");
-ReadOnlyBooleanWrapper = Java.type("javafx.beans.property.ReadOnlyBooleanWrapper");
-ReadOnlyDoubleProperty = Java.type("javafx.beans.property.ReadOnlyDoubleProperty");
-ReadOnlyDoublePropertyBase = Java.type("javafx.beans.property.ReadOnlyDoublePropertyBase");
-ReadOnlyDoubleWrapper = Java.type("javafx.beans.property.ReadOnlyDoubleWrapper");
-ReadOnlyFloatProperty = Java.type("javafx.beans.property.ReadOnlyFloatProperty");
-ReadOnlyFloatPropertyBase = Java.type("javafx.beans.property.ReadOnlyFloatPropertyBase");
-ReadOnlyFloatWrapper = Java.type("javafx.beans.property.ReadOnlyFloatWrapper");
-ReadOnlyIntegerProperty = Java.type("javafx.beans.property.ReadOnlyIntegerProperty");
-ReadOnlyIntegerPropertyBase = Java.type("javafx.beans.property.ReadOnlyIntegerPropertyBase");
-ReadOnlyIntegerWrapper = Java.type("javafx.beans.property.ReadOnlyIntegerWrapper");
-ReadOnlyListProperty = Java.type("javafx.beans.property.ReadOnlyListProperty");
-ReadOnlyListPropertyBase = Java.type("javafx.beans.property.ReadOnlyListPropertyBase");
-ReadOnlyListWrapper = Java.type("javafx.beans.property.ReadOnlyListWrapper");
-ReadOnlyLongProperty = Java.type("javafx.beans.property.ReadOnlyLongProperty");
-ReadOnlyLongPropertyBase = Java.type("javafx.beans.property.ReadOnlyLongPropertyBase");
-ReadOnlyLongWrapper = Java.type("javafx.beans.property.ReadOnlyLongWrapper");
-ReadOnlyMapProperty = Java.type("javafx.beans.property.ReadOnlyMapProperty");
-ReadOnlyMapPropertyBase = Java.type("javafx.beans.property.ReadOnlyMapPropertyBase");
-ReadOnlyMapWrapper = Java.type("javafx.beans.property.ReadOnlyMapWrapper");
-ReadOnlyObjectProperty = Java.type("javafx.beans.property.ReadOnlyObjectProperty");
-ReadOnlyObjectPropertyBase = Java.type("javafx.beans.property.ReadOnlyObjectPropertyBase");
-ReadOnlyObjectWrapper = Java.type("javafx.beans.property.ReadOnlyObjectWrapper");
-ReadOnlyProperty = Java.type("javafx.beans.property.ReadOnlyProperty");
-ReadOnlySetProperty = Java.type("javafx.beans.property.ReadOnlySetProperty");
-ReadOnlySetPropertyBase = Java.type("javafx.beans.property.ReadOnlySetPropertyBase");
-ReadOnlySetWrapper = Java.type("javafx.beans.property.ReadOnlySetWrapper");
-ReadOnlyStringProperty = Java.type("javafx.beans.property.ReadOnlyStringProperty");
-ReadOnlyStringPropertyBase = Java.type("javafx.beans.property.ReadOnlyStringPropertyBase");
-ReadOnlyStringWrapper = Java.type("javafx.beans.property.ReadOnlyStringWrapper");
-SetProperty = Java.type("javafx.beans.property.SetProperty");
-SetPropertyBase = Java.type("javafx.beans.property.SetPropertyBase");
-SimpleBooleanProperty = Java.type("javafx.beans.property.SimpleBooleanProperty");
-SimpleDoubleProperty = Java.type("javafx.beans.property.SimpleDoubleProperty");
-SimpleFloatProperty = Java.type("javafx.beans.property.SimpleFloatProperty");
-SimpleIntegerProperty = Java.type("javafx.beans.property.SimpleIntegerProperty");
-SimpleListProperty = Java.type("javafx.beans.property.SimpleListProperty");
-SimpleLongProperty = Java.type("javafx.beans.property.SimpleLongProperty");
-SimpleMapProperty = Java.type("javafx.beans.property.SimpleMapProperty");
-SimpleObjectProperty = Java.type("javafx.beans.property.SimpleObjectProperty");
-SimpleSetProperty = Java.type("javafx.beans.property.SimpleSetProperty");
-SimpleStringProperty = Java.type("javafx.beans.property.SimpleStringProperty");
-StringProperty = Java.type("javafx.beans.property.StringProperty");
-StringPropertyBase = Java.type("javafx.beans.property.StringPropertyBase");
-ChangeListener = Java.type("javafx.beans.value.ChangeListener");
-ObservableBooleanValue = Java.type("javafx.beans.value.ObservableBooleanValue");
-ObservableDoubleValue = Java.type("javafx.beans.value.ObservableDoubleValue");
-ObservableFloatValue = Java.type("javafx.beans.value.ObservableFloatValue");
-ObservableIntegerValue = Java.type("javafx.beans.value.ObservableIntegerValue");
-ObservableListValue = Java.type("javafx.beans.value.ObservableListValue");
-ObservableLongValue = Java.type("javafx.beans.value.ObservableLongValue");
-ObservableMapValue = Java.type("javafx.beans.value.ObservableMapValue");
-ObservableNumberValue = Java.type("javafx.beans.value.ObservableNumberValue");
-ObservableObjectValue = Java.type("javafx.beans.value.ObservableObjectValue");
-ObservableSetValue = Java.type("javafx.beans.value.ObservableSetValue");
-ObservableStringValue = Java.type("javafx.beans.value.ObservableStringValue");
-ObservableValue = Java.type("javafx.beans.value.ObservableValue");
-ObservableValueBase = Java.type("javafx.beans.value.ObservableValueBase");
-WeakChangeListener = Java.type("javafx.beans.value.WeakChangeListener");
-WritableBooleanValue = Java.type("javafx.beans.value.WritableBooleanValue");
-WritableDoubleValue = Java.type("javafx.beans.value.WritableDoubleValue");
-WritableFloatValue = Java.type("javafx.beans.value.WritableFloatValue");
-WritableIntegerValue = Java.type("javafx.beans.value.WritableIntegerValue");
-WritableListValue = Java.type("javafx.beans.value.WritableListValue");
-WritableLongValue = Java.type("javafx.beans.value.WritableLongValue");
-WritableMapValue = Java.type("javafx.beans.value.WritableMapValue");
-WritableNumberValue = Java.type("javafx.beans.value.WritableNumberValue");
-WritableObjectValue = Java.type("javafx.beans.value.WritableObjectValue");
-WritableSetValue = Java.type("javafx.beans.value.WritableSetValue");
-WritableStringValue = Java.type("javafx.beans.value.WritableStringValue");
-WritableValue = Java.type("javafx.beans.value.WritableValue");
-WeakInvalidationListener = Java.type("javafx.beans.WeakInvalidationListener");
-WeakListener = Java.type("javafx.beans.WeakListener");
-FXCollections = Java.type("javafx.collections.FXCollections");
-ListChangeListener = Java.type("javafx.collections.ListChangeListener");
-ListChangeListener$Change = Java.type("javafx.collections.ListChangeListener$Change");
-MapChangeListener = Java.type("javafx.collections.MapChangeListener");
-MapChangeListener$Change = Java.type("javafx.collections.MapChangeListener$Change");
-ModifiableObservableListBase = Java.type("javafx.collections.ModifiableObservableListBase");
-ObservableList = Java.type("javafx.collections.ObservableList");
-ObservableListBase = Java.type("javafx.collections.ObservableListBase");
-ObservableMap = Java.type("javafx.collections.ObservableMap");
-ObservableSet = Java.type("javafx.collections.ObservableSet");
-SetChangeListener = Java.type("javafx.collections.SetChangeListener");
-SetChangeListener$Change = Java.type("javafx.collections.SetChangeListener$Change");
-WeakListChangeListener = Java.type("javafx.collections.WeakListChangeListener");
-WeakMapChangeListener = Java.type("javafx.collections.WeakMapChangeListener");
-WeakSetChangeListener = Java.type("javafx.collections.WeakSetChangeListener");
-ActionEvent = Java.type("javafx.event.ActionEvent");
-Event = Java.type("javafx.event.Event");
-EventDispatchChain = Java.type("javafx.event.EventDispatchChain");
-EventDispatcher = Java.type("javafx.event.EventDispatcher");
-EventHandler = Java.type("javafx.event.EventHandler");
-EventTarget = Java.type("javafx.event.EventTarget");
-EventType = Java.type("javafx.event.EventType");
-WeakEventHandler = Java.type("javafx.event.WeakEventHandler");
-Builder = Java.type("javafx.util.Builder");
-BuilderFactory = Java.type("javafx.util.BuilderFactory");
-Callback = Java.type("javafx.util.Callback");
-BigDecimalStringConverter = Java.type("javafx.util.converter.BigDecimalStringConverter");
-BigIntegerStringConverter = Java.type("javafx.util.converter.BigIntegerStringConverter");
-BooleanStringConverter = Java.type("javafx.util.converter.BooleanStringConverter");
-ByteStringConverter = Java.type("javafx.util.converter.ByteStringConverter");
-CharacterStringConverter = Java.type("javafx.util.converter.CharacterStringConverter");
-CurrencyStringConverter = Java.type("javafx.util.converter.CurrencyStringConverter");
-DateStringConverter = Java.type("javafx.util.converter.DateStringConverter");
-DateTimeStringConverter = Java.type("javafx.util.converter.DateTimeStringConverter");
-DefaultStringConverter = Java.type("javafx.util.converter.DefaultStringConverter");
-DoubleStringConverter = Java.type("javafx.util.converter.DoubleStringConverter");
-FloatStringConverter = Java.type("javafx.util.converter.FloatStringConverter");
-FormatStringConverter = Java.type("javafx.util.converter.FormatStringConverter");
-IntegerStringConverter = Java.type("javafx.util.converter.IntegerStringConverter");
-LongStringConverter = Java.type("javafx.util.converter.LongStringConverter");
-NumberStringConverter = Java.type("javafx.util.converter.NumberStringConverter");
-PercentageStringConverter = Java.type("javafx.util.converter.PercentageStringConverter");
-ShortStringConverter = Java.type("javafx.util.converter.ShortStringConverter");
-TimeStringConverter = Java.type("javafx.util.converter.TimeStringConverter");
-Duration = Java.type("javafx.util.Duration");
-Pair = Java.type("javafx.util.Pair");
-StringConverter = Java.type("javafx.util.StringConverter");
+ switch (cls[1]) {
+ case "stage":
+ if (cls[2] == "Stage") {
+ JFX_BASE_CLASSES.push(cls);
+ } else {
+ JFX_GRAPHICS_CLASSES.push(cls);
+ }
+ break;
+
+ case "scene":
+ switch (cls[2]) {
+ case "Scene":
+ case "Group":
+ JFX_BASE_CLASSES.push(cls);
+ break;
+
+ case "chart":
+ case "control":
+ JFX_CONTROLS_CLASSES.push(cls);
+ break;
+
+ case "web":
+ JFX_WEB_CLASSES.push(cls);
+ break;
+
+ case "media":
+ JFX_MEDIA_CLASSES.push(cls);
+ break;
+
+ default:
+ JFX_GRAPHICS_CLASSES.push(cls);
+ break;
+ }
+ break;
+
+ case "beans":
+ case "collections":
+ case "events":
+ case "util":
+ JFX_BASE_CLASSES.push(cls);
+ break;
+
+ case "animation":
+ case "application":
+ case "concurrent":
+ case "css":
+ case "geometry":
+ JFX_GRAPHICS_CLASSES.push(cls);
+ break;
+
+ case "fxml":
+ JFX_FXML_CLASSES.push(cls);
+ break;
+
+ case "embed":
+ if (cls[2] == "swing") {
+ JFX_SWING_CLASSES.push(cls);
+ } else {
+ JFX_SWT_CLASSES.push(cls);
+ }
+ break;
+ }
+ }
+})();
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/controls.js Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/controls.js Fri Sep 20 19:15:59 2013 -0700
@@ -23,242 +23,8 @@
* questions.
*/
-AreaChart = Java.type("javafx.scene.chart.AreaChart");
-AreaChartBuilder = Java.type("javafx.scene.chart.AreaChartBuilder");
-Axis = Java.type("javafx.scene.chart.Axis");
-Axis$TickMark = Java.type("javafx.scene.chart.Axis$TickMark");
-AxisBuilder = Java.type("javafx.scene.chart.AxisBuilder");
-BarChart = Java.type("javafx.scene.chart.BarChart");
-BarChartBuilder = Java.type("javafx.scene.chart.BarChartBuilder");
-BubbleChart = Java.type("javafx.scene.chart.BubbleChart");
-BubbleChartBuilder = Java.type("javafx.scene.chart.BubbleChartBuilder");
-CategoryAxis = Java.type("javafx.scene.chart.CategoryAxis");
-CategoryAxisBuilder = Java.type("javafx.scene.chart.CategoryAxisBuilder");
-Chart = Java.type("javafx.scene.chart.Chart");
-ChartBuilder = Java.type("javafx.scene.chart.ChartBuilder");
-LineChart = Java.type("javafx.scene.chart.LineChart");
-LineChartBuilder = Java.type("javafx.scene.chart.LineChartBuilder");
-NumberAxis = Java.type("javafx.scene.chart.NumberAxis");
-NumberAxis$DefaultFormatter = Java.type("javafx.scene.chart.NumberAxis$DefaultFormatter");
-NumberAxisBuilder = Java.type("javafx.scene.chart.NumberAxisBuilder");
-PieChart = Java.type("javafx.scene.chart.PieChart");
-PieChart$Data = Java.type("javafx.scene.chart.PieChart$Data");
-PieChartBuilder = Java.type("javafx.scene.chart.PieChartBuilder");
-ScatterChart = Java.type("javafx.scene.chart.ScatterChart");
-ScatterChartBuilder = Java.type("javafx.scene.chart.ScatterChartBuilder");
-StackedAreaChart = Java.type("javafx.scene.chart.StackedAreaChart");
-StackedAreaChartBuilder = Java.type("javafx.scene.chart.StackedAreaChartBuilder");
-StackedBarChart = Java.type("javafx.scene.chart.StackedBarChart");
-StackedBarChartBuilder = Java.type("javafx.scene.chart.StackedBarChartBuilder");
-ValueAxis = Java.type("javafx.scene.chart.ValueAxis");
-ValueAxisBuilder = Java.type("javafx.scene.chart.ValueAxisBuilder");
-XYChart = Java.type("javafx.scene.chart.XYChart");
-XYChart$Data = Java.type("javafx.scene.chart.XYChart$Data");
-XYChart$Series = Java.type("javafx.scene.chart.XYChart$Series");
-XYChartBuilder = Java.type("javafx.scene.chart.XYChartBuilder");
-Accordion = Java.type("javafx.scene.control.Accordion");
-AccordionBuilder = Java.type("javafx.scene.control.AccordionBuilder");
-Button = Java.type("javafx.scene.control.Button");
-ButtonBase = Java.type("javafx.scene.control.ButtonBase");
-ButtonBaseBuilder = Java.type("javafx.scene.control.ButtonBaseBuilder");
-ButtonBuilder = Java.type("javafx.scene.control.ButtonBuilder");
-Cell = Java.type("javafx.scene.control.Cell");
-CheckBoxListCell = Java.type("javafx.scene.control.cell.CheckBoxListCell");
-CheckBoxListCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxListCellBuilder");
-CheckBoxTableCell = Java.type("javafx.scene.control.cell.CheckBoxTableCell");
-CheckBoxTableCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxTableCellBuilder");
-CheckBoxTreeCell = Java.type("javafx.scene.control.cell.CheckBoxTreeCell");
-CheckBoxTreeCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxTreeCellBuilder");
-CheckBoxTreeTableCell = Java.type("javafx.scene.control.cell.CheckBoxTreeTableCell");
-//CheckBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxTreeTableCellBuilder");
-ChoiceBoxListCell = Java.type("javafx.scene.control.cell.ChoiceBoxListCell");
-ChoiceBoxListCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxListCellBuilder");
-ChoiceBoxTableCell = Java.type("javafx.scene.control.cell.ChoiceBoxTableCell");
-ChoiceBoxTableCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxTableCellBuilder");
-ChoiceBoxTreeCell = Java.type("javafx.scene.control.cell.ChoiceBoxTreeCell");
-ChoiceBoxTreeCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxTreeCellBuilder");
-ChoiceBoxTreeTableCell = Java.type("javafx.scene.control.cell.ChoiceBoxTreeTableCell");
-//ChoiceBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxTreeTableCellBuilder");
-ComboBoxListCell = Java.type("javafx.scene.control.cell.ComboBoxListCell");
-ComboBoxListCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxListCellBuilder");
-ComboBoxTableCell = Java.type("javafx.scene.control.cell.ComboBoxTableCell");
-ComboBoxTableCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxTableCellBuilder");
-ComboBoxTreeCell = Java.type("javafx.scene.control.cell.ComboBoxTreeCell");
-ComboBoxTreeCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxTreeCellBuilder");
-ComboBoxTreeTableCell = Java.type("javafx.scene.control.cell.ComboBoxTreeTableCell");
-//ComboBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxTreeTableCellBuilder");
-MapValueFactory = Java.type("javafx.scene.control.cell.MapValueFactory");
-ProgressBarTableCell = Java.type("javafx.scene.control.cell.ProgressBarTableCell");
-ProgressBarTreeTableCell = Java.type("javafx.scene.control.cell.ProgressBarTreeTableCell");
-PropertyValueFactory = Java.type("javafx.scene.control.cell.PropertyValueFactory");
-PropertyValueFactoryBuilder = Java.type("javafx.scene.control.cell.PropertyValueFactoryBuilder");
-TextFieldListCell = Java.type("javafx.scene.control.cell.TextFieldListCell");
-TextFieldListCellBuilder = Java.type("javafx.scene.control.cell.TextFieldListCellBuilder");
-TextFieldTableCell = Java.type("javafx.scene.control.cell.TextFieldTableCell");
-TextFieldTableCellBuilder = Java.type("javafx.scene.control.cell.TextFieldTableCellBuilder");
-TextFieldTreeCell = Java.type("javafx.scene.control.cell.TextFieldTreeCell");
-TextFieldTreeCellBuilder = Java.type("javafx.scene.control.cell.TextFieldTreeCellBuilder");
-TextFieldTreeTableCell = Java.type("javafx.scene.control.cell.TextFieldTreeTableCell");
-//TextFieldTreeTableCellBuilder = Java.type("javafx.scene.control.cell.TextFieldTreeTableCellBuilder");
-TreeItemPropertyValueFactory = Java.type("javafx.scene.control.cell.TreeItemPropertyValueFactory");
-//TreeItemPropertyValueFactoryBuilder = Java.type("javafx.scene.control.cell.TreeItemPropertyValueFactoryBuilder");
-CellBuilder = Java.type("javafx.scene.control.CellBuilder");
-CheckBox = Java.type("javafx.scene.control.CheckBox");
-CheckBoxBuilder = Java.type("javafx.scene.control.CheckBoxBuilder");
-CheckBoxTreeItem = Java.type("javafx.scene.control.CheckBoxTreeItem");
-CheckBoxTreeItem$TreeModificationEvent = Java.type("javafx.scene.control.CheckBoxTreeItem$TreeModificationEvent");
-CheckBoxTreeItemBuilder = Java.type("javafx.scene.control.CheckBoxTreeItemBuilder");
-CheckMenuItem = Java.type("javafx.scene.control.CheckMenuItem");
-CheckMenuItemBuilder = Java.type("javafx.scene.control.CheckMenuItemBuilder");
-ChoiceBox = Java.type("javafx.scene.control.ChoiceBox");
-ChoiceBoxBuilder = Java.type("javafx.scene.control.ChoiceBoxBuilder");
-ColorPicker = Java.type("javafx.scene.control.ColorPicker");
-ColorPickerBuilder = Java.type("javafx.scene.control.ColorPickerBuilder");
-ComboBox = Java.type("javafx.scene.control.ComboBox");
-ComboBoxBase = Java.type("javafx.scene.control.ComboBoxBase");
-ComboBoxBaseBuilder = Java.type("javafx.scene.control.ComboBoxBaseBuilder");
-ComboBoxBuilder = Java.type("javafx.scene.control.ComboBoxBuilder");
-ContentDisplay = Java.type("javafx.scene.control.ContentDisplay");
-ContextMenu = Java.type("javafx.scene.control.ContextMenu");
-ContextMenuBuilder = Java.type("javafx.scene.control.ContextMenuBuilder");
-Control = Java.type("javafx.scene.control.Control");
-ControlBuilder = Java.type("javafx.scene.control.ControlBuilder");
-CustomMenuItem = Java.type("javafx.scene.control.CustomMenuItem");
-CustomMenuItemBuilder = Java.type("javafx.scene.control.CustomMenuItemBuilder");
-FocusModel = Java.type("javafx.scene.control.FocusModel");
-Hyperlink = Java.type("javafx.scene.control.Hyperlink");
-HyperlinkBuilder = Java.type("javafx.scene.control.HyperlinkBuilder");
-IndexedCell = Java.type("javafx.scene.control.IndexedCell");
-IndexedCellBuilder = Java.type("javafx.scene.control.IndexedCellBuilder");
-IndexRange = Java.type("javafx.scene.control.IndexRange");
-IndexRangeBuilder = Java.type("javafx.scene.control.IndexRangeBuilder");
-Label = Java.type("javafx.scene.control.Label");
-LabelBuilder = Java.type("javafx.scene.control.LabelBuilder");
-Labeled = Java.type("javafx.scene.control.Labeled");
-LabeledBuilder = Java.type("javafx.scene.control.LabeledBuilder");
-ListCell = Java.type("javafx.scene.control.ListCell");
-ListCellBuilder = Java.type("javafx.scene.control.ListCellBuilder");
-ListView = Java.type("javafx.scene.control.ListView");
-ListView$EditEvent = Java.type("javafx.scene.control.ListView$EditEvent");
-ListViewBuilder = Java.type("javafx.scene.control.ListViewBuilder");
-Menu = Java.type("javafx.scene.control.Menu");
-MenuBar = Java.type("javafx.scene.control.MenuBar");
-MenuBarBuilder = Java.type("javafx.scene.control.MenuBarBuilder");
-MenuBuilder = Java.type("javafx.scene.control.MenuBuilder");
-MenuButton = Java.type("javafx.scene.control.MenuButton");
-MenuButtonBuilder = Java.type("javafx.scene.control.MenuButtonBuilder");
-MenuItem = Java.type("javafx.scene.control.MenuItem");
-MenuItemBuilder = Java.type("javafx.scene.control.MenuItemBuilder");
-MultipleSelectionModel = Java.type("javafx.scene.control.MultipleSelectionModel");
-MultipleSelectionModelBuilder = Java.type("javafx.scene.control.MultipleSelectionModelBuilder");
-OverrunStyle = Java.type("javafx.scene.control.OverrunStyle");
-Pagination = Java.type("javafx.scene.control.Pagination");
-PaginationBuilder = Java.type("javafx.scene.control.PaginationBuilder");
-PasswordField = Java.type("javafx.scene.control.PasswordField");
-PasswordFieldBuilder = Java.type("javafx.scene.control.PasswordFieldBuilder");
-PopupControl = Java.type("javafx.scene.control.PopupControl");
-PopupControlBuilder = Java.type("javafx.scene.control.PopupControlBuilder");
-ProgressBar = Java.type("javafx.scene.control.ProgressBar");
-ProgressBarBuilder = Java.type("javafx.scene.control.ProgressBarBuilder");
-ProgressIndicator = Java.type("javafx.scene.control.ProgressIndicator");
-ProgressIndicatorBuilder = Java.type("javafx.scene.control.ProgressIndicatorBuilder");
-RadioButton = Java.type("javafx.scene.control.RadioButton");
-RadioButtonBuilder = Java.type("javafx.scene.control.RadioButtonBuilder");
-RadioMenuItem = Java.type("javafx.scene.control.RadioMenuItem");
-RadioMenuItemBuilder = Java.type("javafx.scene.control.RadioMenuItemBuilder");
-ResizeFeaturesBase = Java.type("javafx.scene.control.ResizeFeaturesBase");
-//ResizeFeaturesBaseBuilder = Java.type("javafx.scene.control.ResizeFeaturesBaseBuilder");
-ScrollBar = Java.type("javafx.scene.control.ScrollBar");
-ScrollBarBuilder = Java.type("javafx.scene.control.ScrollBarBuilder");
-ScrollPane = Java.type("javafx.scene.control.ScrollPane");
-ScrollPane$ScrollBarPolicy = Java.type("javafx.scene.control.ScrollPane$ScrollBarPolicy");
-ScrollPaneBuilder = Java.type("javafx.scene.control.ScrollPaneBuilder");
-ScrollToEvent = Java.type("javafx.scene.control.ScrollToEvent");
-SelectionMode = Java.type("javafx.scene.control.SelectionMode");
-SelectionModel = Java.type("javafx.scene.control.SelectionModel");
-Separator = Java.type("javafx.scene.control.Separator");
-SeparatorBuilder = Java.type("javafx.scene.control.SeparatorBuilder");
-SeparatorMenuItem = Java.type("javafx.scene.control.SeparatorMenuItem");
-SeparatorMenuItemBuilder = Java.type("javafx.scene.control.SeparatorMenuItemBuilder");
-SingleSelectionModel = Java.type("javafx.scene.control.SingleSelectionModel");
-Skin = Java.type("javafx.scene.control.Skin");
-SkinBase = Java.type("javafx.scene.control.SkinBase");
-//SkinBaseBuilder = Java.type("javafx.scene.control.SkinBaseBuilder");
-Skinnable = Java.type("javafx.scene.control.Skinnable");
-Slider = Java.type("javafx.scene.control.Slider");
-SliderBuilder = Java.type("javafx.scene.control.SliderBuilder");
-SortEvent = Java.type("javafx.scene.control.SortEvent");
-SplitMenuButton = Java.type("javafx.scene.control.SplitMenuButton");
-SplitMenuButtonBuilder = Java.type("javafx.scene.control.SplitMenuButtonBuilder");
-SplitPane = Java.type("javafx.scene.control.SplitPane");
-SplitPane$Divider = Java.type("javafx.scene.control.SplitPane$Divider");
-SplitPaneBuilder = Java.type("javafx.scene.control.SplitPaneBuilder");
-Tab = Java.type("javafx.scene.control.Tab");
-TabBuilder = Java.type("javafx.scene.control.TabBuilder");
-TableCell = Java.type("javafx.scene.control.TableCell");
-TableCellBuilder = Java.type("javafx.scene.control.TableCellBuilder");
-TableColumn = Java.type("javafx.scene.control.TableColumn");
-TableColumn$CellDataFeatures = Java.type("javafx.scene.control.TableColumn$CellDataFeatures");
-TableColumn$CellEditEvent = Java.type("javafx.scene.control.TableColumn$CellEditEvent");
-TableColumn$SortType = Java.type("javafx.scene.control.TableColumn$SortType");
-TableColumnBase = Java.type("javafx.scene.control.TableColumnBase");
-//TableColumnBaseBuilder = Java.type("javafx.scene.control.TableColumnBaseBuilder");
-TableColumnBuilder = Java.type("javafx.scene.control.TableColumnBuilder");
-TableFocusModel = Java.type("javafx.scene.control.TableFocusModel");
-TablePosition = Java.type("javafx.scene.control.TablePosition");
-TablePositionBase = Java.type("javafx.scene.control.TablePositionBase");
-TableRow = Java.type("javafx.scene.control.TableRow");
-TableRowBuilder = Java.type("javafx.scene.control.TableRowBuilder");
-TableSelectionModel = Java.type("javafx.scene.control.TableSelectionModel");
-//TableSelectionModelBuilder = Java.type("javafx.scene.control.TableSelectionModelBuilder");
-TableView = Java.type("javafx.scene.control.TableView");
-TableView$ResizeFeatures = Java.type("javafx.scene.control.TableView$ResizeFeatures");
-TableView$TableViewFocusModel = Java.type("javafx.scene.control.TableView$TableViewFocusModel");
-TableView$TableViewSelectionModel = Java.type("javafx.scene.control.TableView$TableViewSelectionModel");
-TableViewBuilder = Java.type("javafx.scene.control.TableViewBuilder");
-TabPane = Java.type("javafx.scene.control.TabPane");
-TabPane$TabClosingPolicy = Java.type("javafx.scene.control.TabPane$TabClosingPolicy");
-TabPaneBuilder = Java.type("javafx.scene.control.TabPaneBuilder");
-TextArea = Java.type("javafx.scene.control.TextArea");
-TextAreaBuilder = Java.type("javafx.scene.control.TextAreaBuilder");
-TextField = Java.type("javafx.scene.control.TextField");
-TextFieldBuilder = Java.type("javafx.scene.control.TextFieldBuilder");
-TextInputControl = Java.type("javafx.scene.control.TextInputControl");
-TextInputControl$Content = Java.type("javafx.scene.control.TextInputControl$Content");
-TextInputControlBuilder = Java.type("javafx.scene.control.TextInputControlBuilder");
-TitledPane = Java.type("javafx.scene.control.TitledPane");
-TitledPaneBuilder = Java.type("javafx.scene.control.TitledPaneBuilder");
-Toggle = Java.type("javafx.scene.control.Toggle");
-ToggleButton = Java.type("javafx.scene.control.ToggleButton");
-ToggleButtonBuilder = Java.type("javafx.scene.control.ToggleButtonBuilder");
-ToggleGroup = Java.type("javafx.scene.control.ToggleGroup");
-ToggleGroupBuilder = Java.type("javafx.scene.control.ToggleGroupBuilder");
-ToolBar = Java.type("javafx.scene.control.ToolBar");
-ToolBarBuilder = Java.type("javafx.scene.control.ToolBarBuilder");
-Tooltip = Java.type("javafx.scene.control.Tooltip");
-TooltipBuilder = Java.type("javafx.scene.control.TooltipBuilder");
-TreeCell = Java.type("javafx.scene.control.TreeCell");
-TreeCellBuilder = Java.type("javafx.scene.control.TreeCellBuilder");
-TreeItem = Java.type("javafx.scene.control.TreeItem");
-TreeItem$TreeModificationEvent = Java.type("javafx.scene.control.TreeItem$TreeModificationEvent");
-TreeItemBuilder = Java.type("javafx.scene.control.TreeItemBuilder");
-TreeSortMode = Java.type("javafx.scene.control.TreeSortMode");
-TreeTableCell = Java.type("javafx.scene.control.TreeTableCell");
-//TreeTableCellBuilder = Java.type("javafx.scene.control.TreeTableCellBuilder");
-TreeTableColumn = Java.type("javafx.scene.control.TreeTableColumn");
-TreeTableColumn$CellDataFeatures = Java.type("javafx.scene.control.TreeTableColumn$CellDataFeatures");
-TreeTableColumn$CellEditEvent = Java.type("javafx.scene.control.TreeTableColumn$CellEditEvent");
-TreeTableColumn$SortType = Java.type("javafx.scene.control.TreeTableColumn$SortType");
-//TreeTableColumnBuilder = Java.type("javafx.scene.control.TreeTableColumnBuilder");
-TreeTablePosition = Java.type("javafx.scene.control.TreeTablePosition");
-TreeTableRow = Java.type("javafx.scene.control.TreeTableRow");
-//TreeTableRowBuilder = Java.type("javafx.scene.control.TreeTableRowBuilder");
-TreeTableView = Java.type("javafx.scene.control.TreeTableView");
-TreeTableView$EditEvent = Java.type("javafx.scene.control.TreeTableView$EditEvent");
-TreeTableView$ResizeFeatures = Java.type("javafx.scene.control.TreeTableView$ResizeFeatures");
-TreeTableView$TreeTableViewFocusModel = Java.type("javafx.scene.control.TreeTableView$TreeTableViewFocusModel");
-TreeTableView$TreeTableViewSelectionModel = Java.type("javafx.scene.control.TreeTableView$TreeTableViewSelectionModel");
-//TreeTableViewBuilder = Java.type("javafx.scene.control.TreeTableViewBuilder");
-TreeView = Java.type("javafx.scene.control.TreeView");
-TreeView$EditEvent = Java.type("javafx.scene.control.TreeView$EditEvent");
-TreeViewBuilder = Java.type("javafx.scene.control.TreeViewBuilder");
+if (!this.JFX_BASE_CLASSES) {
+ load("fx:base.js")
+}
+
+LOAD_FX_CLASSES(JFX_CONTROLS_CLASSES);
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/fxml.js Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/fxml.js Fri Sep 20 19:15:59 2013 -0700
@@ -23,8 +23,8 @@
* questions.
*/
-FXML = Java.type("javafx.fxml.FXML");
-FXMLLoader = Java.type("javafx.fxml.FXMLLoader");
-Initializable = Java.type("javafx.fxml.Initializable");
-JavaFXBuilderFactory = Java.type("javafx.fxml.JavaFXBuilderFactory");
-LoadException = Java.type("javafx.fxml.LoadException");
+if (!this.JFX_BASE_CLASSES) {
+ load("fx:base.js")
+}
+
+LOAD_FX_CLASSES(JFX_FXML_CLASSES);
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js Fri Sep 20 19:15:59 2013 -0700
@@ -23,409 +23,10 @@
* questions.
*/
-Animation = Java.type("javafx.animation.Animation");
-Animation$Status = Java.type("javafx.animation.Animation$Status");
-AnimationBuilder = Java.type("javafx.animation.AnimationBuilder");
-AnimationTimer = Java.type("javafx.animation.AnimationTimer");
-FadeTransition = Java.type("javafx.animation.FadeTransition");
-FadeTransitionBuilder = Java.type("javafx.animation.FadeTransitionBuilder");
-FillTransition = Java.type("javafx.animation.FillTransition");
-FillTransitionBuilder = Java.type("javafx.animation.FillTransitionBuilder");
-Interpolatable = Java.type("javafx.animation.Interpolatable");
-Interpolator = Java.type("javafx.animation.Interpolator");
-KeyFrame = Java.type("javafx.animation.KeyFrame");
-KeyValue = Java.type("javafx.animation.KeyValue");
-ParallelTransition = Java.type("javafx.animation.ParallelTransition");
-ParallelTransitionBuilder = Java.type("javafx.animation.ParallelTransitionBuilder");
-PathTransition = Java.type("javafx.animation.PathTransition");
-PathTransition$OrientationType = Java.type("javafx.animation.PathTransition$OrientationType");
-PathTransitionBuilder = Java.type("javafx.animation.PathTransitionBuilder");
-PauseTransition = Java.type("javafx.animation.PauseTransition");
-PauseTransitionBuilder = Java.type("javafx.animation.PauseTransitionBuilder");
-RotateTransition = Java.type("javafx.animation.RotateTransition");
-RotateTransitionBuilder = Java.type("javafx.animation.RotateTransitionBuilder");
-ScaleTransition = Java.type("javafx.animation.ScaleTransition");
-ScaleTransitionBuilder = Java.type("javafx.animation.ScaleTransitionBuilder");
-SequentialTransition = Java.type("javafx.animation.SequentialTransition");
-SequentialTransitionBuilder = Java.type("javafx.animation.SequentialTransitionBuilder");
-StrokeTransition = Java.type("javafx.animation.StrokeTransition");
-StrokeTransitionBuilder = Java.type("javafx.animation.StrokeTransitionBuilder");
-Timeline = Java.type("javafx.animation.Timeline");
-TimelineBuilder = Java.type("javafx.animation.TimelineBuilder");
-Transition = Java.type("javafx.animation.Transition");
-TransitionBuilder = Java.type("javafx.animation.TransitionBuilder");
-TranslateTransition = Java.type("javafx.animation.TranslateTransition");
-TranslateTransitionBuilder = Java.type("javafx.animation.TranslateTransitionBuilder");
-Application = Java.type("javafx.application.Application");
-Application$Parameters = Java.type("javafx.application.Application$Parameters");
-ConditionalFeature = Java.type("javafx.application.ConditionalFeature");
-HostServices = Java.type("javafx.application.HostServices");
-Platform = Java.type("javafx.application.Platform");
-Preloader = Java.type("javafx.application.Preloader");
-Preloader$ErrorNotification = Java.type("javafx.application.Preloader$ErrorNotification");
-Preloader$PreloaderNotification = Java.type("javafx.application.Preloader$PreloaderNotification");
-Preloader$ProgressNotification = Java.type("javafx.application.Preloader$ProgressNotification");
-Preloader$StateChangeNotification = Java.type("javafx.application.Preloader$StateChangeNotification");
-Preloader$StateChangeNotification$Type = Java.type("javafx.application.Preloader$StateChangeNotification$Type");
-ScheduledService = Java.type("javafx.concurrent.ScheduledService");
-Service = Java.type("javafx.concurrent.Service");
-Task = Java.type("javafx.concurrent.Task");
-Worker = Java.type("javafx.concurrent.Worker");
-Worker$State = Java.type("javafx.concurrent.Worker$State");
-WorkerStateEvent = Java.type("javafx.concurrent.WorkerStateEvent");
-CssMetaData = Java.type("javafx.css.CssMetaData");
-FontCssMetaData = Java.type("javafx.css.FontCssMetaData");
-ParsedValue = Java.type("javafx.css.ParsedValue");
-PseudoClass = Java.type("javafx.css.PseudoClass");
-SimpleStyleableBooleanProperty = Java.type("javafx.css.SimpleStyleableBooleanProperty");
-SimpleStyleableDoubleProperty = Java.type("javafx.css.SimpleStyleableDoubleProperty");
-SimpleStyleableFloatProperty = Java.type("javafx.css.SimpleStyleableFloatProperty");
-SimpleStyleableIntegerProperty = Java.type("javafx.css.SimpleStyleableIntegerProperty");
-SimpleStyleableLongProperty = Java.type("javafx.css.SimpleStyleableLongProperty");
-SimpleStyleableObjectProperty = Java.type("javafx.css.SimpleStyleableObjectProperty");
-SimpleStyleableStringProperty = Java.type("javafx.css.SimpleStyleableStringProperty");
-Styleable = Java.type("javafx.css.Styleable");
-StyleableBooleanProperty = Java.type("javafx.css.StyleableBooleanProperty");
-StyleableDoubleProperty = Java.type("javafx.css.StyleableDoubleProperty");
-StyleableFloatProperty = Java.type("javafx.css.StyleableFloatProperty");
-StyleableIntegerProperty = Java.type("javafx.css.StyleableIntegerProperty");
-StyleableLongProperty = Java.type("javafx.css.StyleableLongProperty");
-StyleableObjectProperty = Java.type("javafx.css.StyleableObjectProperty");
-StyleableProperty = Java.type("javafx.css.StyleableProperty");
-StyleableStringProperty = Java.type("javafx.css.StyleableStringProperty");
-StyleConverter = Java.type("javafx.css.StyleConverter");
-StyleOrigin = Java.type("javafx.css.StyleOrigin");
-BoundingBox = Java.type("javafx.geometry.BoundingBox");
-BoundingBoxBuilder = Java.type("javafx.geometry.BoundingBoxBuilder");
-Bounds = Java.type("javafx.geometry.Bounds");
-Dimension2D = Java.type("javafx.geometry.Dimension2D");
-Dimension2DBuilder = Java.type("javafx.geometry.Dimension2DBuilder");
-HorizontalDirection = Java.type("javafx.geometry.HorizontalDirection");
-HPos = Java.type("javafx.geometry.HPos");
-Insets = Java.type("javafx.geometry.Insets");
-InsetsBuilder = Java.type("javafx.geometry.InsetsBuilder");
-NodeOrientation = Java.type("javafx.geometry.NodeOrientation");
-Orientation = Java.type("javafx.geometry.Orientation");
-Point2D = Java.type("javafx.geometry.Point2D");
-Point2DBuilder = Java.type("javafx.geometry.Point2DBuilder");
-Point3D = Java.type("javafx.geometry.Point3D");
-Point3DBuilder = Java.type("javafx.geometry.Point3DBuilder");
-Pos = Java.type("javafx.geometry.Pos");
-Rectangle2D = Java.type("javafx.geometry.Rectangle2D");
-Rectangle2DBuilder = Java.type("javafx.geometry.Rectangle2DBuilder");
-Side = Java.type("javafx.geometry.Side");
-VerticalDirection = Java.type("javafx.geometry.VerticalDirection");
-VPos = Java.type("javafx.geometry.VPos");
-Collation = Java.type("javafx.print.Collation");
-JobSettings = Java.type("javafx.print.JobSettings");
-PageLayout = Java.type("javafx.print.PageLayout");
-PageOrientation = Java.type("javafx.print.PageOrientation");
-PageRange = Java.type("javafx.print.PageRange");
-Paper = Java.type("javafx.print.Paper");
-Paper$Units = Java.type("javafx.print.Paper$Units");
-PaperSource = Java.type("javafx.print.PaperSource");
-PrintColor = Java.type("javafx.print.PrintColor");
-Printer = Java.type("javafx.print.Printer");
-Printer$MarginType = Java.type("javafx.print.Printer$MarginType");
-PrinterAttributes = Java.type("javafx.print.PrinterAttributes");
-PrinterJob = Java.type("javafx.print.PrinterJob");
-PrinterJob$JobStatus = Java.type("javafx.print.PrinterJob$JobStatus");
-PrintQuality = Java.type("javafx.print.PrintQuality");
-PrintResolution = Java.type("javafx.print.PrintResolution");
-PrintSides = Java.type("javafx.print.PrintSides");
-AmbientLight = Java.type("javafx.scene.AmbientLight");
-//AmbientLightBuilder = Java.type("javafx.scene.AmbientLightBuilder");
-CacheHint = Java.type("javafx.scene.CacheHint");
-Camera = Java.type("javafx.scene.Camera");
-//CameraBuilder = Java.type("javafx.scene.CameraBuilder");
-Canvas = Java.type("javafx.scene.canvas.Canvas");
-CanvasBuilder = Java.type("javafx.scene.canvas.CanvasBuilder");
-GraphicsContext = Java.type("javafx.scene.canvas.GraphicsContext");
-Cursor = Java.type("javafx.scene.Cursor");
-DepthTest = Java.type("javafx.scene.DepthTest");
-Blend = Java.type("javafx.scene.effect.Blend");
-BlendBuilder = Java.type("javafx.scene.effect.BlendBuilder");
-BlendMode = Java.type("javafx.scene.effect.BlendMode");
-Bloom = Java.type("javafx.scene.effect.Bloom");
-BloomBuilder = Java.type("javafx.scene.effect.BloomBuilder");
-BlurType = Java.type("javafx.scene.effect.BlurType");
-BoxBlur = Java.type("javafx.scene.effect.BoxBlur");
-BoxBlurBuilder = Java.type("javafx.scene.effect.BoxBlurBuilder");
-ColorAdjust = Java.type("javafx.scene.effect.ColorAdjust");
-ColorAdjustBuilder = Java.type("javafx.scene.effect.ColorAdjustBuilder");
-ColorInput = Java.type("javafx.scene.effect.ColorInput");
-ColorInputBuilder = Java.type("javafx.scene.effect.ColorInputBuilder");
-DisplacementMap = Java.type("javafx.scene.effect.DisplacementMap");
-DisplacementMapBuilder = Java.type("javafx.scene.effect.DisplacementMapBuilder");
-DropShadow = Java.type("javafx.scene.effect.DropShadow");
-DropShadowBuilder = Java.type("javafx.scene.effect.DropShadowBuilder");
-Effect = Java.type("javafx.scene.effect.Effect");
-FloatMap = Java.type("javafx.scene.effect.FloatMap");
-FloatMapBuilder = Java.type("javafx.scene.effect.FloatMapBuilder");
-GaussianBlur = Java.type("javafx.scene.effect.GaussianBlur");
-GaussianBlurBuilder = Java.type("javafx.scene.effect.GaussianBlurBuilder");
-Glow = Java.type("javafx.scene.effect.Glow");
-GlowBuilder = Java.type("javafx.scene.effect.GlowBuilder");
-ImageInput = Java.type("javafx.scene.effect.ImageInput");
-ImageInputBuilder = Java.type("javafx.scene.effect.ImageInputBuilder");
-InnerShadow = Java.type("javafx.scene.effect.InnerShadow");
-InnerShadowBuilder = Java.type("javafx.scene.effect.InnerShadowBuilder");
-Light = Java.type("javafx.scene.effect.Light");
-Light$Distant = Java.type("javafx.scene.effect.Light$Distant");
-Light$Point = Java.type("javafx.scene.effect.Light$Point");
-Light$Spot = Java.type("javafx.scene.effect.Light$Spot");
-LightBuilder = Java.type("javafx.scene.effect.LightBuilder");
-Lighting = Java.type("javafx.scene.effect.Lighting");
-LightingBuilder = Java.type("javafx.scene.effect.LightingBuilder");
-MotionBlur = Java.type("javafx.scene.effect.MotionBlur");
-MotionBlurBuilder = Java.type("javafx.scene.effect.MotionBlurBuilder");
-PerspectiveTransform = Java.type("javafx.scene.effect.PerspectiveTransform");
-PerspectiveTransformBuilder = Java.type("javafx.scene.effect.PerspectiveTransformBuilder");
-Reflection = Java.type("javafx.scene.effect.Reflection");
-ReflectionBuilder = Java.type("javafx.scene.effect.ReflectionBuilder");
-SepiaTone = Java.type("javafx.scene.effect.SepiaTone");
-SepiaToneBuilder = Java.type("javafx.scene.effect.SepiaToneBuilder");
-Shadow = Java.type("javafx.scene.effect.Shadow");
-ShadowBuilder = Java.type("javafx.scene.effect.ShadowBuilder");
-//Group = Java.type("javafx.scene.Group");
-GroupBuilder = Java.type("javafx.scene.GroupBuilder");
-Image = Java.type("javafx.scene.image.Image");
-ImageView = Java.type("javafx.scene.image.ImageView");
-ImageViewBuilder = Java.type("javafx.scene.image.ImageViewBuilder");
-PixelFormat = Java.type("javafx.scene.image.PixelFormat");
-PixelFormat$Type = Java.type("javafx.scene.image.PixelFormat$Type");
-PixelReader = Java.type("javafx.scene.image.PixelReader");
-PixelWriter = Java.type("javafx.scene.image.PixelWriter");
-WritableImage = Java.type("javafx.scene.image.WritableImage");
-WritablePixelFormat = Java.type("javafx.scene.image.WritablePixelFormat");
-ImageCursor = Java.type("javafx.scene.ImageCursor");
-ImageCursorBuilder = Java.type("javafx.scene.ImageCursorBuilder");
-Clipboard = Java.type("javafx.scene.input.Clipboard");
-ClipboardContent = Java.type("javafx.scene.input.ClipboardContent");
-ClipboardContentBuilder = Java.type("javafx.scene.input.ClipboardContentBuilder");
-ContextMenuEvent = Java.type("javafx.scene.input.ContextMenuEvent");
-DataFormat = Java.type("javafx.scene.input.DataFormat");
-Dragboard = Java.type("javafx.scene.input.Dragboard");
-DragEvent = Java.type("javafx.scene.input.DragEvent");
-GestureEvent = Java.type("javafx.scene.input.GestureEvent");
-InputEvent = Java.type("javafx.scene.input.InputEvent");
-//InputEventBuilder = Java.type("javafx.scene.input.InputEventBuilder");
-InputMethodEvent = Java.type("javafx.scene.input.InputMethodEvent");
-InputMethodHighlight = Java.type("javafx.scene.input.InputMethodHighlight");
-InputMethodRequests = Java.type("javafx.scene.input.InputMethodRequests");
-InputMethodTextRun = Java.type("javafx.scene.input.InputMethodTextRun");
-//InputMethodTextRunBuilder = Java.type("javafx.scene.input.InputMethodTextRunBuilder");
-KeyCharacterCombination = Java.type("javafx.scene.input.KeyCharacterCombination");
-KeyCharacterCombinationBuilder = Java.type("javafx.scene.input.KeyCharacterCombinationBuilder");
-KeyCode = Java.type("javafx.scene.input.KeyCode");
-KeyCodeCombination = Java.type("javafx.scene.input.KeyCodeCombination");
-KeyCodeCombinationBuilder = Java.type("javafx.scene.input.KeyCodeCombinationBuilder");
-KeyCombination = Java.type("javafx.scene.input.KeyCombination");
-KeyCombination$Modifier = Java.type("javafx.scene.input.KeyCombination$Modifier");
-KeyCombination$ModifierValue = Java.type("javafx.scene.input.KeyCombination$ModifierValue");
-KeyEvent = Java.type("javafx.scene.input.KeyEvent");
-Mnemonic = Java.type("javafx.scene.input.Mnemonic");
-MnemonicBuilder = Java.type("javafx.scene.input.MnemonicBuilder");
-MouseButton = Java.type("javafx.scene.input.MouseButton");
-MouseDragEvent = Java.type("javafx.scene.input.MouseDragEvent");
-MouseEvent = Java.type("javafx.scene.input.MouseEvent");
-PickResult = Java.type("javafx.scene.input.PickResult");
-RotateEvent = Java.type("javafx.scene.input.RotateEvent");
-ScrollEvent = Java.type("javafx.scene.input.ScrollEvent");
-ScrollEvent$HorizontalTextScrollUnits = Java.type("javafx.scene.input.ScrollEvent$HorizontalTextScrollUnits");
-ScrollEvent$VerticalTextScrollUnits = Java.type("javafx.scene.input.ScrollEvent$VerticalTextScrollUnits");
-SwipeEvent = Java.type("javafx.scene.input.SwipeEvent");
-TouchEvent = Java.type("javafx.scene.input.TouchEvent");
-TouchPoint = Java.type("javafx.scene.input.TouchPoint");
-TouchPoint$State = Java.type("javafx.scene.input.TouchPoint$State");
-//TouchPointBuilder = Java.type("javafx.scene.input.TouchPointBuilder");
-TransferMode = Java.type("javafx.scene.input.TransferMode");
-ZoomEvent = Java.type("javafx.scene.input.ZoomEvent");
-AnchorPane = Java.type("javafx.scene.layout.AnchorPane");
-AnchorPaneBuilder = Java.type("javafx.scene.layout.AnchorPaneBuilder");
-Background = Java.type("javafx.scene.layout.Background");
-//BackgroundBuilder = Java.type("javafx.scene.layout.BackgroundBuilder");
-BackgroundFill = Java.type("javafx.scene.layout.BackgroundFill");
-//BackgroundFillBuilder = Java.type("javafx.scene.layout.BackgroundFillBuilder");
-BackgroundImage = Java.type("javafx.scene.layout.BackgroundImage");
-//BackgroundImageBuilder = Java.type("javafx.scene.layout.BackgroundImageBuilder");
-BackgroundPosition = Java.type("javafx.scene.layout.BackgroundPosition");
-//BackgroundPositionBuilder = Java.type("javafx.scene.layout.BackgroundPositionBuilder");
-BackgroundRepeat = Java.type("javafx.scene.layout.BackgroundRepeat");
-BackgroundSize = Java.type("javafx.scene.layout.BackgroundSize");
-//BackgroundSizeBuilder = Java.type("javafx.scene.layout.BackgroundSizeBuilder");
-Border = Java.type("javafx.scene.layout.Border");
-//BorderBuilder = Java.type("javafx.scene.layout.BorderBuilder");
-BorderImage = Java.type("javafx.scene.layout.BorderImage");
-//BorderImageBuilder = Java.type("javafx.scene.layout.BorderImageBuilder");
-BorderPane = Java.type("javafx.scene.layout.BorderPane");
-BorderPaneBuilder = Java.type("javafx.scene.layout.BorderPaneBuilder");
-BorderRepeat = Java.type("javafx.scene.layout.BorderRepeat");
-BorderStroke = Java.type("javafx.scene.layout.BorderStroke");
-//BorderStrokeBuilder = Java.type("javafx.scene.layout.BorderStrokeBuilder");
-BorderStrokeStyle = Java.type("javafx.scene.layout.BorderStrokeStyle");
-//BorderStrokeStyleBuilder = Java.type("javafx.scene.layout.BorderStrokeStyleBuilder");
-BorderWidths = Java.type("javafx.scene.layout.BorderWidths");
-//BorderWidthsBuilder = Java.type("javafx.scene.layout.BorderWidthsBuilder");
-ColumnConstraints = Java.type("javafx.scene.layout.ColumnConstraints");
-ColumnConstraintsBuilder = Java.type("javafx.scene.layout.ColumnConstraintsBuilder");
-ConstraintsBase = Java.type("javafx.scene.layout.ConstraintsBase");
-CornerRadii = Java.type("javafx.scene.layout.CornerRadii");
-FlowPane = Java.type("javafx.scene.layout.FlowPane");
-FlowPaneBuilder = Java.type("javafx.scene.layout.FlowPaneBuilder");
-GridPane = Java.type("javafx.scene.layout.GridPane");
-GridPaneBuilder = Java.type("javafx.scene.layout.GridPaneBuilder");
-HBox = Java.type("javafx.scene.layout.HBox");
-HBoxBuilder = Java.type("javafx.scene.layout.HBoxBuilder");
-Pane = Java.type("javafx.scene.layout.Pane");
-PaneBuilder = Java.type("javafx.scene.layout.PaneBuilder");
-Priority = Java.type("javafx.scene.layout.Priority");
-Region = Java.type("javafx.scene.layout.Region");
-RegionBuilder = Java.type("javafx.scene.layout.RegionBuilder");
-RowConstraints = Java.type("javafx.scene.layout.RowConstraints");
-RowConstraintsBuilder = Java.type("javafx.scene.layout.RowConstraintsBuilder");
-StackPane = Java.type("javafx.scene.layout.StackPane");
-StackPaneBuilder = Java.type("javafx.scene.layout.StackPaneBuilder");
-TilePane = Java.type("javafx.scene.layout.TilePane");
-TilePaneBuilder = Java.type("javafx.scene.layout.TilePaneBuilder");
-VBox = Java.type("javafx.scene.layout.VBox");
-VBoxBuilder = Java.type("javafx.scene.layout.VBoxBuilder");
-LightBase = Java.type("javafx.scene.LightBase");
-//LightBaseBuilder = Java.type("javafx.scene.LightBaseBuilder");
-Node = Java.type("javafx.scene.Node");
-NodeBuilder = Java.type("javafx.scene.NodeBuilder");
-Color = Java.type("javafx.scene.paint.Color");
-ColorBuilder = Java.type("javafx.scene.paint.ColorBuilder");
-CycleMethod = Java.type("javafx.scene.paint.CycleMethod");
-ImagePattern = Java.type("javafx.scene.paint.ImagePattern");
-ImagePatternBuilder = Java.type("javafx.scene.paint.ImagePatternBuilder");
-LinearGradient = Java.type("javafx.scene.paint.LinearGradient");
-LinearGradientBuilder = Java.type("javafx.scene.paint.LinearGradientBuilder");
-Material = Java.type("javafx.scene.paint.Material");
-Paint = Java.type("javafx.scene.paint.Paint");
-PhongMaterial = Java.type("javafx.scene.paint.PhongMaterial");
-//PhongMaterialBuilder = Java.type("javafx.scene.paint.PhongMaterialBuilder");
-RadialGradient = Java.type("javafx.scene.paint.RadialGradient");
-RadialGradientBuilder = Java.type("javafx.scene.paint.RadialGradientBuilder");
-Stop = Java.type("javafx.scene.paint.Stop");
-StopBuilder = Java.type("javafx.scene.paint.StopBuilder");
-ParallelCamera = Java.type("javafx.scene.ParallelCamera");
-//ParallelCameraBuilder = Java.type("javafx.scene.ParallelCameraBuilder");
-Parent = Java.type("javafx.scene.Parent");
-ParentBuilder = Java.type("javafx.scene.ParentBuilder");
-PerspectiveCamera = Java.type("javafx.scene.PerspectiveCamera");
-PerspectiveCameraBuilder = Java.type("javafx.scene.PerspectiveCameraBuilder");
-PointLight = Java.type("javafx.scene.PointLight");
-//PointLightBuilder = Java.type("javafx.scene.PointLightBuilder");
-//Scene = Java.type("javafx.scene.Scene");
-SceneBuilder = Java.type("javafx.scene.SceneBuilder");
-Arc = Java.type("javafx.scene.shape.Arc");
-ArcBuilder = Java.type("javafx.scene.shape.ArcBuilder");
-ArcTo = Java.type("javafx.scene.shape.ArcTo");
-ArcToBuilder = Java.type("javafx.scene.shape.ArcToBuilder");
-ArcType = Java.type("javafx.scene.shape.ArcType");
-Box = Java.type("javafx.scene.shape.Box");
-//BoxBuilder = Java.type("javafx.scene.shape.BoxBuilder");
-Circle = Java.type("javafx.scene.shape.Circle");
-CircleBuilder = Java.type("javafx.scene.shape.CircleBuilder");
-ClosePath = Java.type("javafx.scene.shape.ClosePath");
-ClosePathBuilder = Java.type("javafx.scene.shape.ClosePathBuilder");
-CubicCurve = Java.type("javafx.scene.shape.CubicCurve");
-CubicCurveBuilder = Java.type("javafx.scene.shape.CubicCurveBuilder");
-CubicCurveTo = Java.type("javafx.scene.shape.CubicCurveTo");
-CubicCurveToBuilder = Java.type("javafx.scene.shape.CubicCurveToBuilder");
-CullFace = Java.type("javafx.scene.shape.CullFace");
-Cylinder = Java.type("javafx.scene.shape.Cylinder");
-//CylinderBuilder = Java.type("javafx.scene.shape.CylinderBuilder");
-DrawMode = Java.type("javafx.scene.shape.DrawMode");
-Ellipse = Java.type("javafx.scene.shape.Ellipse");
-EllipseBuilder = Java.type("javafx.scene.shape.EllipseBuilder");
-FillRule = Java.type("javafx.scene.shape.FillRule");
-HLineTo = Java.type("javafx.scene.shape.HLineTo");
-HLineToBuilder = Java.type("javafx.scene.shape.HLineToBuilder");
-Line = Java.type("javafx.scene.shape.Line");
-LineBuilder = Java.type("javafx.scene.shape.LineBuilder");
-LineTo = Java.type("javafx.scene.shape.LineTo");
-LineToBuilder = Java.type("javafx.scene.shape.LineToBuilder");
-Mesh = Java.type("javafx.scene.shape.Mesh");
-MeshView = Java.type("javafx.scene.shape.MeshView");
-//MeshViewBuilder = Java.type("javafx.scene.shape.MeshViewBuilder");
-MoveTo = Java.type("javafx.scene.shape.MoveTo");
-MoveToBuilder = Java.type("javafx.scene.shape.MoveToBuilder");
-Path = Java.type("javafx.scene.shape.Path");
-PathBuilder = Java.type("javafx.scene.shape.PathBuilder");
-PathElement = Java.type("javafx.scene.shape.PathElement");
-PathElementBuilder = Java.type("javafx.scene.shape.PathElementBuilder");
-Polygon = Java.type("javafx.scene.shape.Polygon");
-PolygonBuilder = Java.type("javafx.scene.shape.PolygonBuilder");
-Polyline = Java.type("javafx.scene.shape.Polyline");
-PolylineBuilder = Java.type("javafx.scene.shape.PolylineBuilder");
-QuadCurve = Java.type("javafx.scene.shape.QuadCurve");
-QuadCurveBuilder = Java.type("javafx.scene.shape.QuadCurveBuilder");
-QuadCurveTo = Java.type("javafx.scene.shape.QuadCurveTo");
-QuadCurveToBuilder = Java.type("javafx.scene.shape.QuadCurveToBuilder");
-Rectangle = Java.type("javafx.scene.shape.Rectangle");
-RectangleBuilder = Java.type("javafx.scene.shape.RectangleBuilder");
-Shape = Java.type("javafx.scene.shape.Shape");
-Shape3D = Java.type("javafx.scene.shape.Shape3D");
-//Shape3DBuilder = Java.type("javafx.scene.shape.Shape3DBuilder");
-ShapeBuilder = Java.type("javafx.scene.shape.ShapeBuilder");
-Sphere = Java.type("javafx.scene.shape.Sphere");
-//SphereBuilder = Java.type("javafx.scene.shape.SphereBuilder");
-StrokeLineCap = Java.type("javafx.scene.shape.StrokeLineCap");
-StrokeLineJoin = Java.type("javafx.scene.shape.StrokeLineJoin");
-StrokeType = Java.type("javafx.scene.shape.StrokeType");
-SVGPath = Java.type("javafx.scene.shape.SVGPath");
-SVGPathBuilder = Java.type("javafx.scene.shape.SVGPathBuilder");
-TriangleMesh = Java.type("javafx.scene.shape.TriangleMesh");
-VLineTo = Java.type("javafx.scene.shape.VLineTo");
-VLineToBuilder = Java.type("javafx.scene.shape.VLineToBuilder");
-SnapshotParameters = Java.type("javafx.scene.SnapshotParameters");
-SnapshotParametersBuilder = Java.type("javafx.scene.SnapshotParametersBuilder");
-SnapshotResult = Java.type("javafx.scene.SnapshotResult");
-SubScene = Java.type("javafx.scene.SubScene");
-//SubSceneBuilder = Java.type("javafx.scene.SubSceneBuilder");
-Font = Java.type("javafx.scene.text.Font");
-FontBuilder = Java.type("javafx.scene.text.FontBuilder");
-FontPosture = Java.type("javafx.scene.text.FontPosture");
-FontSmoothingType = Java.type("javafx.scene.text.FontSmoothingType");
-FontWeight = Java.type("javafx.scene.text.FontWeight");
-Text = Java.type("javafx.scene.text.Text");
-TextAlignment = Java.type("javafx.scene.text.TextAlignment");
-TextBoundsType = Java.type("javafx.scene.text.TextBoundsType");
-TextBuilder = Java.type("javafx.scene.text.TextBuilder");
-TextFlow = Java.type("javafx.scene.text.TextFlow");
-//TextFlowBuilder = Java.type("javafx.scene.text.TextFlowBuilder");
-Affine = Java.type("javafx.scene.transform.Affine");
-AffineBuilder = Java.type("javafx.scene.transform.AffineBuilder");
-MatrixType = Java.type("javafx.scene.transform.MatrixType");
-NonInvertibleTransformException = Java.type("javafx.scene.transform.NonInvertibleTransformException");
-Rotate = Java.type("javafx.scene.transform.Rotate");
-RotateBuilder = Java.type("javafx.scene.transform.RotateBuilder");
-Scale = Java.type("javafx.scene.transform.Scale");
-ScaleBuilder = Java.type("javafx.scene.transform.ScaleBuilder");
-Shear = Java.type("javafx.scene.transform.Shear");
-ShearBuilder = Java.type("javafx.scene.transform.ShearBuilder");
-Transform = Java.type("javafx.scene.transform.Transform");
-//TransformBuilder = Java.type("javafx.scene.transform.TransformBuilder");
-TransformChangedEvent = Java.type("javafx.scene.transform.TransformChangedEvent");
-Translate = Java.type("javafx.scene.transform.Translate");
-TranslateBuilder = Java.type("javafx.scene.transform.TranslateBuilder");
-DirectoryChooser = Java.type("javafx.stage.DirectoryChooser");
-DirectoryChooserBuilder = Java.type("javafx.stage.DirectoryChooserBuilder");
-FileChooser = Java.type("javafx.stage.FileChooser");
-FileChooser$ExtensionFilter = Java.type("javafx.stage.FileChooser$ExtensionFilter");
-FileChooserBuilder = Java.type("javafx.stage.FileChooserBuilder");
-Modality = Java.type("javafx.stage.Modality");
-Popup = Java.type("javafx.stage.Popup");
-PopupBuilder = Java.type("javafx.stage.PopupBuilder");
-PopupWindow = Java.type("javafx.stage.PopupWindow");
-PopupWindowBuilder = Java.type("javafx.stage.PopupWindowBuilder");
-Screen = Java.type("javafx.stage.Screen");
-//Stage = Java.type("javafx.stage.Stage");
-StageBuilder = Java.type("javafx.stage.StageBuilder");
-StageStyle = Java.type("javafx.stage.StageStyle");
-Window = Java.type("javafx.stage.Window");
-WindowBuilder = Java.type("javafx.stage.WindowBuilder");
-WindowEvent = Java.type("javafx.stage.WindowEvent");
+if (!this.JFX_BASE_CLASSES) {
+ load("fx:base.js")
+}
+LOAD_FX_CLASSES(JFX_GRAPHICS_CLASSES);
+
+
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/media.js Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/media.js Fri Sep 20 19:15:59 2013 -0700
@@ -23,23 +23,8 @@
* questions.
*/
-AudioClip = Java.type("javafx.scene.media.AudioClip");
-AudioClipBuilder = Java.type("javafx.scene.media.AudioClipBuilder");
-AudioEqualizer = Java.type("javafx.scene.media.AudioEqualizer");
-AudioSpectrumListener = Java.type("javafx.scene.media.AudioSpectrumListener");
-AudioTrack = Java.type("javafx.scene.media.AudioTrack");
-EqualizerBand = Java.type("javafx.scene.media.EqualizerBand");
-Media = Java.type("javafx.scene.media.Media");
-MediaBuilder = Java.type("javafx.scene.media.MediaBuilder");
-MediaErrorEvent = Java.type("javafx.scene.media.MediaErrorEvent");
-MediaException = Java.type("javafx.scene.media.MediaException");
-MediaException$Type = Java.type("javafx.scene.media.MediaException$Type");
-MediaMarkerEvent = Java.type("javafx.scene.media.MediaMarkerEvent");
-MediaPlayer = Java.type("javafx.scene.media.MediaPlayer");
-MediaPlayer$Status = Java.type("javafx.scene.media.MediaPlayer$Status");
-MediaPlayerBuilder = Java.type("javafx.scene.media.MediaPlayerBuilder");
-MediaView = Java.type("javafx.scene.media.MediaView");
-MediaViewBuilder = Java.type("javafx.scene.media.MediaViewBuilder");
-SubtitleTrack = Java.type("javafx.scene.media.SubtitleTrack");
-Track = Java.type("javafx.scene.media.Track");
-VideoTrack = Java.type("javafx.scene.media.VideoTrack");
+if (!this.JFX_BASE_CLASSES) {
+ load("fx:base.js")
+}
+
+LOAD_FX_CLASSES(JFX_MEDIA_CLASSES);
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swing.js Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swing.js Fri Sep 20 19:15:59 2013 -0700
@@ -23,7 +23,8 @@
* questions.
*/
-JFXPanel = Java.type("javafx.embed.swing.JFXPanel");
-JFXPanelBuilder = Java.type("javafx.embed.swing.JFXPanelBuilder");
-SwingFXUtils = Java.type("javafx.embed.swing.SwingFXUtils");
-SwingNode = Java.type("javafx.embed.swing.SwingNode");
+if (!this.JFX_BASE_CLASSES) {
+ load("fx:base.js")
+}
+
+LOAD_FX_CLASSES(JFX_SWING_CLASSES);
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swt.js Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swt.js Fri Sep 20 19:15:59 2013 -0700
@@ -23,7 +23,8 @@
* questions.
*/
-CustomTransfer = Java.type("javafx.embed.swt.CustomTransfer");
-//CustomTransferBuilder = Java.type("javafx.embed.swt.CustomTransferBuilder");
-FXCanvas = Java.type("javafx.embed.swt.FXCanvas");
-SWTFXUtils = Java.type("javafx.embed.swt.SWTFXUtils");
+if (!this.JFX_BASE_CLASSES) {
+ load("fx:base.js")
+}
+
+LOAD_FX_CLASSES(JFX_SWT_CLASSES);
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/web.js Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/web.js Fri Sep 20 19:15:59 2013 -0700
@@ -23,14 +23,8 @@
* questions.
*/
-HTMLEditor = Java.type("javafx.scene.web.HTMLEditor");
-//HTMLEditorBuilder = Java.type("javafx.scene.web.HTMLEditorBuilder");
-PopupFeatures = Java.type("javafx.scene.web.PopupFeatures");
-PromptData = Java.type("javafx.scene.web.PromptData");
-//PromptDataBuilder = Java.type("javafx.scene.web.PromptDataBuilder");
-WebEngine = Java.type("javafx.scene.web.WebEngine");
-WebEngineBuilder = Java.type("javafx.scene.web.WebEngineBuilder");
-WebEvent = Java.type("javafx.scene.web.WebEvent");
-WebHistory = Java.type("javafx.scene.web.WebHistory");
-WebView = Java.type("javafx.scene.web.WebView");
-WebViewBuilder = Java.type("javafx.scene.web.WebViewBuilder");
+if (!this.JFX_BASE_CLASSES) {
+ load("fx:base.js")
+}
+
+LOAD_FX_CLASSES(JFX_WEB_CLASSES);
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js Fri Sep 20 19:15:59 2013 -0700
@@ -137,17 +137,6 @@
}
});
-// Object.prototype.__proto__ (read-only)
-Object.defineProperty(Object.prototype, "__proto__", {
- configurable: true, enumerable: false,
- get: function() {
- return Object.getPrototypeOf(this);
- },
- set: function(x) {
- Object.setPrototypeOf(this, x);
- }
-});
-
// Object.prototype.toSource
Object.defineProperty(Object.prototype, "toSource", {
configurable: true, enumerable: false, writable: true,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/8024180/global_var_delete.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * JDK-8024180: Incorrect handling of expression and parent scope in 'with' statements
+ *
+ * @test
+ * @run
+ */
+
+
+this.x = 44;
+
+function func() {
+ with({ }) {
+ print(x);
+ }
+}
+
+func();
+
+// delete global 'x'
+delete this.x;
+
+try {
+ func();
+} catch(e) {
+ // expect ReferenceError
+ print(e);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/8024180/global_var_delete.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,2 @@
+44
+ReferenceError: "x" is not defined
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/8024180/global_var_shadow.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * JDK-8024180: Incorrect handling of expression and parent scope in 'with' statements
+ *
+ * @test
+ * @run
+ */
+
+// global variable is shadowed by with 'expression' property
+var user = { name: 'foo' };
+
+function func(locals) {
+ with (locals) {
+ print(user.name);
+ }
+}
+
+// global user.name 'foo' printed
+func({});
+
+// local user.name 'toto' printed
+func({ user: { name: 'toto' } });
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/8024180/global_var_shadow.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,2 @@
+foo
+toto
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/8024180/scope_no_such_prop.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * JDK-8024180: Incorrect handling of expression and parent scope in 'with' statements
+ *
+ * @test
+ * @run
+ */
+
+// __noSuchProperty__ defined here confuses 'with'
+// results in ReferenceError even when 'with' expression has
+// the property
+
+load("nashorn:mozilla_compat.js")
+
+function func(locals) {
+ with (locals) {
+ print(user.name);
+ }
+}
+
+try {
+ func({});
+} catch (e) {
+ print(e);
+}
+
+// 'toto' expected in the call below
+func({ user: { name: 'toto' } });
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/8024180/scope_no_such_prop.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,2 @@
+ReferenceError: user is not defined
+toto
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/8024180/with_expr_prop_add.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * JDK-8024180: Incorrect handling of expression and parent scope in 'with' statements
+ *
+ * @test
+ * @run
+ */
+
+var obj = {};
+var x = "global x";
+
+// adding property to 'with' xpression object should reflect
+// as variable inside the 'with' block.
+function func() {
+ with(obj) {
+ for (i = 0; i < 2; i++) {
+ print(x);
+ if (i == 0) {
+ obj.x = "obj.x";
+ }
+ }
+ }
+}
+
+func();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/8024180/with_expr_prop_add.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,2 @@
+global x
+obj.x
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/8024180/with_expr_proto_prop_add.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * JDK-8024180: Incorrect handling of expression and parent scope in 'with' statements
+ *
+ * @test
+ * @run
+ */
+
+var p = { };
+var obj = Object.create(p);
+
+var x = "global x";
+
+// adding property to __proto__ of 'with' expression should
+// reflect as a variable immediately.
+function func() {
+ with(obj) {
+ for (i = 0; i < 2; i++) {
+ print(x);
+ if (i == 0) {
+ p.x = "p.x";
+ }
+ }
+ }
+}
+
+func();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/8024180/with_expr_proto_prop_add.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,2 @@
+global x
+p.x
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/8024180/with_java_object.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * JDK-8024180: Incorrect handling of expression and parent scope in 'with' statements
+ *
+ * @test
+ * @run
+ */
+
+// TypeError for with expression being non script object
+try {
+ with(new java.lang.Object()) {}
+} catch (e) {
+ print(e);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/8024180/with_java_object.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,1 @@
+TypeError: Cannot apply "with" to non script object
--- a/nashorn/test/script/basic/JDK-8023368.js Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/test/script/basic/JDK-8023368.js Fri Sep 20 19:15:59 2013 -0700
@@ -28,8 +28,6 @@
* @run
*/
-load("nashorn:mozilla_compat.js");
-
// function to force same callsites
function check(obj) {
print(obj.func());
--- a/nashorn/test/script/basic/JDK-8023368.js.EXPECTED Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/test/script/basic/JDK-8023368.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -4,15 +4,15 @@
Func.prototype.func
hello
[object Object]
-obj.__proto__.func @ 57
+obj.__proto__.func @ 55
344
[object Object]
-obj.__proto__.func @ 57
+obj.__proto__.func @ 55
344
[object Object]
-obj.__proto__.func @ 57
+obj.__proto__.func @ 55
344
new object.toString
-obj.__proto__.func @ 57
+obj.__proto__.func @ 55
344
new object.toString
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8024120.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * JDK-8024120: Setting __proto__ to null removes the __proto__ property
+ *
+ * @test
+ * @run
+ */
+
+var obj = {};
+
+obj.__proto__ = null;
+
+if (obj.__proto__ !== null || typeof(obj.__proto__) != 'object') {
+ fail("obj.__proto__ is expected to be null");
+}
+
+var p = Object.getPrototypeOf(obj);
+if (p !== null || typeof(p) != 'object') {
+ fail("Object.getPrototypeOf(obj) is expected to be null");
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8024174.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * JDK-8024174: Setting __proto__ property in Object literal should be supported *
+ * @test
+ * @run
+ */
+
+var p = { foo: function() { print("p.foo"); } };
+
+var obj = {
+ __proto__ : p,
+ bar: 44
+};
+
+if (obj.__proto__ !== p || Object.getPrototypeOf(obj) !== p) {
+ fail("obj.__proto__ was not set inside literal");
+}
+
+if (typeof(obj.foo) !== 'function' || obj.foo !== p.foo) {
+ fail("'obj' failed to inherit 'foo' from 'p'");
+}
+
+var obj2 = {
+ __proto__: null
+};
+
+if (obj2.__proto__ !== null || Object.getPrototypeOf(obj2) !== null) {
+ fail("obj2.__proto__ was not set to null inside literal");
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8024255.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * JDK-8024255: When a keyword is used as object property name, the property can not be deleted
+ *
+ * @test
+ * @run
+ */
+
+function check(obj, name) {
+ var desc = Object.getOwnPropertyDescriptor(obj, name);
+ if (! desc.configurable) {
+ fail("Property " + name + " is not configurable");
+ }
+
+ if (! (delete obj[name])) {
+ fail("Property " + name + " can not be deleted");
+ }
+}
+
+var obj = {
+ default: 344,
+ in: 'hello',
+ if: false,
+ class: 4.223
+}
+
+for (var p in obj) {
+ check(obj, p);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8024512.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * JDK-8024512: Regex /[^\[]/ doesn't match
+ *
+ * @test
+ * @run
+ */
+
+print("[M]".match(/(\[[^\[]*\])/));
+print("[[]".match(/(\[[^\[]*\])/));
+
+print("[M]".match(/(\[[^\[^]*\])/));
+print("[[]".match(/(\[[^\[^]*\])/));
+print("[^]".match(/(\[[^\[^]*\])/));
+
+print("[M]".match(/(\[[^\[]\])/));
+print("[[]".match(/(\[[^\[]\])/));
+
+print("[M]".match(/(\[[^\[^]\])/));
+print("[[]".match(/(\[[^\[^]\])/));
+print("[^]".match(/(\[[^\[^]\])/));
+
+print("M".match(/[^\[]/));
+print("[".match(/[^\[]/));
+print("^".match(/[^\[]/));
+
+// Repeat above without escaping inner square bracket
+print("[M]".match(/(\[[^[]\])/));
+print("[[]".match(/(\[[^[]\])/));
+
+print("[M]".match(/(\[[^[^]\])/));
+print("[[]".match(/(\[[^[^]\])/));
+print("[^]".match(/(\[[^[^]\])/));
+
+print("M".match(/[^[]/));
+print("[".match(/[^[]/));
+print("^".match(/[^[]/));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8024512.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,21 @@
+[M],[M]
+[],[]
+[M],[M]
+[],[]
+null
+[M],[M]
+null
+[M],[M]
+null
+null
+M
+null
+^
+[M],[M]
+null
+[M],[M]
+null
+null
+M
+null
+^
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8024619.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * JDK-8024619: JDBC java.sql.DriverManager is not usable from JS script
+ *
+ * @test
+ * @run
+ */
+
+var DriverManager = Java.type("java.sql.DriverManager");
+var e = DriverManager.getDrivers();
+
+var driverFound = false;
+// check for Nashorn SQL driver
+while (e.hasMoreElements()) {
+ var driver = e.nextElement();
+ if (driver.acceptsURL("jdbc:nashorn:")) {
+ driverFound = true;
+ break;
+ }
+}
+
+if (! driverFound) {
+ fail("Nashorn JDBC Driver not found!");
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8024846.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * JDK-8024846: keep separate internal arguments variable
+ *
+ * @test
+ */
+
+function f() { print(arguments); }
+
+function func(obj) {
+ var arguments = obj;
+ for (var i in arguments) {
+ }
+ return obj;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8024847.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * JDK-8024847: Java.to should accept mirror and external JSObjects as array-like objects as well
+ *
+ * @test
+ * @run
+ */
+
+var global = loadWithNewGlobal({ name: "test", script:"this" });
+var arr = new global.Array(2, 4, 6, 8);
+var jarr = Java.to(arr, "int[]");
+for (var i in jarr) {
+ print(jarr[i]);
+}
+
+arr = null;
+jarr = null;
+
+// external JSObjects
+var JSObject = Java.type("jdk.nashorn.api.scripting.JSObject");
+var arr = new JSObject() {
+ getMember: function(name) {
+ return name == "length"? 4 : undefined;
+ },
+
+ hasMember: function(name) {
+ return name == "length";
+ },
+
+ getSlot: function(idx) {
+ return idx*idx;
+ },
+
+ hasSlot: function(idx) {
+ return true;
+ }
+};
+
+var jarr = Java.to(arr, "int[]");
+for (var i in jarr) {
+ print(jarr[i]);
+}
+
+arr = null;
+jarr = null;
+
+// List conversion
+var arr = global.Array("hello", "world");
+var jlist = Java.to(arr, java.util.List);
+print(jlist instanceof java.util.List);
+print(jlist);
+
+arr = null;
+jlist = null;
+
+// external JSObject
+var __array__ = [ "nashorn", "js" ];
+
+var obj = new JSObject() {
+
+ hasMember: function(name) {
+ return name in __array__;
+ },
+
+ hasSlot: function(idx) {
+ return idx in __array__;
+ },
+
+ getMember: function(name) {
+ return __array__[name];
+ },
+
+ getSlot: function(idx) {
+ return __array__[idx];
+ }
+}
+
+var jlist = Java.to(obj, java.util.List);
+print(jlist instanceof java.util.List);
+print(jlist);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8024847.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,12 @@
+2
+4
+6
+8
+0
+1
+4
+9
+true
+[hello, world]
+true
+[nashorn, js]
--- a/nashorn/test/script/basic/NASHORN-737.js Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/test/script/basic/NASHORN-737.js Fri Sep 20 19:15:59 2013 -0700
@@ -30,4 +30,4 @@
load("nashorn:parser.js");
var ast = parse("label: while(true) break label;");
-print(JSON.stringify(ast));
+print(JSON.stringify(ast, null, " "));
--- a/nashorn/test/script/basic/NASHORN-737.js.EXPECTED Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/test/script/basic/NASHORN-737.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -1,1 +1,36 @@
-{"type":"Program","rest":null,"body":[{"type":"LabeledStatement","label":{"type":"Identifier","name":"label"},"body":{"type":"BlockStatement","body":[{"type":"WhileStatement","test":{"type":"Literal","value":true},"block":{"type":"BlockStatement","body":[{"type":"BreakStatement","label":"label"}]}}]}}]}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "LabeledStatement",
+ "label": {
+ "type": "Identifier",
+ "name": "label"
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "WhileStatement",
+ "test": {
+ "type": "Literal",
+ "value": true
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "BreakStatement",
+ "label": {
+ "type": "Identifier",
+ "name": "label"
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
--- a/nashorn/test/script/basic/circular_proto.js Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/test/script/basic/circular_proto.js Fri Sep 20 19:15:59 2013 -0700
@@ -29,7 +29,6 @@
*/
// check that we cannot create __proto__ cycle
-load("nashorn:mozilla_compat.js");
var obj = {};
var obj2 = Object.create(obj);
--- a/nashorn/test/script/basic/nonextensible_proto_assign.js Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/test/script/basic/nonextensible_proto_assign.js Fri Sep 20 19:15:59 2013 -0700
@@ -28,8 +28,6 @@
* @run
*/
-load("nashorn:mozilla_compat.js")
-
// check that we cannot assign to __proto__ of a non-extensible object
try {
var obj = {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/assignmentExpr.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests to check assignment e xyzpressions.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("xyz = 314");
+printParse("xyz += 314");
+printParse("xyz -= 314");
+printParse("xyz *= 314");
+printParse("xyz /= 314");
+printParse("xyz %= 314");
+printParse("xyz <<= 314");
+printParse("xyz >>= 314");
+printParse("xyz >>>= 314");
+printParse("xyz &= 314");
+printParse("xyz ^= 314");
+printParse("xyz |= 314");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/assignmentExpr.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,240 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "AssignmentExpression",
+ "operator": "=",
+ "left": {
+ "type": "Identifier",
+ "name": "xyz"
+ },
+ "right": {
+ "type": "Literal",
+ "value": 314
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "AssignmentExpression",
+ "operator": "+=",
+ "left": {
+ "type": "Identifier",
+ "name": "xyz"
+ },
+ "right": {
+ "type": "Literal",
+ "value": 314
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "AssignmentExpression",
+ "operator": "-=",
+ "left": {
+ "type": "Identifier",
+ "name": "xyz"
+ },
+ "right": {
+ "type": "Literal",
+ "value": 314
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "AssignmentExpression",
+ "operator": "*=",
+ "left": {
+ "type": "Identifier",
+ "name": "xyz"
+ },
+ "right": {
+ "type": "Literal",
+ "value": 314
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "AssignmentExpression",
+ "operator": "/=",
+ "left": {
+ "type": "Identifier",
+ "name": "xyz"
+ },
+ "right": {
+ "type": "Literal",
+ "value": 314
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "AssignmentExpression",
+ "operator": "%=",
+ "left": {
+ "type": "Identifier",
+ "name": "xyz"
+ },
+ "right": {
+ "type": "Literal",
+ "value": 314
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "AssignmentExpression",
+ "operator": "<<=",
+ "left": {
+ "type": "Identifier",
+ "name": "xyz"
+ },
+ "right": {
+ "type": "Literal",
+ "value": 314
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "AssignmentExpression",
+ "operator": ">>=",
+ "left": {
+ "type": "Identifier",
+ "name": "xyz"
+ },
+ "right": {
+ "type": "Literal",
+ "value": 314
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "AssignmentExpression",
+ "operator": ">>>=",
+ "left": {
+ "type": "Identifier",
+ "name": "xyz"
+ },
+ "right": {
+ "type": "Literal",
+ "value": 314
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "AssignmentExpression",
+ "operator": "&=",
+ "left": {
+ "type": "Identifier",
+ "name": "xyz"
+ },
+ "right": {
+ "type": "Literal",
+ "value": 314
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "AssignmentExpression",
+ "operator": "^=",
+ "left": {
+ "type": "Identifier",
+ "name": "xyz"
+ },
+ "right": {
+ "type": "Literal",
+ "value": 314
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "AssignmentExpression",
+ "operator": "|=",
+ "left": {
+ "type": "Identifier",
+ "name": "xyz"
+ },
+ "right": {
+ "type": "Literal",
+ "value": 314
+ }
+ }
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/binaryExpr.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests to check binary operators.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("a * b")
+printParse("a / b");
+printParse("a % b");
+printParse("a + b");
+printParse("a - b");
+printParse("a << b");
+printParse("a >> b");
+printParse("a >>> b");
+printParse("a < b");
+printParse("a > b");
+printParse("a <= b");
+printParse("a >= b");
+printParse("a instanceof b");
+printParse("a == b");
+printParse("a != b");
+printParse("a === b");
+printParse("a !== b");
+printParse("a & b");
+printParse("a ^ b");
+printParse("a | b");
+printParse("a && b");
+printParse("a || b");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/binaryExpr.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,440 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "*",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "/",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "%",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "+",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "-",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "<<",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": ">>",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": ">>>",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "<",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": ">",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "<=",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": ">=",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "instanceof",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "==",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "!=",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "===",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "!==",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "&",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "^",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "|",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "LogicalExpression",
+ "operator": "&&",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "LogicalExpression",
+ "operator": "||",
+ "left": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "b"
+ }
+ }
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/breakStat.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests to check 'break' statement.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("while (true) { break; }");
+printParse("loop: { while (true) { break loop } }");
+printParse("loop: { for (;;) { break loop } }");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/breakStat.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,92 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "WhileStatement",
+ "test": {
+ "type": "Literal",
+ "value": true
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "BreakStatement",
+ "label": null
+ }
+ ]
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "LabeledStatement",
+ "label": {
+ "type": "Identifier",
+ "name": "loop"
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "WhileStatement",
+ "test": {
+ "type": "Literal",
+ "value": true
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "BreakStatement",
+ "label": {
+ "type": "Identifier",
+ "name": "loop"
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "LabeledStatement",
+ "label": {
+ "type": "Identifier",
+ "name": "loop"
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ForStatement",
+ "init": null,
+ "test": null,
+ "update": null,
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "BreakStatement",
+ "label": {
+ "type": "Identifier",
+ "name": "loop"
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/condExpr.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests to check ternary operator.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("a? b : c");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/condExpr.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,23 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "ConditionalExpression",
+ "test": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "consequent": {
+ "type": "Identifier",
+ "name": "b"
+ },
+ "alternate": {
+ "type": "Identifier",
+ "name": "c"
+ }
+ }
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/continueStat.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests to check 'continue' statement.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("while (true) { continue; }");
+printParse("begin: { while (true) { continue begin; } }");
+printParse("start: { for(;;) { continue start; } }");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/continueStat.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,92 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "WhileStatement",
+ "test": {
+ "type": "Literal",
+ "value": true
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ContinueStatement",
+ "label": null
+ }
+ ]
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "LabeledStatement",
+ "label": {
+ "type": "Identifier",
+ "name": "begin"
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "WhileStatement",
+ "test": {
+ "type": "Literal",
+ "value": true
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ContinueStatement",
+ "label": {
+ "type": "Identifier",
+ "name": "begin"
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "LabeledStatement",
+ "label": {
+ "type": "Identifier",
+ "name": "start"
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ForStatement",
+ "init": null,
+ "test": null,
+ "update": null,
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ContinueStatement",
+ "label": {
+ "type": "Identifier",
+ "name": "start"
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/debuggerStat.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests to check debugger statement.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("debugger");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/debuggerStat.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,8 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "DebuggerStatement"
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/functions.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests to check 'function' statements and expressions.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("function hello() { print('hello') }")
+printParse("function hello(a) { print(a) }")
+printParse("function hello(a, b) { print(a, b) }")
+printParse("var hello = function() { print('hello') };")
+printParse("var hello = function hello() { print('hello') };")
+printParse("(function(){})")
+printParse("function test() { 'use strict' }");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/functions.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,279 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "FunctionDeclaration",
+ "id": {
+ "type": "Identifier",
+ "name": "hello"
+ },
+ "params": [],
+ "defaults": [],
+ "rest": null,
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "print"
+ },
+ "arguments": [
+ {
+ "type": "Literal",
+ "value": "hello"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "generator": false,
+ "expression": false
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "FunctionDeclaration",
+ "id": {
+ "type": "Identifier",
+ "name": "hello"
+ },
+ "params": [
+ {
+ "type": "Identifier",
+ "name": "a"
+ }
+ ],
+ "defaults": [],
+ "rest": null,
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "print"
+ },
+ "arguments": [
+ {
+ "type": "Identifier",
+ "name": "a"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "generator": false,
+ "expression": false
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "FunctionDeclaration",
+ "id": {
+ "type": "Identifier",
+ "name": "hello"
+ },
+ "params": [
+ {
+ "type": "Identifier",
+ "name": "a"
+ },
+ {
+ "type": "Identifier",
+ "name": "b"
+ }
+ ],
+ "defaults": [],
+ "rest": null,
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "print"
+ },
+ "arguments": [
+ {
+ "type": "Identifier",
+ "name": "a"
+ },
+ {
+ "type": "Identifier",
+ "name": "b"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "generator": false,
+ "expression": false
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "VariableDeclaration",
+ "declarations": [
+ {
+ "type": "VariableDeclarator",
+ "id": {
+ "type": "Identifier",
+ "name": "hello"
+ },
+ "init": {
+ "type": "FunctionExpression",
+ "id": null,
+ "params": [],
+ "defaults": [],
+ "rest": null,
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "print"
+ },
+ "arguments": [
+ {
+ "type": "Literal",
+ "value": "hello"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "generator": false,
+ "expression": false
+ }
+ }
+ ]
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "VariableDeclaration",
+ "declarations": [
+ {
+ "type": "VariableDeclarator",
+ "id": {
+ "type": "Identifier",
+ "name": "hello"
+ },
+ "init": {
+ "type": "FunctionExpression",
+ "id": {
+ "type": "Identifier",
+ "name": "hello"
+ },
+ "params": [],
+ "defaults": [],
+ "rest": null,
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "print"
+ },
+ "arguments": [
+ {
+ "type": "Literal",
+ "value": "hello"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "generator": false,
+ "expression": false
+ }
+ }
+ ]
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "FunctionExpression",
+ "id": null,
+ "params": [],
+ "defaults": [],
+ "rest": null,
+ "body": {
+ "type": "BlockStatement",
+ "body": []
+ },
+ "generator": false,
+ "expression": false
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "FunctionDeclaration",
+ "id": {
+ "type": "Identifier",
+ "name": "test"
+ },
+ "params": [],
+ "defaults": [],
+ "rest": null,
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "Literal",
+ "value": "use strict"
+ }
+ }
+ ]
+ },
+ "generator": false,
+ "expression": false
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/ifStat.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests to check 'if' statement.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("if (js) { nashorn() }");
+printParse("if (js) { nashorn() } else { java() }");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/ifStat.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,73 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "IfStatement",
+ "test": {
+ "type": "Identifier",
+ "name": "js"
+ },
+ "consequent": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "nashorn"
+ },
+ "arguments": []
+ }
+ }
+ ]
+ },
+ "alternate": null
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "IfStatement",
+ "test": {
+ "type": "Identifier",
+ "name": "js"
+ },
+ "consequent": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "nashorn"
+ },
+ "arguments": []
+ }
+ }
+ ]
+ },
+ "alternate": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "java"
+ },
+ "arguments": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/labelledStat.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2010, 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 for labelled statements.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("begin: { for (;;) break begin }");
+printParse("begin: { while (true) break begin }");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/labelledStat.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,71 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "LabeledStatement",
+ "label": {
+ "type": "Identifier",
+ "name": "begin"
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ForStatement",
+ "init": null,
+ "test": null,
+ "update": null,
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "BreakStatement",
+ "label": {
+ "type": "Identifier",
+ "name": "begin"
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "LabeledStatement",
+ "label": {
+ "type": "Identifier",
+ "name": "begin"
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "WhileStatement",
+ "test": {
+ "type": "Literal",
+ "value": true
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "BreakStatement",
+ "label": {
+ "type": "Identifier",
+ "name": "begin"
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/lhsExpr.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests to check left-hand-side expressions
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("a[3]");
+printParse("a[b]");
+printParse("a['foo']");
+printParse("obj.foo");
+printParse("obj.foo.bar");
+printParse("new Type");
+printParse("new Type()");
+printParse("new Type(a, 'hello')");
+printParse("new obj.Type");
+printParse("new obj.Type()");
+printParse("new obj.Type(a, 'hello')");
+printParse("foo()")
+printParse("obj.foo()");
+printParse("foo(a,b)");
+printParse("obj.foo(a, b)");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/lhsExpr.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,344 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "MemberExpression",
+ "object": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "property": {
+ "type": "Literal",
+ "value": 3
+ },
+ "computed": true
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "MemberExpression",
+ "object": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "property": {
+ "type": "Identifier",
+ "name": "b"
+ },
+ "computed": true
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "MemberExpression",
+ "object": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "property": {
+ "type": "Literal",
+ "value": "foo"
+ },
+ "computed": true
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "MemberExpression",
+ "object": {
+ "type": "Identifier",
+ "name": "obj"
+ },
+ "property": {
+ "type": "Identifier",
+ "name": "foo"
+ },
+ "computed": false
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "MemberExpression",
+ "object": {
+ "type": "MemberExpression",
+ "object": {
+ "type": "Identifier",
+ "name": "obj"
+ },
+ "property": {
+ "type": "Identifier",
+ "name": "foo"
+ },
+ "computed": false
+ },
+ "property": {
+ "type": "Identifier",
+ "name": "bar"
+ },
+ "computed": false
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "NewExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "Type"
+ },
+ "arguments": []
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "NewExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "Type"
+ },
+ "arguments": []
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "NewExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "Type"
+ },
+ "arguments": [
+ {
+ "type": "Identifier",
+ "name": "a"
+ },
+ {
+ "type": "Literal",
+ "value": "hello"
+ }
+ ]
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "NewExpression",
+ "callee": {
+ "type": "MemberExpression",
+ "object": {
+ "type": "Identifier",
+ "name": "obj"
+ },
+ "property": {
+ "type": "Identifier",
+ "name": "Type"
+ },
+ "computed": false
+ },
+ "arguments": []
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "NewExpression",
+ "callee": {
+ "type": "MemberExpression",
+ "object": {
+ "type": "Identifier",
+ "name": "obj"
+ },
+ "property": {
+ "type": "Identifier",
+ "name": "Type"
+ },
+ "computed": false
+ },
+ "arguments": []
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "NewExpression",
+ "callee": {
+ "type": "MemberExpression",
+ "object": {
+ "type": "Identifier",
+ "name": "obj"
+ },
+ "property": {
+ "type": "Identifier",
+ "name": "Type"
+ },
+ "computed": false
+ },
+ "arguments": [
+ {
+ "type": "Identifier",
+ "name": "a"
+ },
+ {
+ "type": "Literal",
+ "value": "hello"
+ }
+ ]
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "foo"
+ },
+ "arguments": []
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "MemberExpression",
+ "object": {
+ "type": "Identifier",
+ "name": "obj"
+ },
+ "property": {
+ "type": "Identifier",
+ "name": "foo"
+ },
+ "computed": false
+ },
+ "arguments": []
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "foo"
+ },
+ "arguments": [
+ {
+ "type": "Identifier",
+ "name": "a"
+ },
+ {
+ "type": "Identifier",
+ "name": "b"
+ }
+ ]
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "MemberExpression",
+ "object": {
+ "type": "Identifier",
+ "name": "obj"
+ },
+ "property": {
+ "type": "Identifier",
+ "name": "foo"
+ },
+ "computed": false
+ },
+ "arguments": [
+ {
+ "type": "Identifier",
+ "name": "a"
+ },
+ {
+ "type": "Identifier",
+ "name": "b"
+ }
+ ]
+ }
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/loopStat.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests for loop statements.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("while(true) { print('hello') }")
+printParse("do { print('hello') } while(true)")
+printParse("for (i in obj) { print(obj[i]) }")
+printParse("for each (i in obj) { print(i) }")
+printParse("for (i = 0; i < 10; i++) { print(i) }")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/loopStat.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,212 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "WhileStatement",
+ "test": {
+ "type": "Literal",
+ "value": true
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "print"
+ },
+ "arguments": [
+ {
+ "type": "Literal",
+ "value": "hello"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "DoWhileStatement",
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "print"
+ },
+ "arguments": [
+ {
+ "type": "Literal",
+ "value": "hello"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "test": {
+ "type": "Literal",
+ "value": true
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ForInStatement",
+ "left": {
+ "type": "Identifier",
+ "name": "i"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "obj"
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "print"
+ },
+ "arguments": [
+ {
+ "type": "MemberExpression",
+ "object": {
+ "type": "Identifier",
+ "name": "obj"
+ },
+ "property": {
+ "type": "Identifier",
+ "name": "i"
+ },
+ "computed": true
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "each": false
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ForInStatement",
+ "left": {
+ "type": "Identifier",
+ "name": "i"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "obj"
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "print"
+ },
+ "arguments": [
+ {
+ "type": "Identifier",
+ "name": "i"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "each": true
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ForStatement",
+ "init": {
+ "type": "AssignmentExpression",
+ "operator": "=",
+ "left": {
+ "type": "Identifier",
+ "name": "i"
+ },
+ "right": {
+ "type": "Literal",
+ "value": 0
+ }
+ },
+ "test": {
+ "type": "BinaryExpression",
+ "operator": "<",
+ "left": {
+ "type": "Identifier",
+ "name": "i"
+ },
+ "right": {
+ "type": "Literal",
+ "value": 10
+ }
+ },
+ "update": {
+ "type": "UpdateExpression",
+ "operator": "++",
+ "prefix": false,
+ "argument": {
+ "type": "Identifier",
+ "name": "i"
+ }
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "print"
+ },
+ "arguments": [
+ {
+ "type": "Identifier",
+ "name": "i"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/objectLitExpr.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests to check assignment e xyzpressions.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("obj = {}");
+printParse("p = { x: 10, y: 2 }");
+printParse("p = { 'x': 10, 'y': 2 }");
+printParse("p = { get x() { return xValue }, get y() { return yValue } }");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/objectLitExpr.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,189 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "AssignmentExpression",
+ "operator": "=",
+ "left": {
+ "type": "Identifier",
+ "name": "obj"
+ },
+ "right": {
+ "type": "ObjectExpression",
+ "properties": []
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "AssignmentExpression",
+ "operator": "=",
+ "left": {
+ "type": "Identifier",
+ "name": "p"
+ },
+ "right": {
+ "type": "ObjectExpression",
+ "properties": [
+ {
+ "key": {
+ "type": "Identifier",
+ "name": "x"
+ },
+ "value": {
+ "type": "Literal",
+ "value": 10
+ },
+ "kind": "init"
+ },
+ {
+ "key": {
+ "type": "Identifier",
+ "name": "y"
+ },
+ "value": {
+ "type": "Literal",
+ "value": 2
+ },
+ "kind": "init"
+ }
+ ]
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "AssignmentExpression",
+ "operator": "=",
+ "left": {
+ "type": "Identifier",
+ "name": "p"
+ },
+ "right": {
+ "type": "ObjectExpression",
+ "properties": [
+ {
+ "key": {
+ "type": "Literal",
+ "value": "x"
+ },
+ "value": {
+ "type": "Literal",
+ "value": 10
+ },
+ "kind": "init"
+ },
+ {
+ "key": {
+ "type": "Literal",
+ "value": "y"
+ },
+ "value": {
+ "type": "Literal",
+ "value": 2
+ },
+ "kind": "init"
+ }
+ ]
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "AssignmentExpression",
+ "operator": "=",
+ "left": {
+ "type": "Identifier",
+ "name": "p"
+ },
+ "right": {
+ "type": "ObjectExpression",
+ "properties": [
+ {
+ "key": {
+ "type": "Identifier",
+ "name": "x"
+ },
+ "value": {
+ "type": "FunctionExpression",
+ "id": {
+ "type": "Identifier",
+ "name": "get x"
+ },
+ "params": [],
+ "defaults": [],
+ "rest": null,
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ReturnStatement",
+ "argument": {
+ "type": "Identifier",
+ "name": "xValue"
+ }
+ }
+ ]
+ },
+ "generator": false,
+ "expression": false
+ },
+ "kind": "get"
+ },
+ {
+ "key": {
+ "type": "Identifier",
+ "name": "y"
+ },
+ "value": {
+ "type": "FunctionExpression",
+ "id": {
+ "type": "Identifier",
+ "name": "get y"
+ },
+ "params": [],
+ "defaults": [],
+ "rest": null,
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ReturnStatement",
+ "argument": {
+ "type": "Identifier",
+ "name": "yValue"
+ }
+ }
+ ]
+ },
+ "generator": false,
+ "expression": false
+ },
+ "kind": "get"
+ }
+ ]
+ }
+ }
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/parenExpr.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests for parenthesis expressions.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("(2) + (1) + 4");
+printParse("3 + (7) << (5)");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/parenExpr.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,56 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "+",
+ "left": {
+ "type": "BinaryExpression",
+ "operator": "+",
+ "left": {
+ "type": "Literal",
+ "value": 2
+ },
+ "right": {
+ "type": "Literal",
+ "value": 1
+ }
+ },
+ "right": {
+ "type": "Literal",
+ "value": 4
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "<<",
+ "left": {
+ "type": "BinaryExpression",
+ "operator": "+",
+ "left": {
+ "type": "Literal",
+ "value": 3
+ },
+ "right": {
+ "type": "Literal",
+ "value": 7
+ }
+ },
+ "right": {
+ "type": "Literal",
+ "value": 5
+ }
+ }
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/primaryExpr.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests to check primary expressions.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("this");
+printParse("foo");
+printParse("null");
+printParse("true");
+printParse("false");
+printParse("33");
+printParse("3.14");
+printParse("(10 + 3)*2");
+printParse("({})");
+printParse("({ x: 3 })");
+printParse("[]");
+printParse("[,,]");
+printParse("[4, 5, 5]");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/primaryExpr.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,199 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "ThisExpression"
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "Identifier",
+ "name": "foo"
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "Literal",
+ "value": null
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "Literal",
+ "value": true
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "Literal",
+ "value": false
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "Literal",
+ "value": 33
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "Literal",
+ "value": 3.14
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "BinaryExpression",
+ "operator": "*",
+ "left": {
+ "type": "BinaryExpression",
+ "operator": "+",
+ "left": {
+ "type": "Literal",
+ "value": 10
+ },
+ "right": {
+ "type": "Literal",
+ "value": 3
+ }
+ },
+ "right": {
+ "type": "Literal",
+ "value": 2
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "ObjectExpression",
+ "properties": []
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "ObjectExpression",
+ "properties": [
+ {
+ "key": {
+ "type": "Identifier",
+ "name": "x"
+ },
+ "value": {
+ "type": "Literal",
+ "value": 3
+ },
+ "kind": "init"
+ }
+ ]
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "ArrayExpression",
+ "elements": []
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "ArrayExpression",
+ "elements": [
+ null,
+ null
+ ]
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "ArrayExpression",
+ "elements": [
+ {
+ "type": "Literal",
+ "value": 4
+ },
+ {
+ "type": "Literal",
+ "value": 5
+ },
+ {
+ "type": "Literal",
+ "value": 5
+ }
+ ]
+ }
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/returnStat.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests to check 'return' statement.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("(function() { return })");
+printParse("(function() { return res })");
+printParse("(function() { return foo() })");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/returnStat.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,88 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "FunctionExpression",
+ "id": null,
+ "params": [],
+ "defaults": [],
+ "rest": null,
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ReturnStatement",
+ "argument": null
+ }
+ ]
+ },
+ "generator": false,
+ "expression": false
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "FunctionExpression",
+ "id": null,
+ "params": [],
+ "defaults": [],
+ "rest": null,
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ReturnStatement",
+ "argument": {
+ "type": "Identifier",
+ "name": "res"
+ }
+ }
+ ]
+ },
+ "generator": false,
+ "expression": false
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "FunctionExpression",
+ "id": null,
+ "params": [],
+ "defaults": [],
+ "rest": null,
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ReturnStatement",
+ "argument": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "foo"
+ },
+ "arguments": []
+ }
+ }
+ ]
+ },
+ "generator": false,
+ "expression": false
+ }
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/switchStat.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests for switch statement.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("switch (key) {}");
+printParse("switch (key) { case 2: hello(); break; }");
+printParse("switch (key) { case 4: hello(); break; case 2: world(); break; default: break }");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/switchStat.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,123 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "SwitchStatement",
+ "discriminant": {
+ "type": "Identifier",
+ "name": "key"
+ },
+ "cases": []
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "SwitchStatement",
+ "discriminant": {
+ "type": "Identifier",
+ "name": "key"
+ },
+ "cases": [
+ {
+ "type": "SwitchCase",
+ "test": {
+ "type": "Literal",
+ "value": 2
+ },
+ "consequent": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "hello"
+ },
+ "arguments": []
+ }
+ },
+ {
+ "type": "BreakStatement",
+ "label": null
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "SwitchStatement",
+ "discriminant": {
+ "type": "Identifier",
+ "name": "key"
+ },
+ "cases": [
+ {
+ "type": "SwitchCase",
+ "test": {
+ "type": "Literal",
+ "value": 4
+ },
+ "consequent": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "hello"
+ },
+ "arguments": []
+ }
+ },
+ {
+ "type": "BreakStatement",
+ "label": null
+ }
+ ]
+ },
+ {
+ "type": "SwitchCase",
+ "test": {
+ "type": "Literal",
+ "value": 2
+ },
+ "consequent": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "world"
+ },
+ "arguments": []
+ }
+ },
+ {
+ "type": "BreakStatement",
+ "label": null
+ }
+ ]
+ },
+ {
+ "type": "SwitchCase",
+ "test": null,
+ "consequent": [
+ {
+ "type": "BreakStatement",
+ "label": null
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/throwStat.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests for throw statement.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("throw err");
+printParse("throw 'wrong'");
+printParse("throw new TypeError");
+printParse("throw new TypeError('not an array')");
+printParse("throw { msg: 'wrong!' }");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/throwStat.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,85 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ThrowStatement",
+ "argument": {
+ "type": "Identifier",
+ "name": "err"
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ThrowStatement",
+ "argument": {
+ "type": "Literal",
+ "value": "wrong"
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ThrowStatement",
+ "argument": {
+ "type": "NewExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "TypeError"
+ },
+ "arguments": []
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ThrowStatement",
+ "argument": {
+ "type": "NewExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "TypeError"
+ },
+ "arguments": [
+ {
+ "type": "Literal",
+ "value": "not an array"
+ }
+ ]
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ThrowStatement",
+ "argument": {
+ "type": "ObjectExpression",
+ "properties": [
+ {
+ "key": {
+ "type": "Identifier",
+ "name": "msg"
+ },
+ "value": {
+ "type": "Literal",
+ "value": "wrong!"
+ },
+ "kind": "init"
+ }
+ ]
+ }
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/tryCatchStat.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests to check try..catch statements.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("try { } catch (e) { }");
+printParse("try { } catch (e) { } finally {}");
+printParse("try { } finally {}");
+printParse("try { } catch (e) { handle() }");
+printParse("try { that() } catch (e) { handle() } finally { clean() }");
+printParse("try { that() } catch (e if e instanceof TypeError) { handle() } catch (e) { rest() }");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/tryCatchStat.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,305 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "BlockStatement",
+ "block": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "TryStatement",
+ "block": {
+ "type": "BlockStatement",
+ "body": []
+ },
+ "guardedHandlers": [],
+ "handler": {
+ "type": "CatchClause",
+ "param": {
+ "type": "Identifier",
+ "name": "e"
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": []
+ }
+ },
+ "finalizer": null
+ }
+ ]
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "BlockStatement",
+ "block": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "TryStatement",
+ "block": {
+ "type": "BlockStatement",
+ "body": []
+ },
+ "guardedHandlers": [],
+ "handler": {
+ "type": "CatchClause",
+ "param": {
+ "type": "Identifier",
+ "name": "e"
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": []
+ }
+ },
+ "finalizer": {
+ "type": "BlockStatement",
+ "body": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "BlockStatement",
+ "block": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "TryStatement",
+ "block": {
+ "type": "BlockStatement",
+ "body": []
+ },
+ "guardedHandlers": [],
+ "handler": null,
+ "finalizer": {
+ "type": "BlockStatement",
+ "body": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "BlockStatement",
+ "block": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "TryStatement",
+ "block": {
+ "type": "BlockStatement",
+ "body": []
+ },
+ "guardedHandlers": [],
+ "handler": {
+ "type": "CatchClause",
+ "param": {
+ "type": "Identifier",
+ "name": "e"
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "handle"
+ },
+ "arguments": []
+ }
+ }
+ ]
+ }
+ },
+ "finalizer": null
+ }
+ ]
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "BlockStatement",
+ "block": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "TryStatement",
+ "block": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "that"
+ },
+ "arguments": []
+ }
+ }
+ ]
+ },
+ "guardedHandlers": [],
+ "handler": {
+ "type": "CatchClause",
+ "param": {
+ "type": "Identifier",
+ "name": "e"
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "handle"
+ },
+ "arguments": []
+ }
+ }
+ ]
+ }
+ },
+ "finalizer": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "clean"
+ },
+ "arguments": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "BlockStatement",
+ "block": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "TryStatement",
+ "block": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "that"
+ },
+ "arguments": []
+ }
+ }
+ ]
+ },
+ "guardedHandlers": [
+ {
+ "type": "CatchClause",
+ "param": {
+ "type": "Identifier",
+ "name": "e"
+ },
+ "guard": {
+ "type": "BinaryExpression",
+ "operator": "instanceof",
+ "left": {
+ "type": "Identifier",
+ "name": "e"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "TypeError"
+ }
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "handle"
+ },
+ "arguments": []
+ }
+ }
+ ]
+ }
+ }
+ ],
+ "handler": {
+ "type": "CatchClause",
+ "param": {
+ "type": "Identifier",
+ "name": "e"
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "CallExpression",
+ "callee": {
+ "type": "Identifier",
+ "name": "rest"
+ },
+ "arguments": []
+ }
+ }
+ ]
+ }
+ },
+ "finalizer": null
+ }
+ ]
+ }
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/unaryExpr.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests to check unary operators.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("x++");
+printParse("x--");
+printParse("delete x");
+printParse("void x");
+printParse("typeof x");
+printParse("++x");
+printParse("--x");
+printParse("+x");
+printParse("-x");
+printParse("~x");
+printParse("!x");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/unaryExpr.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,187 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "UpdateExpression",
+ "operator": "++",
+ "prefix": false,
+ "argument": {
+ "type": "Identifier",
+ "name": "x"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "UpdateExpression",
+ "operator": "--",
+ "prefix": false,
+ "argument": {
+ "type": "Identifier",
+ "name": "x"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "UnaryExpression",
+ "operator": "delete",
+ "prefix": true,
+ "argument": {
+ "type": "Identifier",
+ "name": "x"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "UnaryExpression",
+ "operator": "void",
+ "prefix": true,
+ "argument": {
+ "type": "Identifier",
+ "name": "x"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "UnaryExpression",
+ "operator": "typeof",
+ "prefix": true,
+ "argument": {
+ "type": "Identifier",
+ "name": "x"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "UpdateExpression",
+ "operator": "++",
+ "prefix": true,
+ "argument": {
+ "type": "Identifier",
+ "name": "x"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "UpdateExpression",
+ "operator": "--",
+ "prefix": true,
+ "argument": {
+ "type": "Identifier",
+ "name": "x"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "UnaryExpression",
+ "operator": "+",
+ "prefix": true,
+ "argument": {
+ "type": "Identifier",
+ "name": "x"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "UnaryExpression",
+ "operator": "-",
+ "prefix": true,
+ "argument": {
+ "type": "Identifier",
+ "name": "x"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "UnaryExpression",
+ "operator": "~",
+ "prefix": true,
+ "argument": {
+ "type": "Identifier",
+ "name": "x"
+ }
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "UnaryExpression",
+ "operator": "!",
+ "prefix": true,
+ "argument": {
+ "type": "Identifier",
+ "name": "x"
+ }
+ }
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/useStrict.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests to check if statement.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("'use strict'");
+printParse("function f() { 'use strict' }");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/useStrict.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,41 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "Literal",
+ "value": "use strict"
+ }
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "FunctionDeclaration",
+ "id": {
+ "type": "Identifier",
+ "name": "f"
+ },
+ "params": [],
+ "defaults": [],
+ "rest": null,
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "Literal",
+ "value": "use strict"
+ }
+ }
+ ]
+ },
+ "generator": false,
+ "expression": false
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/util.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * @subtest
+ */
+
+// utilitity for parser tests
+
+load("nashorn:parser.js");
+function printParse(code) {
+ print(JSON.stringify(parse(code), null, ' '));
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/varDecl.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests to check variable declarations.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+// no initialization
+printParse("var a");
+printParse("var a, b");
+
+// init single, multiple
+printParse("var a = 'hello'");
+printParse("var a = 1, b = 2, c = 3");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/varDecl.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,123 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "VariableDeclaration",
+ "declarations": [
+ {
+ "type": "VariableDeclarator",
+ "id": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "init": null
+ }
+ ]
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "VariableDeclaration",
+ "declarations": [
+ {
+ "type": "VariableDeclarator",
+ "id": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "init": null
+ }
+ ]
+ },
+ {
+ "type": "VariableDeclaration",
+ "declarations": [
+ {
+ "type": "VariableDeclarator",
+ "id": {
+ "type": "Identifier",
+ "name": "b"
+ },
+ "init": null
+ }
+ ]
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "VariableDeclaration",
+ "declarations": [
+ {
+ "type": "VariableDeclarator",
+ "id": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "init": {
+ "type": "Literal",
+ "value": "hello"
+ }
+ }
+ ]
+ }
+ ]
+}
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "VariableDeclaration",
+ "declarations": [
+ {
+ "type": "VariableDeclarator",
+ "id": {
+ "type": "Identifier",
+ "name": "a"
+ },
+ "init": {
+ "type": "Literal",
+ "value": 1
+ }
+ }
+ ]
+ },
+ {
+ "type": "VariableDeclaration",
+ "declarations": [
+ {
+ "type": "VariableDeclarator",
+ "id": {
+ "type": "Identifier",
+ "name": "b"
+ },
+ "init": {
+ "type": "Literal",
+ "value": 2
+ }
+ }
+ ]
+ },
+ {
+ "type": "VariableDeclaration",
+ "declarations": [
+ {
+ "type": "VariableDeclarator",
+ "id": {
+ "type": "Identifier",
+ "name": "c"
+ },
+ "init": {
+ "type": "Literal",
+ "value": 3
+ }
+ }
+ ]
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/withStat.js Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Tests for 'with' statement.
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "util.js");
+
+printParse("with (scope) { x = y }");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/parser/withStat.js.EXPECTED Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,32 @@
+{
+ "type": "Program",
+ "body": [
+ {
+ "type": "WithStatement",
+ "object": {
+ "type": "Identifier",
+ "name": "scope"
+ },
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+ {
+ "type": "ExpressionStatement",
+ "expression": {
+ "type": "AssignmentExpression",
+ "operator": "=",
+ "left": {
+ "type": "Identifier",
+ "name": "x"
+ },
+ "right": {
+ "type": "Identifier",
+ "name": "y"
+ }
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/src/META-INF/services/java.sql.Driver Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,1 @@
+jdk.nashorn.api.NashornSQLDriver
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/src/jdk/nashorn/api/NashornSQLDriver.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010, 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 jdk.nashorn.api;
+
+import java.sql.*;
+import java.util.Properties;
+import java.util.logging.Logger;
+
+/**
+ * A dummy SQL driver for testing purpose.
+ */
+public final class NashornSQLDriver implements Driver {
+ static {
+ try {
+ DriverManager.registerDriver(new NashornSQLDriver(), null);
+ } catch (SQLException se) {
+ throw new RuntimeException(se);
+ }
+ }
+
+ @Override
+ public boolean acceptsURL(String url) {
+ return url.startsWith("jdbc:nashorn:");
+ }
+
+ @Override
+ public Connection connect(String url, Properties info) {
+ throw new UnsupportedOperationException("I am a dummy!!");
+ }
+
+ @Override
+ public int getMajorVersion() {
+ return -1;
+ }
+
+ @Override
+ public int getMinorVersion() {
+ return -1;
+ }
+
+ @Override
+ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) {
+ return new DriverPropertyInfo[0];
+ }
+
+ @Override
+ public boolean jdbcCompliant() {
+ // no way!
+ return false;
+ }
+
+ @Override
+ public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ throw new SQLFeatureNotSupportedException();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2010, 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 jdk.nashorn.api.scripting;
+
+import java.nio.IntBuffer;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Set;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.fail;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for pluggable external impls. of jdk.nashorn.api.scripting.JSObject.
+ *
+ * JDK-8024615: Refactor ScriptObjectMirror and JSObject to support external
+ * JSObject implementations.
+ */
+public class PluggableJSObjectTest {
+ public static class MapWrapperObject extends JSObject {
+ private final HashMap<String, Object> map = new LinkedHashMap<>();
+
+ public HashMap<String, Object> getMap() {
+ return map;
+ }
+
+ @Override
+ public Object getMember(String name) {
+ return map.get(name);
+ }
+
+ @Override
+ public void setMember(String name, Object value) {
+ map.put(name, value);
+ }
+
+ @Override
+ public boolean hasMember(String name) {
+ return map.containsKey(name);
+ }
+
+ @Override
+ public void removeMember(String name) {
+ map.remove(name);
+ }
+
+ @Override
+ public Set<String> keySet() {
+ return map.keySet();
+ }
+
+ @Override
+ public Collection<Object> values() {
+ return map.values();
+ }
+ }
+
+ @Test
+ // Named property access on a JSObject
+ public void namedAccessTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ try {
+ final MapWrapperObject obj = new MapWrapperObject();
+ e.put("obj", obj);
+ obj.getMap().put("foo", "bar");
+
+ // property-like access on MapWrapperObject objects
+ assertEquals(e.eval("obj.foo"), "bar");
+ e.eval("obj.foo = 'hello'");
+ assertEquals(e.eval("'foo' in obj"), Boolean.TRUE);
+ assertEquals(e.eval("obj.foo"), "hello");
+ assertEquals(obj.getMap().get("foo"), "hello");
+ e.eval("delete obj.foo");
+ assertFalse(obj.getMap().containsKey("foo"));
+ assertEquals(e.eval("'foo' in obj"), Boolean.FALSE);
+ } catch (final Exception exp) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+
+ public static class BufferObject extends JSObject {
+ private final IntBuffer buf;
+
+ public BufferObject(int size) {
+ buf = IntBuffer.allocate(size);
+ }
+
+ public IntBuffer getBuffer() {
+ return buf;
+ }
+
+ @Override
+ public Object getMember(String name) {
+ return name.equals("length")? buf.capacity() : null;
+ }
+
+ @Override
+ public boolean hasSlot(int i) {
+ return i > -1 && i < buf.capacity();
+ }
+
+ @Override
+ public Object getSlot(int i) {
+ return buf.get(i);
+ }
+
+ @Override
+ public void setSlot(int i, Object value) {
+ buf.put(i, ((Number)value).intValue());
+ }
+
+ @Override
+ public boolean isArray() {
+ return true;
+ }
+ }
+
+ @Test
+ // array-like indexed access for a JSObject
+ public void indexedAccessTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ try {
+ final BufferObject buf = new BufferObject(2);
+ e.put("buf", buf);
+
+ // array-like access on BufferObject objects
+ assertEquals(e.eval("buf.length"), buf.getBuffer().capacity());
+ e.eval("buf[0] = 23");
+ assertEquals(buf.getBuffer().get(0), 23);
+ assertEquals(e.eval("buf[0]"), 23);
+ assertEquals(e.eval("buf[1]"), 0);
+ buf.getBuffer().put(1, 42);
+ assertEquals(e.eval("buf[1]"), 42);
+ assertEquals(e.eval("Array.isArray(buf)"), Boolean.TRUE);
+ } catch (final Exception exp) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+
+ public static class Adder extends JSObject {
+ @Override
+ public Object call(Object thiz, Object... args) {
+ double res = 0.0;
+ for (Object arg : args) {
+ res += ((Number)arg).doubleValue();
+ }
+ return res;
+ }
+
+ @Override
+ public boolean isFunction() {
+ return true;
+ }
+ }
+
+ @Test
+ // a callable JSObject
+ public void callableJSObjectTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ try {
+ e.put("sum", new Adder());
+ // check callability of Adder objects
+ assertEquals(e.eval("typeof sum"), "function");
+ assertEquals(((Number)e.eval("sum(1, 2, 3, 4, 5)")).intValue(), 15);
+ } catch (final Exception exp) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+
+ public static class Factory extends JSObject {
+ @Override
+ public Object newObject(Object... args) {
+ return new HashMap<Object, Object>();
+ }
+
+ @Override
+ public boolean isFunction() {
+ return true;
+ }
+ }
+
+ @Test
+ // a factory JSObject
+ public void factoryJSObjectTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ try {
+ e.put("Factory", new Factory());
+
+ // check new on Factory
+ assertEquals(e.eval("typeof Factory"), "function");
+ assertEquals(e.eval("typeof new Factory()"), "object");
+ assertEquals(e.eval("(new Factory()) instanceof java.util.Map"), Boolean.TRUE);
+ } catch (final Exception exp) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+
+ @Test
+ // iteration tests
+ public void iteratingJSObjectTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ try {
+ final MapWrapperObject obj = new MapWrapperObject();
+ obj.setMember("foo", "hello");
+ obj.setMember("bar", "world");
+ e.put("obj", obj);
+
+ // check for..in
+ Object val = e.eval("var str = ''; for (i in obj) str += i; str");
+ assertEquals(val.toString(), "foobar");
+
+ // check for..each..in
+ val = e.eval("var str = ''; for each (i in obj) str += i; str");
+ assertEquals(val.toString(), "helloworld");
+ } catch (final Exception exp) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+}
--- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -140,8 +140,8 @@
fail("obj[1] != 'world'");
}
- if (!obj.call("func", new Object[0]).equals("hello")) {
- fail("obj.call('func') != 'hello'");
+ if (!obj.callMember("func", new Object[0]).equals("hello")) {
+ fail("obj.func() != 'hello'");
}
// try setting properties
@@ -210,8 +210,8 @@
e.eval("function func() {}");
e2.put("foo", e.get("func"));
- final Object e2global = e2.eval("this");
- final Object newObj = ((ScriptObjectMirror) e2global).newObject("foo");
+ final ScriptObjectMirror e2global = (ScriptObjectMirror)e2.eval("this");
+ final Object newObj = ((ScriptObjectMirror)e2global.getMember("foo")).newObject();
assertTrue(newObj instanceof ScriptObjectMirror);
}
@@ -223,8 +223,8 @@
e.eval("function func() {}");
e2.put("func", e.get("func"));
- final Object e2obj = e2.eval("({ foo: func })");
- final Object newObj = ((ScriptObjectMirror) e2obj).newObject("foo");
+ final ScriptObjectMirror e2obj = (ScriptObjectMirror)e2.eval("({ foo: func })");
+ final Object newObj = ((ScriptObjectMirror)e2obj.getMember("foo")).newObject();
assertTrue(newObj instanceof ScriptObjectMirror);
}
}
--- a/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java Fri Sep 20 17:11:32 2013 -0700
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java Fri Sep 20 19:15:59 2013 -0700
@@ -64,6 +64,7 @@
final Options options = new Options("");
final ErrorManager errors = new ErrorManager();
final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader());
+ final boolean strict = cx.getEnv()._strict;
final ScriptObject oldGlobal = Context.getGlobal();
Context.setGlobal(cx.createGlobal());
@@ -95,7 +96,7 @@
assertEquals(sobj.size(), 2);
// add property
- sobj.put("zee", "hello");
+ sobj.put("zee", "hello", strict);
assertEquals(sobj.get("zee"), "hello");
assertEquals(sobj.size(), 3);